Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jasonmccallister's avatar

Blade - using conditionals on a relationship that can return null.

So I ran into a templating issue with Blade last night and was hoping for some help…

Here is a quick synopsis:

I have a template that needs to show and hide a section based on a conditional of a relationship… To keep it simple, I’m going to relate this to a Task app…

First, here is the controller:

$project = Project::with(’tasks')->findOrFail($id);

return view('projects.tasks', compact('project'));

When no tasks are present, it obviously returns a null value - expected.

Now the template it self needs to show a a button if no value is assigned to the task upload, as an example:

{{ $project->tasks->uploaded_document }}

In the template, I need to show an hide a button based on that condition (is there a document?), easy right? So I tried this:

@if(is_null($project->tasks->uploaded_document))
// show the upload a document button
@else
// show the link to the document

Pretty straight forward with a seeded database… Then the tricky part comes along… What happens when the he `t relationship is null? This error is thrown, and for good reasons…

Trying to get property of non-object

Because the tasks relationship is null… So there is my predicament, I can’t really change the template design - not my call. So, I’m sure there is a better way to handle this.. Anyone want to give it a go?

0 likes
5 replies
shawnyv's avatar

It's probably inelegant, but what about another if statement that simply looks at the $project variable?

@if(count($project) > 0)
    @if(is_null($project->tasks->uploaded_document))
        ...
    @endif
@endif
1 like
willvincent's avatar

When no tasks are present, it obviously returns a null value - expected.

So, shouldn't you be checking if $project->tasks is null, rather than $project->tasks->uploaded_document?

@if(is_null($project->tasks))
// show the upload a document button
@else
// show the link to the document

Or perhaps test both?

@if(is_null($project->tasks) || is_null($project->tasks->uploaded_document))
// show the upload a document button
@else
// show the link to the document
1 like
jasonmccallister's avatar

Those both kind of do the trick.. But this design has multiple tasks per page and the design requires editing one task and saving, not one button for all... So it's kind of tricky template-fu.

ATOM-Group's avatar

Well, from what I can infer from your API, that's going to fail anyway.

$project->tasks

is a collection is it not? (implied by the pluralization of tasks).

In which case you can't call uploaded_document because that's a property of a single task, not the collection. So given that, your problem is self-solving:

@foreach($project->tasks as $task)
    @if ($task->uploaded_document)
        // ...
     @else
        // ...
     @endif
@endforeach

Given tasks is an empty collection, it will still iterate without failing, but iterate 0 times.

If however tasks is indeed a single object, I would personally move the uploaded_document field from task, to the project itself, or write a wrapper in your Project object:


public function hasUploadedDocument() {
     return !is_null($this->tasks) || !is_null($this->tasks->uploaded_document); // something to this effect
}
3 likes

Please or to participate in this conversation.