->toArray() is giving empty arrays instead of objects - php

I have a chunked array of 1000 Raw Objects:
class Raw extends Model
{
protected $table = 'raws';
protected $casts = [
'time' => 'datetime'
];
public $timestamps = [
"time"
];
private string $operationId;
private string $meterId;
private string $consoProd;
private string $timestep;
private string $unit;
private string $timestamp;
private string $value;
}
collect($measures)->chunk(1000)->each(function ($raws) use ($meter) {
$raws = $raws->map(function ($raw) use ($meter) {
return new \App\Models\Raw($meter['OperationID'], $meter['ID'], $meter['ConsoProd'], $meter['Timestep'], $meter['Unit'], $raw['t'], $raw['d']);
})->toArray();
dd($raws);
});
When I don't use ->toArray(), I can see a collection of 1000 Raw elements:
Illuminate\Support\Collection {#2857 ▼
#items: array:1000 [▼
0 => App\Models\Raw {#1857 ▼
#table: "raws"
#casts: array:1 [ …1]
+timestamps: array:1 [ …1]
-operationId: "ACC00000001"
-meterId: "30002431650000"
-consoProd: "Conso"
-timestep: "600000000000"
-unit: "kW"
-timestamp: "2018-09-11T00:00:00+02:00"
-value: "7"
#connection: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: false
+wasRecentlyCreated: false
#attributes: []
#original: []
#changes: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
#hidden: []
#visible: []
#fillable: []
#guarded: array:1 [ …1]
}
1 => App\Models\Raw {#1858 ▶}
2 => App\Models\Raw {#1859 ▶}
3 => App\Models\Raw {#1860 ▶}
But I try to convert it into an array with:
dd($raws->toArray());
I get:
array:1000 [
0 => []
1 => []
2 => []
3 => []
4 => []
5 => []
6 => []
7 => []
8 => []
9 => []...
Why ???

As you can see in Model.php, in it's constructor it accepts an array of attributes and not multiple parameters. So you need to do the creation of Raw.php model like so.
$raws = $raws->map(function ($raw) use ($meter) {
return new \App\Models\Raw([
'operationId' => $meter['OperationID'],
'meterId' => $meter['ID'],
'consoProd' => $meter['ConsoProd'],
'timestep' => $meter['Timestep'],
'unit' => $meter['Unit'],
'timestamp' => $meter['t'],
'value' => $meter['d'],
]);
})->toArray();
It was a little hard to assume your database columns, the keys in the array, has to be the column name of the database so please check it.

Related

Call to a member function toArray() on array -Laravel

// $result=[];
foreach ($chapter['chapter_content'] as $row) {
$result = CoursePublishChaptercontent::create([
'courseId' => $postdata[$i]['courseId'],
'course_chapter_id' => $postdata[$i]['course_chapter_id'],
'file_id' => $postdata[$i]['file_id'],
'course_chapter_content_id' => $postdata[$i]['course_chapter_content_id'],
]);
}
dd($result->toArray());
dd($result) shows the below data. I cannot call $result->toArray(); outside the foreach - it shows the error Undefined variable: result. When declaring $result before foreach as $result=[];, it shows the error Call to a member function toArray() on array. How can i fix it?Can someone tell me how to achieve this? I also tried declaring $result as '' & null before foreach. Both shows errors Call to a member function toArray() on string & Call to a member function toArray() on null respectively.
App\Models\CoursePublishChaptercontent {#441
#table: "course_publish_chapter_contents"
#fillable: array:9 [
0 => "course_chapter_id"
1 => "file_id"
2 => "courseId"
3 => "course_chapter_content_id"
]
#connection: "pgsql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: true
#attributes: array:12 [
"courseId" => 1
"course_chapter_id" => 18
"content_type_id" => 1
"file_id" => null
"course_chapter_content_id" => 17
"id" => 106
]
#original: array:12 [
"courseId" => 1
"course_chapter_id" => 18
"content_type_id" => 1
"course_chapter_content_id" => 17
"content_description" => null
"id" => 106
]
#changes: []
#casts: array:1 [
"deleted_at" => "datetime"
]
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [
0 => "*"
]
#forceDeleting: false
#enableLoggingModelsEvents: true
#oldAttributes: []
}
You are on the right track. You can use the collect() helper to convert the result array into a collection and than you can use the toArray() method.
This is one way to do it:
$result = [];
foreach ($chapter['chapter_content'] as $row) {
$result[] = CoursePublishChaptercontent::create([
'courseId' => $postdata[$i]['courseId'],
'course_chapter_id' => $postdata[$i]['course_chapter_id'],
'file_id' => $postdata[$i]['file_id'],
'course_chapter_content_id' => $postdata[$i]['course_chapter_content_id'],
]);
}
dd(collect($result)->toArray());

Laravel 5.8: Parameter passed to the event listener is getting null

I have created an Event called UserWalletNewTransaction.php and added this to it:
public $transaction;
public function __construct($transaction) {
$this->$transaction = $transaction;
}
And also registered it at EventServiceProivder.php:
use App\Listeners\UserWalletNotification;
protected $listen = [
UserWalletNewTransaction::class => [
UserWalletNotification::class,
],
Now in order to fire this event at the Controller, I coded this:
$newTransaction = UserWalletTransaction::create(['user_id' => $user_id, 'wallet_id' => $wallet_id, 'creator_id' => $creator_id, 'amount' => $amount_add_value, 'description' => $trans_desc]);
event(new UserWalletNewTransaction($newTransaction));
Then at the Listener, UserWalletNotification.php, I tried:
public function handle(UserWalletNewTransaction $event) {
dd($event->transaction);
}
But it returns null somehow.
However if I dd($event) instead, I get this:
So what is going wrong here? I can properly insert new record at user_wallet_transactions and the variable $newTransaction should contain the transaction information but it's not.
Here is also the Model UserWalletTransaction.php:
protected $fillable = ['user_id','wallet_id','amount','description','creator_id'];
protected $table = 'user_wallet_transactions';
I would really appreciate any idea or suggestion from you guys about this...
Thanks in advance.
UPDATE #1:
If I do dd($newTransaction) at the Controller before event(), I get this:
UPDATE #2:
Here is the full code of event, UserWalletNewTransaction.php:
class UserWalletNewTransaction
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* #return void
*/
public $transaction;
public function __construct($transaction)
{
$this->$transaction = $transaction;
}
}
UPDATE #3:
Here is the full result of dd($event) at the Listener:
App\Events\UserWalletNewTransaction {#2533 ▼
+newTransaction: null
+socket: null
+"{"user_id":"373","wallet_id":"2","creator_id":2,"amount":"-60","description":null,"updated_at":"2021-07-18 13:33:59","created_at":"2021-07-18 13:33:59","id":61}": App\UserWalletTransaction {#2535 ▼
#fillable: array:5 [▼
0 => "user_id"
1 => "wallet_id"
2 => "amount"
3 => "description"
4 => "creator_id"
]
#table: "user_wallet_transactions"
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: true
#attributes: array:8 [▼
"user_id" => "373"
"wallet_id" => "2"
"creator_id" => 2
"amount" => "-60"
"description" => null
"updated_at" => "2021-07-18 13:33:59"
"created_at" => "2021-07-18 13:33:59"
"id" => 61
]
#original: array:8 [▼
"user_id" => "373"
"wallet_id" => "2"
"creator_id" => 2
"amount" => "-60"
"description" => null
"updated_at" => "2021-07-18 13:33:59"
"created_at" => "2021-07-18 13:33:59"
"id" => 61
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▼
0 => "*"
]
}
}
I just figured out the problem... You are doing $this->$transaction when it should be $this->transaction.
I also had this problem, in case it is the case: remove the underscores in the properties of the event. ($_order has to be $order)

