Using whenLoaded in Resource Collection I got error - laravel

In laravel 6 app I have a Resource Collection, which works ok for me :
class UserSkillCollection extends ResourceCollection
{
public static $wrap = 'user_skills';
public function toArray($request)
{
return $this->collection->transform(function($userSkill){
return [
'id' => $userSkill->id,
'user_id' => $userSkill->user_id,
'user_name' => $userSkill->user_name,
'skill_id' => $userSkill->skill_id,
'skill_name' => $userSkill->skill_name,
'rating' => $userSkill->rating,
'created_at' => $userSkill->created_at,
];
});
}
except when some fields are defined, like user_name, I have keys with null values.
To get rid of them I tried to use whenLoaded, but with line :
'user_id' => $this->whenLoaded('user_id'),
I got error :
"message": "Method Illuminate\\Support\\Collection::relationLoaded does not exist.",
Which way is valid ?
MODIFIED :
I added relations in models and making :
'user' => $userSkill->whenLoaded('user'),
or
'user' => $this->whenLoaded('user'),
I got error :
Call to undefined method App\UserSkill::whenLoaded(
I suppose this error as I call it from Collection.
How correctly ?
Thanks!

relationLoaded() is a method inherited from the HasRelationships trait on Illuminate\Database\Eloquent\Model.
Your code is trying to access it on a instance of an Illuminate\Support\Collection.
Try accessing the relationship user rather than it's key user_id. Like so:
$this->whenLoaded('user')

Related

Add a custom item to eloquent collection

I am using Laravel 7.
I have Category model. I sent categories as API with laravel resources. But now I want to add "all" value to categories.
Controller:
'categories' => CategoryResource::collection(Category::all()->push([
'id' => 0,
'name' => "All",
'subcategories' => []
]))
Resource:
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'subcategories' => SubcategryResource::collection($this->subcategories)
];
}
Also, I wanted to add this custom value to the beginning of the collection.
But I am getting this error:
Trying to get property 'id' of non-object
Please, help me. How can I solve my problem?
Try replacing $this->id with $this['id']
If that works your query is returning an array not an object.
The problem here is that you're trying to add an item to the collection which is not a category model. $this in the resource reverts to the given model. However, you pass in an array so there is no model.
So try this instead
$allCategory = new Category(['id' => 0, 'name' => 'All']);
'categories' => CategoryResource::collection(Category::all()->prepend($allCategory));
I got these from: https://laracasts.com/discuss/channels/eloquent/add-a-custom-value-to-eloquent-collection

Trying to get property of non-object in laravel shopping cart

I am using darryldecode for shopping cart in my project
this is my shoppingcartController and add method:
public function add(){
$pdt = Singleproduct::find(\request()->id);
\Cart::add(array(
array(
'id' => $pdt->id,
'name' => $pdt->name ,
'price' => $pdt->price,
'quantity' => \request()->qty ,
'attributes' => array()
)));
}
and this is route list:
Route::post('/cart/add' , 'admin\ShopingController#add')->name('cart.add');
and in my SingleProduct i have id,price and name!
the error is:"Trying to get property 'id' of non-object"
where is the problem??
The id may be returning null, or you may not be getting the right request object. Try injecting it into the method (which is kind of a 'Laravel') way to do it:
public function add(Illuminate\Http\Request $request){
$pdt = Singleproduct::find($request->input('id'));
}
Dump the request variable if you want to double check it has the id from your form: dd($request->all()); If id is not there in the dump, you can see where your problem lies.

Exporting Excel getting this error Trying to get property 'id' of non-object

I'm using Maatwebsite Laravel Excel package 3.0.
This is my InvoicesExport.php
class InvoicesExport implements FromCollection
{
public function collection()
{
$company_id = Auth::user()->company_id;
$assets = Asset::where('id', $company_id)->get()->toArray();
$assets_array = array();
if(!$assets->isEmpty()){
foreach($assets as $asset){
$assets_array[] = array(
'Asset ID' => $asset->id,
'Asset Name' => $asset->name,
'Description' => $asset->description,
'Serial Number' => $asset->serialno,
'External ID' => $asset->external_id,
'Location' => $asset->location,
'Expiry Date' => $asset->expiry_date,
'Owner' => $asset->owner,
'Status' => $asset->status,
'Updated at' => $asset->updated_at
);
}
}
//dd($assets_array);
return $assets_array;
}
}
And i keep getting this error
Trying to get property 'id' of non-object
And this is my function in controller
public function excel()
{
return Excel::download(new InvoicesExport, 'invoices.xlsx');
}
My code looks like this now and I keep getting this error.
Call to a member function each() on array
When i use dd($assets_array) I get those 2 items that i have in database, so i think maybe it's problem in my RETURN
It seems, the problem is outside of the InvoicesExport Class.
Why don't you change the type of return?
instead of returning
return $assets_array;
Do it like this:
return collect($assets_array);
you convert the collection to array and try to access it as object
just remove the toArray
$assets = Asset::where('id', $company_id)->get();

ErrorException in CrudTrait.php Undefined offset: 0 Backpack for Laravel 5.2

