[php] Trying to get property of non-object - Laravel 5

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?

This question is related to php laravel

The answer is


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.


It happen that after some time we need to run

 'php artisan passport:install --force 

again to generate a key this solved my problem ,


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

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>

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

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

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.