Valkyrurr
Valkyrurr

Reputation: 119

Eloquent relationship fails to work unless dd()ed in view

Reference: Laravel Eloquent relationship not an object when doing anything but dd()

I am trying to output a Laravel relationship in Blade. However, this, {{ $video->channel->id }} returns a non-object error. But, when dded, like so, {{ dd($video->channel->id) }}, a value is there. I've been pulling my hair so hard because of this... What is going on? Why is there an output only when the variable is dded?

I'm testing on PHP 7.2 with Laravel 5.6. Relationships are established as per Eloquent documentation. I've tried fetching the data like this:

$videos = Video::where('foo', 'bar')->with('channel')->take(100)->get();

and

$videos = Video::where('foo', 'bar')->take(100)->get();

The same thing; same output/error.

$tokens = preg_split("/[\s,]+/", $q);
$videos = Video::with('channel')
  ->where(function ($query) use ($tokens) {
    foreach ($tokens as $token) {
      $query->orWhere('title', 'LIKE', "%$token%");
    }
   })
  ->take(100)
  ->get();
// foreach ($videos as $video)
{{ $video->channel->id }} // non-object error
{{ dd($video->channel->id) }} // WORKS! IDK Why...

Trying to get property 'id' of non-object is the actual error log.

EDIT:
Below is an image of the $videos collection fetched from Database. If in dd(), something gets outputted fine, I can only assume I'm fetching the data right, yea?

enter image description here

Upvotes: 1

Views: 967

Answers (1)

Tim Lewis
Tim Lewis

Reputation: 29278

As you're doing this in a loop, the error

Trying to get property 'id' of non-object

means that 1 iteration of $video->channel returns a non-object (likely null), and you can't access the property ->id of it (as null doesn't have any properties, etc.)

The reason dd() works is that it's dumping and dieing on the first iteration, which has a channel. To handle this, simply add an @if() clause:

@foreach($videos AS $video)
  @if($video->channel)
    {{ $video->channel->id }}
  @else 
    ...
  @endif
  ...
@endforeach

Or, in the query to get $videos, enforce relationship:

$videos = Video::where('foo', 'bar')->has('channel')->with('channel')->take(100)->get();

This way, $video->channel will not be null.

Upvotes: 2

Related Questions