No data was collected in my relation array in Laravel Eloquent method

I used eloquent method in my controller to collect data from my database, but something weird happened. If i use this code below,
$female_old_visitors = Treatment::with('diseases', 'patient', 'insurance', 'referer')
->leftJoin('patients', 'treatments.patient_id', 'patients.id')
->where('treatments.visit_status', 'old')
->where('patients.gender', 'female')
->whereBetween('treatments.date', $date_range)
->get();
i can get all the data that i want include diseases and referer
Collection {#3053 ▼
#items: array:25 [▼
0 => Treatment {#2799 ▼
...
#relations: array:4 [▼
"diseases" => Collection {#3346 ▼
#dates: array:1 [▶]
#cascadeDeletes: array:1 [▶]
#guarded: []
#connection: "mysql"
#table: "diseases"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:32 [▶]
#original: array:32 [▶]
#changes: []
#casts: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#forceDeleting: false
}
"patient" => Patient {#3328 ▶}
"insurance" => Insurance {#3346 ▶}
"referer" => TreatmentReferer {#3138 ▶}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#forceDeleting: false
}
but when i use other code like this
$common_insurance_old_visitors = Treatment::with('diseases', 'patient', 'insurance', 'referer')
->leftJoin('insurances', 'treatments.insurance_id', 'insurances.id')
->where('treatments.visit_status', 'old')
->where('insurances.id', 1)
->whereBetween('treatments.date', $date_range)
->get();
all the data has been selected or collected except disease and referer
Collection {#3053 ▼
#items: array:25 [▼
0 => Treatment {#2799 ▼
...
#relations: array:4 [▼
"diseases" => Collection {#3246 ▼
#items: []
}
"patient" => Patient {#3328 ▶}
"insurance" => Insurance {#3346 ▶}
"referer" => null
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#forceDeleting: false
}
i have been checking in my database, that the data is still there and the column is not empty, it should be collected just like the code i use first. Is it because i use left join uncorrectly? i am still new for laravel, thanks for anyone who giving me a solution for this problem
this is my model for Treatment
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Iatstuti\Database\Support\CascadeSoftDeletes;
class Treatment extends Model
{
use SoftDeletes, CascadeSoftDeletes;
protected $dates = ['deleted_at'];
protected $cascadeDeletes = ['medicines', 'actions', 'referer', 'diseases', 'queues'];
protected $guarded = [];
public function queues(){
return $this->hasMany(TreatmentQueue::class);
}
public function treatmentType(){
return $this->belongsTo(TreatmentType::class);
}
public function medicines(){
return $this->hasMany(TreatmentMedicine::class)->with('medicine', 'recu');
}
public function actions(){
return $this->hasMany(TreatmentAction::class)->with('action', 'doctor', 'nurse', 'recu', 'teeth', 'therapy', 'treatmentDisease');
}
public function insurance(){
return $this->belongsTo(Insurance::class);
}
public function referer(){
return $this->hasOne(TreatmentReferer::class)->with('puskesmas', 'disease');
}
public function diseases(){
return $this->hasMany(TreatmentDisease::class)->with('disease', 'doctor', 'teeth');
}
public function patient(){
return $this->belongsTo(Patient::class);
}
}
with() is for eager loading. That basically means, along the main model, Laravel will preload the relationship(s) you specify. This is especially helpful if you have a collection of models and you want to load a relation for all of them. Because with eager loading you run only one additional DB query instead of one for every model in the collection.
In your example.
you're using left join why? it already contain in with() you use with('patient') it means you join treatments to left join with patient
$female_old_visitors = Treatment::with('diseases', 'insurance', 'referer')
->with(['patient' => function ($q) {
$q->where('gender', 'female');
}])
->where('visit_status', 'old')
->whereBetween('treatments.date', $date_range)
->get();
eager-loads

Laravel ManyToMany withPivot Trying to get property 'started_at' of non-object

I have a simeple ManyToMany relation between 2 models when I try to access a field in my pivot table I get this error:
Trying to get property 'started_at' of non-object
I have followed the instructions on the laravel documentation correctly.
My Models:
Instance:
public function steps(): BelongsToMany
{
return $this->belongsToMany(Step::class)
->using(InstanceStep::class)
->withTimestamps();
}
Step:
public function instances(): BelongsToMany
{
return $this->belongsToMany(Instance::class)
->using(InstanceStep::class)
->withPivot([
'started_at',
'finished_at',
'failed_at',
'output',
])
->withTimestamps();
}
How I try to access 'started_at' of a step:
dd($step->pivot->started_at);
EDIT
private function finishStep(Step $step)
{
dd($step->pivot->started_at);
}
/** #var Step $step */
foreach ($this->workflow->steps as $step) {
StepJob::dispatch($step, $instance);
}
dd($step)
Step {#420 ▼
#table: "workflow_steps"
#fillable: array:6 [▶]
#casts: array:3 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:10 [▼
"id" => "ca646f59-b215-41b0-afe6-ea9e6174f4f5"
"workflow_id" => "d786bd13-4111-4199-94d6-c52fef33b78b"
"category" => "transport"
"properties" => "props"
"entity_type" => "App\TransportWorkflowStep"
"entity_id" => "4d32e11c-6453-4f48-9419-7c5cbd647128"
"order" => 1
"created_at" => "2019-07-04 11:19:41"
"updated_at" => "2019-07-04 11:41:16"
"deleted_at" => null
]
#original: array:10 [▶]
#changes: []
#dates: array:1 [▶]
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#forceDeleting: false
}
Attach step to instance
// set started_at
$workflowInstance->workflowsteps()->attach(
$step,
[
'started_at' => Carbon::now(),
]
);
// do something
// set finished_at when done
dd($step->pivot->started_at);
I did the dd($step->pivot->started_at); to see if i am working with the correct pivot row
You've not specified the relationship you're after, you may access the intermediate table using the pivot attribute on the models:
Try the following code:
private function finishStep(Step $step)
{
foreach ($step->instances as $instance) {
var_dump($instance->pivot->started_at);
}
die();
}
It depends on how declare $step, it gets collection and you have to insert it in foreach loop.
private function finishStep(Step $step)
{
dd($step->pivot->started_at);
}
this doesn't declare $step, you have to declare it first like
$step=Step::where(...)->get();
and then you can dd($step);
in short - object doesn't exist yet

How to get Laravel set table to 'stick' for collection

We have a Laravel model and sometimes we want to get data from it's default table, but other times from a different table. It all works from a data perspective, but when the collection is returned from the alternate table, the 'table' attribute still references the original table (even though the data is from the other one as expected).
If we dd() getTable(), it is correct:
$model = COUNTRY;
$table = "countires";
$org_id = 1;
$org_collection = $model->setTable('merge_' . $table)->get()
->where('organization_id', $org_id)->keyBy('id');
dd($model->getTable()); // *** THIS SHOWS THE 2nd TABLE AS EXPECTED
dd() ouput:
"merge_countries"
But with the exact same code, if we dd() the result the table attribute in the collection is still the 1st one ('orgs') and not 'merge_orgs' as expected even though the data is correctly coming from the 'merge_orgs' table:
$model = COUNTRY;
$table = "countires";
$org_id = 1;
$org_collection = $model->setTable('merge_' . $table)->get()
->where('organization_id', $org_id)->keyBy('id');
dd($org_collection); // *** THIS SHOWS THE 1st TABLE EVEN THOUGH THE getTable() ABOVE DOES NOT
dd() output:
Collection {#297
#items: array:1 [
3 => Country {#295
#connection: "common"
#table: "countries" <---- WHY IS THIS NOT 'merge_countries'???
#hidden: array:2 [
0 => "created_at"
1 => "updated_at"
]
#appends: array:1 [
0 => "level"
]
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:7 [
"id" => 3
"organization_id" => 1
"region_id" => 2
"name" => "Southpark"
"active" => 1
"created_at" => "2018-06-21 14:05:36"
"updated_at" => "2018-06-21 13:25:27"
]
#original: array:7 [
"id" => 3
"organization_id" => 1
"region_id" => 2
"name" => "Southpark"
"active" => 1
"created_at" => "2018-06-21 14:05:36"
"updated_at" => "2018-06-21 13:25:27"
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#visible: []
#fillable: []
#guarded: array:1 [
0 => "*"
]
}
]
}
Any idea how to address this? We're not sure what else to even try at this point. Laravel if 5.6 if that matters.
OK, there is a fix reference and more detail at github.com/laravel/framework/issues/26058. In the interim you can also override the model newInstance method in the trait to work around it:
public function newInstance($attributes = [], $exists = false)
{
// Overridden in order to allow for late table binding.
$model = parent::newInstance($attributes, $exists);
$model->setTable($this->table);
return $model;
}

Categories