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

WallyJ's avatar

Referencing a variable within a controller is not recognized

If I have relationships set up for the following: Contacts have ContactNotes Contacts have Deals Deals have Tasks

public function show($id)
    {
        $contacts = Contact::find($id);
        $contactnotes = Contactnote::orderBy('created_at', 'desc')->where('contact_id', '=', $contacts->id)->get();
        $deals = Deal::where('contact_id', '=', $contacts->id)->get();
        $tasks = Task::where('deal_id', '=', $deals->id);
        // Check for correct user
        if(auth()->user()->id !== $contacts->user_id){
            return redirect('/contacts')->with('error', 'That Is Not Your Contact');
        }
        return view('contacts.show')
        ->with('contact', $contacts)
        ->with('contactnotes', $contactnotes)
        ->with('deals', $deals)
        ->with('tasks', $tasks);
    }

I am getting an error "Property [id] does not exist on this collection instance." because I am obviously doing something wrong in the "$tasks=" line.

I am making things a little difficult here because the contact view (show) pulls in the contact info, the contact notes, and then includes deals.index, which brings in the task info.

I tried to simply reference $tasks in the DealsController, but I'm thinking that since the Contacts view is the primary view being called, all variables have to be defined within that controller function. Am I right about that?

Or can you include a file, and it's part of it's own controller will be called?

0 likes
42 replies
Sergiu17's avatar
$contacts = Contact::with('contactnotes')->with('deals.tasks')->get();

dd($contacts);

I think this should work in your case.

1 like
WallyJ's avatar

But wouldn't that get rid of the use of the ID it's pulling from the URL?

Sergiu17's avatar

@WallyJ ohh, yes.

$contacts = Contact::with('contactnotes')->with('deals.tasks')->find($id);

Instead of get() use find($id). Try this and tell me if works

1 like
WallyJ's avatar

Same error. Same line - $tasks

public function show($id)
    {
        $contacts = Contact::with('contactnotes')->with('deals.tasks')->find($id);
        $contactnotes = Contactnote::orderBy('created_at', 'desc')->where('contact_id', '=', $contacts->id)->get();
        $deals = Deal::where('contact_id', '=', $contacts->id)->get();
        $tasks = Task::where('deal_id', '=', $deals->id)-get();
        // Check for correct user
        if(auth()->user()->id !== $contacts->user_id){
            return redirect('/contacts')->with('error', 'That Is Not Your Contact');
        }
        return view('contacts.show')
        ->with('contact', $contacts)
        ->with('contactnotes', $contactnotes)
        ->with('deals', $deals)
        ->with('tasks', $tasks);
    }
Sergiu17's avatar

@WallyJ delete this entirely

// DETELE THIS.
$contactnotes = Contactnote::orderBy('created_at', 'desc')->where('contact_id', '=', $contacts->id)->get();
$deals = Deal::where('contact_id', '=', $contacts->id)->get();
$tasks = Task::where('deal_id', '=', $deals->id)-get();

Try this. your delas, your tasks your contactnotes will be in be in collection if you have setup relationships properly

// TRY THIS
public function show($id)
{
    $contacts = Contact::with('contactnotes')->with('deals.tasks')->find($id);

    dd($contacts);

        if(auth()->user()->id !== $contacts->user_id){
            return redirect('/contacts')->with('error', 'That Is Not Your Contact');
        }

        return view('contacts.show')
        ->with('contact', $contacts)
        ->with('contactnotes', $contactnotes)
        ->with('deals', $deals)
        ->with('tasks', $tasks);
}
1 like
WallyJ's avatar

All of the information shows, so the relationships are working, but if I remove the dd($contacts);, I receive the error "Undefined variable: contactnotes" on this line:

->with('contactnotes', $contactnotes)
Sergiu17's avatar

@WallyJ ContactsController.php =>

public function show($id)
{
    $contacts = Contact::with('contactnotes')->with('deals.tasks')->find($id);

    if(auth()->user()->id !== $contacts->user_id){
        return redirect('/contacts')->with('error', 'That Is Not Your Contact');
    }

    return view('contacts.show')
    ->with('contact', $contacts)
    ->with('contactnotes', $contacts->contactnotes)
    ->with('deals', $contacts->deals);
    // ->with('tasks', $tasks); this work will be done in front end.
}

show.blade.php =>

// this is in view file. I think it makes sense, you separate all your tasks by deal
@foreach ($deals as $deal)
    {{ $deal->name }}
    @foreach($deal->tasks as $task)
        {{ $task->title }}
    @endforeach 
@endforeach 
1 like
WallyJ's avatar

That makes sense.

However, when I try to use this code in my view, I receive a "Invalid argument supplied for foreach()"

@foreach($contactnotes as $contactnote)
                                <li class="list-group-item">
                                    <p>{{$contactnote->created_at->diffForHumans()}} - {{$contactnote->contactnotetext}}</p>
                                </li>
                                @endforeach

I did a {{dd($contactnotes)}} in the view to test and it only shows quotation marks - ""

It doesn't like something about the variable, or the way I used it.

Also, I tried changing $contactnotes as $contactnote to:

$contacts->contactnotes as $contactnote, and it gave me a "Undefined variable contacts" error on that line.

Sergiu17's avatar

@WallyJ do a quick check in your controller

public function show($id)
{
    $contacts = Contact::with('contactnotes')->with('deals.tasks')->find($id);

    if(auth()->user()->id !== $contacts->user_id){
        return redirect('/contacts')->with('error', 'That Is Not Your Contact');
    }

    dd($contacts->contactnotes, $contacts->deals); // ADD THIS LINE TO SEE IF THERE ARE ANY CONTACTNOTES AND DEALS ASSOCIATED WITH TASKS
}
1 like
WallyJ's avatar

