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

// $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());

Related

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)

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

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.

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;
}

Transform eloquent model using fractal

I am trying to use fractal to convert dates in my eloquent model when sending it to a web page via ajax. However, I'm not getting the expected transformed data object. Here's my code:
Transformer:
<?php
namespace App\Transformers\Models;
use App\Models\Student;
use League\Fractal;
class StudentTransformer extends Fractal\TransformerAbstract
{
public function transform(Student $student)
{
return [
'name' => $student->name,
'birth_date' => date('d-m-Y', strtotime($student->birth_date)),
'start_date' => date('d-m-Y', strtotime($student->start_date)),
'is_active' => $student->is_active ? 'Yes' : 'No',
'course_title' => $student->course_title,
'university_id' => $student->university_id,
'institution_id' => $student->institution_id,
'course_id' => $student->course_id,
];
}
}
Routes file:
Route::get('/', function () {
$student = App\Models\Student::first();
$response = new League\Fractal\Resource\Item($student, new App\Transformers\Models\StudentTransformer);
return response()->json([$response]);
});
returns this:
[
{ }
]
if I dd(), like so:
Route::get('/', function () {
$student = App\Models\Student::first();
$response = new League\Fractal\Resource\Item($student, new App\Transformers\Models\StudentTransformer);
dd($response);
});
I get the following, with no apparent transformations made
Item {#299 ▼
#data: Student {#305 ▼
#fillable: array:10 [▼
0 => "name"
1 => "birth_date"
2 => "start_date"
3 => "is_active"
4 => "course_title"
5 => "university_id"
6 => "institution_id"
7 => "course_id"
]
#connection: null
#table: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:13 [▼
"id" => 1
"name" => "Michel Jast"
"birth_date" => "1979-12-22"
"start_date" => "2015-08-02"
"is_active" => 1
"course_title" => "quia"
"university_id" => "10954"
"institution_id" => 1044
"course_id" => 1
"created_at" => "2015-11-23 09:40:35"
"updated_at" => "2015-11-26 10:24:14"
]
#original: array:13 [▼
"id" => 1
"name" => "Michel Jast"
"birth_date" => "1979-12-22"
"start_date" => "2015-08-02"
"is_active" => 1
"course_title" => "quia"
"university_id" => "10954"
"institution_id" => 1044
"course_id" => 1
"created_at" => "2015-11-23 09:40:35"
"updated_at" => "2015-11-26 10:24:14"
]
#relations: []
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
}
#meta: []
#resourceKey: null
#transformer: StudentTransformer {#301 ▼
#availableIncludes: []
#defaultIncludes: []
#currentScope: null
}
}
Any ideas what I'm missing here?
My implementation is the following :
Route::get('/', function () {
$student = App\Models\Student::first();
$response = new League\Fractal\Resource\Item($student, new App\Transformers\Models\StudentTransformer);
$manager = new \League\Fractal\Manager();
$manager->setSerializer(new \League\Fractal\Serializer\ArraySerializer());
return response()->json($manager->createData($response)->toArray());
});
You have to create a \League\Fractal\Manager instance and assign a serializer into it. The manager will return the data into array or others.
In fractal page, there is more detail.
Ive not used Factral in a project but I think you need to do something like.
Route::get('/', function () {
$student = App\Models\Student::first();
$response = new League\Fractal\Resource\Item($student, new App\Transformers\Models\StudentTransformer);
return response()->json($response->toArray());
});

Categories