Laravel: Trying to get property of non object - php

I have been writing a web application in the Laravel framework andhave come across an issue I am having with getting certain data for a user. The user structure of my web application is based on a main users table, then I have an RP table for all the users statistics such as health, energy, items they own, and so on.
When visiting a page I am trying to display this data on I am receiving the following error
Trying to get property of non-object (View: C:\workspace\mainwebsite\resources\views\frontend\home.blade.php)
O simply tried to print out the user_id column of the roleplay table for the user (and yes, I have tried other columns they output the same result)
<div class="panel panel-default">
<div class="panel-body">
{{ Auth::user()->roleplay->user_id }}
</div>
</div>
Here is my user table class:
<?php
namespace App\Database\Website\User;
use Hash;
use Eloquent;
use \Illuminate\Auth\Authenticatable;
use \Illuminate\Contracts\Auth\Authenticatable as Authentication;
class Player extends Eloquent implements Authentication
{
use Authenticatable;
protected $primaryKey = 'id';
protected $table = 'users';
public $timestamps = false;
protected $fillable = [];
public function setPasswordAttribute($value)
{
$this->attributes['password'] = Hash::make($value);
}
public function setUsernameAttribute($value)
{
return $this->attributes['username'] = $value;
}
public function roleplay()
{
return $this->hasOne('App\Database\Website\User\Roleplay', 'user_id');
}
}
Here is my roleplay table class:
<?php
namespace App\Database\Website\User;
use Eloquent;
class Roleplay extends Eloquent
{
protected $primaryKey = 'id';
protected $table = 'srp_user_statistics';
public $timestamps = false;
protected $fillable = ['user_id'];
public function user()
{
return $this->belongsTo('App\Database\Website\User\Player', 'user_id', 'id');
}
}

Check to make sure that your current user has a roleplay object. Eloquent will return null for empty relationships.
<div class="panel panel-default">
#if(Auth::user()->roleplay)
<div class="panel-body">
{{ Auth::user()->roleplay->user_id }}
</div>
#endif
</div>
Question: why not just get the authorized user's id ({{Auth::user()->id}}) ? It appears that the roleplay object is related to the user on that id anyway; why go through a relationship to fetch an id that you already have?
Related:
Laravel Blade template how to return null instead of ErrorException when trying to get property of non-object

Probably, the authentication doesn't work in your webapp.

This is pretty basic debugging, you just need to figure out what part of that expression is not returning an object.
If the user isn't logged in, then Auth::user() would return null and since you are chaining ->roleplay after that, it would give you this error.
If Auth::user() is returning something but Auth::user()->roleplay returns null, then you would get this error because you are trying to chain ->user_id onto the end of null. The likely cause for this would be there is no roleplay data in the database for the logged in user or there is something wrong with your relationship.

By seeing your problem, it seems that you're fetching user's roleplay without actually checking that what auth()->user() is originally returning. If there isn't any authenticated user, it will return null.
You should use auth()->check() before fetching user from auth like this:
<div class="panel panel-default">
<div class="panel-body">
{{ (auth()->check()) ? auth()->user()->roleplay->user_id : '' }}
</div>
</div>
If the user is currently authenticated, then you should fetch the user details. auth()->check() returns a boolean value - false: if user isn't authenticated else it returns true
Hope this helps!

Related

laravel how to get use with relation in blade after login

I am using Laravel 8 and the User model has relation with model UserProfile
as following
class User extends Authenticatable
{
use LaratrustUserTrait;
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
.
.
.
public function profile(){
return $this->hasOne(UserProfile::class,'user_id');
}
}
when i create a new user i directly do login for him and redirect him to dashboard
as following
Auth::login($user, true);
return $this->sendSuccessResponse();
but my question is how i can use user data with it's userProfile relation in blade or controller
I tried to use the following code in blade
<img src="{{Auth::user()->profile->image}}" id="profile-img" alt="">
but i get the following error message
Attempt to read property "image" on null
Your profile relationship is either malformed or missing.
This error means that you are trying to get the property image on a value of null.
That's because Auth::user()->profile returns null, then Auth::user()->profile->image is like writing (null)->image.
This can be caused by several things:
Missing data in the database
Wrong columns name
Wrong tables name
The easiest thing to bypass this error would be to only display the image when this relationship isn't null:
#if(Auth::user()->profile !== null)
<img src="{{Auth::user()->profile->image}}" id="profile-img" alt="">
#endif
However, it would be better to understand why it's null, at least to avoid further problems in your project.
Apply these changes in your User model. I think it will work for you.
User Model
class User extends Authenticatable
{
/**
* The relationships that should always be loaded.
*
* #var array
*/
protected $with = ['profile'];
/**
* Get the user profile.
*/
public function profile()
{
return $this->hasOne(UserProfile::class);
}
}