i want create dynamic combobox from database, but i have an error with this message :
ErrorException in CrudTrait.php line 32: Undefined offset: 0 (View: /home/vagrant/Code/hrd/resources/views/vendor/backpack/crud/fields/select2.blade.php) (View: /home/vagrant/Code/hrd/resources/views/vendor/backpack/crud/fields/select2.blade.php) (View: /home/vagrant/Code/hrd/resources/views/vendor/backpack/crud/fields/select2.blade.php)
This is my DistrictCrudController.php :
<?php
namespace App\Http\Controllers\Admin;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use App\Http\Requests\DistrictRequest as StoreRequest;
use App\Http\Requests\DistrictRequest as UpdateRequest;
class DistrictCrudController extends CrudController {
public function __construct() {
parent::__construct();
$this->crud->setModel("App\Models\District");
$this->crud->setRoute("admin/district");
$this->crud->setEntityNameStrings('district', 'districts');
$this->crud->setFromDb();
$this->crud->addField([
'label' => "City",
'type' => 'select2',// the method that defines the relationship in your Model
'name' => 'city_id', // the db column for the foreign key
'entity' => 'cities', //tabel entity
'attribute' => 'id', // foreign key attribute that is shown to user
'model' => "App\Models\City" // foreign key model
]);
}
public function store(StoreRequest $request)
{
return parent::storeCrud();
}
public function update(UpdateRequest $request)
{
return parent::updateCrud();
}
}
The code is run well if i remove :
$this->crud->addField([
'label' => "City",
'type' => 'select2',// the method that defines the relationship in your Model
'name' => 'city_id', // the db column for the foreign key
'entity' => 'cities', //tabel entity
'attribute' => 'id', // foreign key attribute that is shown to user
'model' => "App\Models\City" // foreign key model
]);
I use Backpack for Laravel 5.2
Not sure if it will solve, but i can only see two issues that might be causing that.
You don't have cities relationship defined or you could try using:
public function setUp()
{
$this->crud->setModel("App\Models\District");
$this->crud->setRoute("admin/district");
$this->crud->setEntityNameStrings('district', 'districts');
$this->crud->setFromDb();
...
...
don't use parent::__construct().
Give it a try and post your results if not solved.

Laravel 4.2: Can't Use Transformer with DB::Raw Query

Throughout my app, I have been taking the results of an Eloquent query and channeling it through a transformer and it is working well. This is what I am doing:
public function index()
{
$users = User::with('profile', 'location', 'role')->get();
return $this->respond([
'data' => $this->userTransformer->transformCollection($users->all())
]);
}
However, I ran into a situation where to produce a nested resource I needed to use a DB::RAW query
public function byLoan($id)
{
$users = DB::select( DB::raw("SELECT * FROM users WHERE id IN (SELECT DISTINCT(user_id) FROM farms WHERE user_id = {$id})") );
return $this->respond([
'data' => $this->userTransformer->transformCollection($users->all())
]);
}
The code above gave me this error "Symfony \ Component \ Debug \ Exception \ FatalErrorException (E_ERROR) Call to a member function all() on array".
I changed transformCollection($users->all()) to transformCollection($users) and now the error is this "Symfony \ Component \ Debug \ Exception \ FatalErrorException (E_ERROR) Cannot use object of type stdClass as array".
I don't know what else to try.
My Transformer class looks like this:
<?php namespace Acme\Transformers;
abstract class Transformer {
public function transformCollection(array $items)
{
return array_map([$this, 'transform'], $items);
}
public abstract function transform($item);
}
And the UserTransformer implentation:
<?php namespace Acme\Transformers;
class UserTransformer extends Transformer
{
public function transform($arr)
{
//return $arr;
return [
'id' => $arr['id'],
'username' => $arr['username'],
'abr' => $arr['abr'],
'email' => $arr['email'],
'phone' => $arr['phone'],
'role_id' => $arr['role_id'],
'role_abr' => $arr['role']['abr'],
'role' => $arr['role']['role'],
'loc_id' => $arr['location']['id'],
'loc_abr' => $arr['location']['loc_abr'],
'region_id' => $arr['location']['region_id'],
'is_admin' => (boolean) $arr['is_admin'],
'is_manager' => (boolean) $arr['is_manager'],
'show_agency' => (boolean)$arr['profile']['show_agency'],
'show_balance_due' => (boolean)$arr['profile']['show_balance_due'],
'show_close_date' => (boolean)$arr['profile']['show_close_date'],
'show_commit_arm' => (boolean)$arr['profile']['show_commit_arm'],
'show_region' => (boolean)$arr['profile']['show_region'],
'show_season' => (boolean)$arr['profile']['show_season']
];
}
}
First off, don't use all() on a DB::select. The select method does execute the query as soon as it's called. Also all() is for Eloquent models only.
However the bigger problem here, is how a Query Builder result is structured. Its an array (of all rows) filled with objects (the individual row, with properties for each column)
So that means, passing it to your transform method and then accessing the columns like an associative array doesn't work. Example:
$arr['id']
What you would have to do instead is:
$arr->id // obviously the name $arr doesn't make any sense now because its an object..
If this messes up the other usages of transform() you should also be fine by just adding
$arr = (array) $arr;
at the beginning of the function. This converts the object into an array and makes sure you can access it like $arr['id']

Resources