37
votes

I'm trying to echo out the name of the user in my article and I'm getting the ErrorException: Trying to get property of non-object. My codes:

Models

1. News

    class News extends Model
    {
      public function postedBy()
      {
         return $this->belongsTo('App\User');
      }
      protected $table = 'news';
      protected $fillable = ['newsContent', 'newsTitle', 'postedBy'];
    }

2. User

    class User extends Model implements AuthenticatableContract,
                                AuthorizableContract,
                                CanResetPasswordContract
    {
        use Authenticatable, Authorizable, CanResetPassword;

        protected $table = 'users';

        protected $fillable = ['name', 'email', 'password'];

        protected $hidden = ['password', 'remember_token'];

    }

Schema

table users

enter image description here

table news

enter image description here

Controller

public function showArticle($slug)
    {
        $article = News::where('slug', $slug)->firstOrFail();
        return view('article', compact('article'));
    }

Blade

{{ $article->postedBy->name }}

When I try to remove name in the blade {{ $article->postedBy }} it outputs the id, but when I try to add the ->name there it says Trying to get property of non-object but I have a field name in my table and a User model. Am I missing something?

9
Can you print_r($article);?aldrin27
@aldrin27 print_r directly in my controller? well actually everything works, I get every field but I can't get the relation. It gives me the errorwobsoriano
You need to foreach that inside your blade.aldrin27
@aldrin27 even if I use foreach I'm still getting the same errorwobsoriano
Do you have pivot table?aldrin27

9 Answers

89
votes

Is your query returning array or object? If you dump it out, you might find that it's an array and all you need is an array access ([]) instead of an object access (->).

33
votes

I got it working by using Jimmy Zoto's answer and adding a second parameter to my belongsTo. Here it is:

First, as suggested by Jimmy Zoto, my code in blade from

$article->poster->name 

to

$article->poster['name']

Next is to add a second parameter in my belongsTo, from

return $this->belongsTo('App\User');

to

return $this->belongsTo('App\User', 'user_id');

in which user_id is my foreign key in the news table.

17
votes

If you working with or loops (for, foreach, etc.) or relationships (one to many, many to many, etc.), this may mean that one of the queries is returning a null variable or a null relationship member.

For example: In a table, you may want to list users with their roles.

<table>
    <tr>
        <th>Name</th>
        <th>Role</th>
    </tr>
    @foreach ($users as $user)
    <tr>
        <td>{{ $user->name }}</td>
        <td>{{ $user->role->name }}</td>
    </tr>
    @endforeach
</table>

In the above case, you may receive this error if there is even one User who does not have a Role. You should replace {{ $user->role->name }} with {{ !empty($user->role) ? $user->role->name:'' }}, like this:

<table>
    <tr>
        <th>Name</th>
        <th>Role</th>
    </tr>
    @foreach ($users as $user)
    <tr>
        <td>{{ $user->name }}</td>
        <td>{{ !empty($user->role) ? $user->role->name:'' }}</td>
    </tr>
    @endforeach
</table>

Edit: You can use Laravel's the optional method to avoid errors (more information). For example:

<table>
    <tr>
        <th>Name</th>
        <th>Role</th>
    </tr>
    @foreach ($users as $user)
    <tr>
        <td>{{ $user->name }}</td>
        <td>{{ optional($user->role)->name }}</td>
    </tr>
    @endforeach
</table>

If you are using PHP 8, you can use the null safe operator:

<table>
    <tr>
        <th>Name</th>
        <th>Role</th>
    </tr>
    @foreach ($users as $user)
    <tr>
        <td>{{ $user?->name }}</td>
        <td>{{ $user?->role?->name }}</td>
    </tr>
    @endforeach
</table>
9
votes

I implemented a hasOne relation in my parent class, defined both the foreign and local key, it returned an object but the columns of the child must be accessed as an array.
i.e. $parent->child['column']
Kind of confusing.

5
votes

It happen that after some time we need to run

 'php artisan passport:install --force 

again to generate a key this solved my problem ,

4
votes

I had also this problem. Add code like below in the related controller (e.g. UserController)

$users = User::all();
return view('mytemplate.home.homeContent')->with('users',$users);
4
votes

Laravel optional() Helper is comes to solve this problem. Try this helper so that if any key have not value then it not return error

foreach ($sample_arr as $key => $value) {        
      $sample_data[] = array(       
        'client_phone' =>optional($users)->phone        
      );
    }
 print_r($sample_data);
4
votes

REASON WHY THIS HAPPENS (EXPLANATION)

suppose we have 2 tables users and subscription.

1 user has 1 subscription

IN USER MODEL, we have

public function subscription()
{
    return $this->hasOne('App\Subscription','user_id');
}

we can access subscription details as follows

$users = User:all();

foreach($users as $user){
    echo $user->subscription;
}

if any of the user does not have a subscription, which can be a case. we cannot use arrow function further after subscription like below

$user->subscription->abc   [this will not work] 
$user->subscription['abc']  [this will work]

but if the user has a subscription

$user->subscription->abc   [this will work] 

NOTE: try putting a if condition like this

if($user->subscription){
 return $user->subscription->abc;
}
0
votes

Worked for me:

{{ !empty($user->role) ? $user->role->name:'' }}