Why does Livewire run a new query on each render and why are relationships lost

Scenario
What i try to do
I am creating a multicolumn user index page, where the right column shows details from the user selected in the left column.
When selected, the user is not pulled out of the collection but freshly out of the database, so the data is up to date.
I defer the loading of the user list using the described method in the livewire documentation.
The user has a 'roles' relationship, which is displayed in the list column.
What I'd expect
I would expect that once the $this→users is set as a collection of the users and a user is selected, only the query will fire for getting the data for this user.
What actually happens
When a user is selected, a query for getting all users from the database is run (again), and because of the fact that the roles from the user are displayed in the list view, for each user, a new query is executed.
After that, a query for getting the selected user is executed. Afterwards another query for getting the roles of the user is fired to.
So my questions
Why does Livewire lose the relations that were eager loaded in the first declaration of public $users?
Why is it that Livewire reruns the query for getting all users, while the public $users is already defined as a collection of users?
Files:
UserListDetail.php
<?php
namespace App\Http\Livewire;
use App\Models\User;
use Livewire\Component;
class UsersListDetail extends Component {
public string $search = '';
public $users;
public $selectedUser;
public int $timesRun = 0;
public bool $readyToLoadUserList = false;
protected $queryString = [
'search' => [ 'except' => '' ],
];
// Defer loading users
public function readyToLoadUserList()
{
// Get all users with roles relationship
$this->users = User::with('roles')->get();
$this->readyToLoadUserList = true;
}
public function selectUser(int $userId)
{
$this->selectedUser = User::with('roles')->find($userId);
}
public function render()
{
return view('livewire.users-list-detail', [
'selectedUser' => $this->selectedUser,
]
);
}
}
simplified version of user-list-detail.blade.php
<div>
<div wire:init="readyToLoadUserList">
#if($readyToLoadUserList)
<ul>
#foreach($users as $user)
<li wire:click="selectUser({{ $user->id }})">
{{ $user→name_first }} {{ $user→name_last }},
#foreach($user→roles as $role)
{{ $role→label }},
#endforeach
</li>
#endforeach
</ul>
#endif
</div>
<div>
#isset($selectedUser)
{{ $name_first
#endisset
</div>
</div>
When selectUser() method is triggered, the livewire will re-render the blade and since wire:init="readyToLoadUserList" is there, it will load every user (again).
Replce readyToLoadUserList() with mount() and simply keep wire:init="" empty.
Also, condition with #if($users->count() > 0)

Trying to get property of non-object in ;laravel array displaying

I have a laravel fetching controller like below,
public function fetchbywhere()
{
$result=User::find(2);
return View::make('fetchbywhere')->with('resultrow',$result);
}
My Model file of User.php like,
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $table = 'users';
protected $hidden = array('password', 'remember_token');
}
and my routes.php file ,
Route::get('select-by-where',array('as'=>'select_by_where','uses'=>'Test#fetchbywhere'));
and my view file named fetchbywhere.blade.php,
<title>Fetch by Where clouse</title>
<h2>Users - Where clouse</h2>
#foreach($resultrow as $data)
<ul>
<li>{{$data->name}}</li>
</ul>
#endforeach
my database have fields like
id|name|email|age|created_at|updated_at
am getting error like Trying to get property of non-object (View: E:\wamp\www\new_laravel\app\views\fetchbywhere.blade.php)
anybody please give me a solution. t
thanks
You are using User::find(2) this returns a single instance of User with id = 2. Or even null if it doesn't exist. In your view you are iterating over $resultrow as if it where a collection and not a single model.
I believe what you actually want to do is something like this:
$result=User::where('some-column', 'operator', 'some-value')->get();
return View::make('fetchbywhere')->with('resultrow',$result);
So an example could be...
$result=User::where('age', '>', '18')->get();
return View::make('fetchbywhere')->with('resultrow',$result);
...to get everybody over 18
Also its "where clause" not clouse ;)
Update
The actual use for the find method is to get only one object with the passed id (primary key in the database). It doesn't return a collection (list) because there no way it could find multiple rows with the same id, since the primary key is unique.
If you only want one user (by a specific id) you have to change your view to directly access the model
<title>Fetch by Where clouse</title>
<h2>Users - Where clouse</h2>
{{ $resultrow->name }}