Yes. It returns an array of 2 items (deals), and under item 0, the #relations has an array of 1 task, and under its attributes it shows the fields. So the data is connected.

There's something in the naming between the controller and the view that is off. I just can't figure out what.

Sergiu17's avatar

@WallyJ

 return view('contacts.show')
    ->with('contact', $contacts)
    ->with('contactnotes', $contacts->contactnotes)
    ->with('deals', $contacts->deals);

Now open contacts/show.blade.php

{{ dd($contactnotes, $deals) }} 

Do you get something ?

1 like
WallyJ's avatar

Yes. Same array.

So it's getting the deals, but not the contactnotes.

Actually, it technically returns:

""

Collection {#744)

So I am getting the quotation marks instead of the contact notes collection

Sergiu17's avatar

@WallyJ now start looping through it, and display all concatnotes, all deals and tasks' deals

Make sure that there are some contactnotes associated with current category

1 like
WallyJ's avatar

There are definitely notes associated with that contact. That part was working before I added the tasks.

WallyJ's avatar

Contact Model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Contact extends Model
{
    public function User()
    {
        return $this->belongsTo(User::class);
    }
    
    public function Contactnotes()
    {
        return $this->hasMany(Contactnote::class);
    }
    
    public function Deals()
    {
        return $this->hasMany(Deal::class);
    }

    public function addContactnote($contactnotetext)
    {
            $this->contactnotes()->create(compact('contactnotetext'));
    }

}

Sergiu17's avatar

@WallyJ lol, ok. let's get back to the initial example

This is your example.

$deals = Deal::where('contact_id', '=', $contacts->id)->get();
$tasks = Task::where('deal_id', '=', $deals->id);

You could do something like this, but it's a bit odd.

$deals = Deal::where('contact_id', '=', $contacts->id)->get(); // Collection of deals.

// You can't say $deals->id, because it's a collection
// $tasks = Task::where('deal_id', '=', $deals->id);
// Instead
$tasks = Taks::where('deal_id', '=', $deals[0]->id)->get(); // You will get an error if $deals is an empty collection
1 like
WallyJ's avatar

I think there's something wrong with this line:

$contacts = Contact::with('contactnotes')->with('deals.tasks')->find($id);

Because it works for deals, but not for contactnotes.

JoaoPedroAS51's avatar

@WallyJ Try to change Contactnote::class to 'App\Contactnote', I know it is the same thing, but for me it fixed an error.

1 like
JoaoPedroAS51's avatar

@WallyJ And here you do not need two with, you can use an array $contacts = Contact::with(['contactnotes', 'deals.tasks'])->find($id);

1 like
Sergiu17's avatar

@WallyJ there's nothing wrong, since you do dd() in your controller and you get all the information. Make sure your don't overwrite your $contactnotes variable in view, otherwise, I've no idea what it could be.

@JoaoPedroAS51 awesome example with array in with() method :)

1 like
WallyJ's avatar

Thanks @JoaoPedroAS51 . That looks cleaner. And I changed the Model as you suggested. No change.

The dump of the $contactnotes still gives ""

WallyJ's avatar

@Sergiu17, You gave me an idea, so I went back to my controller and did a:

dd($contacts->contactnotes);

and it returned the quotation marks. So the view is not the problem.

JoaoPedroAS51's avatar

@WallyJ What returns if you remove deals.tasks?

$contacts = Contact::with('contactnotes')->find($id);

dd($contacts);
1 like
WallyJ's avatar

Returns the Contact Info for the contact.

Also includes a "relations" array with 3 contactnotes and their values.

Now if I change the first line back the way it was and dd($contacts) I get everything.

Sergiu17's avatar
dd($contacts);

Returns the Contact Info for the contact.

Also includes a "relations" array with 3 contactnotes and their values.

dd($contacts->contactnotes);

Returns " " ( quotation marks )

?

1 like
WallyJ's avatar

It's the strangest thing... If I perform:

dd($contacts);

I get back:

Contact {#585 ▼
  #connection: "mysql"
  #table: null
  #primaryKey: "id"
  #keyType: "int"
  +incrementing: true
  #with: []
  #withCount: []
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: false
  #attributes: array:26 [▶]
  #original: array:26 [▶]
  #changes: []
  #casts: []
  #dates: []
  #dateFormat: null
  #appends: []
  #dispatchesEvents: []
  #observables: []
  #relations: array:2 [▼
    "contactnotes" => Collection {#640 ▶}
    "deals" => Collection {#744 ▶}
  ]
  #touches: []
  +timestamps: true
  #hidden: []
  #visible: []
  #fillable: []
  #guarded: array:1 [▶]
}

And I can click through the relations and see the contactnotes collection and the deals collection.

If I perform:

dd($contacts->deals)

I get back:

Collection {#744 ▼
  #items: array:2 [▼
    0 => Deal {#682 ▶}
    1 => Deal {#683 ▶}
  ]
}

With only the deals collection, as expected.

However, if I perform:

dd($contacts->contactnotes);

I get back this:

""

That's it... a set of quotation marks... That's the only thing on the page. I am baffled.

JoaoPedroAS51's avatar

@WallyJ Just to test, what returns if you remove contactnotes from with and call it later?

$contacts = Contact::with('deals.tasks')->find($id);

dd($contacts->contactnotes);
1 like
JoaoPedroAS51's avatar

@WallyJ And to make the return cleaner, change the with to an array

return view('greetings', ['contact' => $contacts, 'contactnotes' => $contacts->contactnotes, 'deals' => $contacts->deals]);
1 like
JoaoPedroAS51's avatar

@WallyJ To make sure that a simple thing is not giving error, change the Contactnotes to contactnotes in your Contact Model

1 like
Next

Please or to participate in this conversation.