Undefined variable laravel 4.1

I am trying to get data from database and pass values to controller. I am new at laravel and thats the first query. Here is my code:
class Cars extends Eloquent
{
}
FleetController.php
public function index()
{
$fleet = Cars::all()->first()->Description;
return View::make('pages.home')->with('fleet', $fleet);
}
home.blade.php
#extends('layouts.default')
#section('content')
{{ $fleet }}
#stop
The problem is that it shows this at log
Next exception 'ErrorException' with message
'Undefined variable: fleet (View: C:\wamp\www\laravel\app\views\pages\home.blade.php)' in C:\wamp\www\laravel\app\storage\views\7da5cff457f71f3156f90053865b6cb1:2
Stack trace:
You should try using
#if(Session::has('fleet'))
{{Session::get('fleet')}}
#endif
Your '->with()' just flashes the variable to your session. You still need to retrieve it from there though.
Also, you should try creating a model with the same name as your table. If you were to create a model Car that extends Eloquent, it will automatically be linked to your Cars table. Laravel docs:
The lower-case, plural name of the class will be used as the table
name unless another name is explicitly specified.
This part is important as well:
Eloquent will also assume that each table has a primary key column
named 'id'.
Once you got that configured, you'll be able to get the description of a car by simple doing
Car::all()->first()->description;
See also: Laravel docs on eloquent
Update
What should work:
Car.php
class Car extends Eloquent{
//Let's try setting these manually. Make sure they are correct.
protected $table = 'cars';
protected primaryKey = 'id';
}
FleetController.php
public function index()
{
//You have to call the model here, so singular 'Car'.
$fleet = Car::all()->first()->Description;
return View::make('pages.home')->with('fleet', $fleet);
}
home.blade.php
#extends('layouts.default')
#section('content')
//You can use blade's #if as well:
#if(Session::has('fleet'))
{{Session::get('fleet')}}
#endif
#stop

Laravel 4: Eloquent relationship get all data

I have 2 relationship data table; users table and memberdetails table.
Users.php
class Users extends Eloquent{
public function memberdetails()
{
return $this->hasOne('Memberdetails','user_id');
}
}
Memberdetails.php
class Memberdetails extends Eloquent{
public function user()
{
return $this->belongsTo('Users','user_id');
}
}
When I try to retrieve data, with $data = User::find($id); I only get data from users table.
Example of my blade form:
{{-- User's Name, stored on user table --}}
{{ Form::text('name',null, array('id'=>'name','class'=>'form-control','required')) }}
{{-- User's address, stored on member table --}}
{{ Form::text('address',null, array('id'=>'address','class'=>'form-control','required')) }}
When I visit, localhost/user/2/edit/, the name field is populated, but address field is empty. How can I retrieve data from both tables and put into a form for editing?
Thank you.
You could use eager loading.
$user = User::with('memberdetails')->find($id);
Using this, you will automatically get the memberdetails when retrieving the user. Then you can use $user->memberdetails
Using eager loading, you do only one query to the DB so it should be the preferred way. If you dont use the with('memberdetails'), you will perform a second query when accessing the memberdetails.
After getting the user instance, access the relationship, then you can access the other class properties
$user = User::find($id);
$userData = $user->memberdetails;

Categories