Home > database >  ErrorException - Trying to get property 'name' of non-object
ErrorException - Trying to get property 'name' of non-object

Time:10-02

Sorry I am new to Laravel and PHP. I have a web application code that I need to debug. I run the code, and it gives me ErrorException Trying to get property 'name' of non-object. I looked it up, and I know it's a common problem but I still cannot figure out what is causing this error. I already looked at this page and I don't understand: Reference - What does this error mean in PHP?

This is my controller code:

    function getActivity(){
    $lead_history = Lead::with('user','eventTypeTrashed','locationTrashed')->get();
    $event_history = Event::with('user','booking','contactus.event_type_trashed','booking.location_trashed')->get();
    
    $data = [];
    foreach ($lead_history as $key => $leads){
        if(count($leads->revisionHistory) > 0){
            foreach ($leads->revisionHistory as $history){
                $date_diff = \DateTime::createFromFormat('Y-m-d H:i:s',date('Y-m-d H:i:s'))->diff(\DateTime::createFromFormat('Y-m-d H:i:s',date('Y-m-d H:i:s',strtotime($history->updated_at))));
                if($date_diff->d > 0 ){
                    $date = $date_diff->d . ' days ago';
                } elseif($date_diff->h > 0){
                    $date = $date_diff->h . ' hours ago';
                }else{
                    $date = $date_diff->i . ' minutes ago';
                }
                $data[] = [
                    'id' => $leads->id,
                    'type' => 'lead',
                    'image' => $history->userResponsible()->user_avatar,
                    'user' => $history->userResponsible()->first_name .' '. $history->userResponsible()->last_name,
                    'user_id' => $history->userResponsible()->id,
                    'key' => ucwords(str_replace("_"," ",$history->fieldName())),
                    'client' => $leads->client_name,
                    'status' => 'update',
                    'old_value' =>$history->oldValue(),
                    'new_value' =>$history->newValue(),
                    'updated_at' => $history->updated_at,
                    'time_diff' =>$date,
                    'priority' => $leads->priority,
                    'location' => $leads->locationTrashed->name, // This line casuses an error
                    'event_type' => ($leads->eventTypeTrashed) ? $leads->eventTypeTrashed->name : ''
                ];

            }
        }
        $date_diff = \DateTime::createFromFormat('Y-m-d H:i:s',date('Y-m-d H:i:s'))->diff(\DateTime::createFromFormat('Y-m-d H:i:s',date('Y-m-d H:i:s',strtotime($leads->created_at))));
        if($date_diff->d > 0){
            $date = $date_diff->d . ' days ago';
        } elseif($date_diff->h > 0){
            $date = $date_diff->h . ' hours ago';
        }else{
            $date = $date_diff->i . ' minutes ago';
        }
        $data[] = [
            'id' => $leads->id,
            'type' => 'lead',
            'image' => $leads->user->user_avatar,
            'user' => $leads->user->first_name .' '. $leads->user->last_name,
            'user_id' => $leads->user->id,
            'key' => '',
            'client' => $leads->client_name,
            'status' => 'created',
            'updated_at' => $leads->created_at,
            'old_value' =>'',
            'new_value' =>'',
            'time_diff' =>$date,
            'priority' => $leads->priority,
            'location' => $leads->locationTrashed->name,
            'event_type' => ($leads->eventTypeTrashed) ? $leads->eventTypeTrashed->name : ''
        ];
    }

    foreach ($event_history as $key => $events){
        if(count($events->revisionHistory) > 0){
            foreach ($events->revisionHistory as $history){
                $date_diff = \DateTime::createFromFormat('Y-m-d H:i:s',date('Y-m-d H:i:s'))->diff(\DateTime::createFromFormat('Y-m-d H:i:s',date('Y-m-d H:i:s',strtotime($history->updated_at))));
                if($date_diff->d > 0){
                    $date = $date_diff->d . ' days ago';
                }elseif ($date_diff->h > 0){
                    $date = $date_diff->h . ' hours ago';
                }else{
                    $date = $date_diff->i . ' minutes ago';
                }
                $data[] = [
                    'id' => $events->id,
                    'type' => 'event',
                    'image' => $history->userResponsible()->user_avatar,
                    'user' => $history->userResponsible()->first_name .' '. $history->userResponsible()->last_name,
                    'user_id' => $history->userResponsible()->id,
                    'key' => ucwords(str_replace("_"," ",$history->fieldName())),
                    'client' => $events->booking->booking_name,
                    'status' => 'update',
                    'updated_at' => $history->updated_at,
                    'old_value' =>$history->oldValue(),
                    'new_value' =>$history->newValue(),
                    'time_diff' =>$date,
                    'priority' => $events->status,
                    'location' => $events->booking->location_trashed->name,
                    'event_type' => $events->contactus->event_type_trashed->name
                ];
            }
        }
        $date_diff = \DateTime::createFromFormat('Y-m-d H:i:s',date('Y-m-d H:i:s'))->diff(\DateTime::createFromFormat('Y-m-d H:i:s',date('Y-m-d H:i:s',strtotime($events->created_at))));
        if($date_diff->d > 0){
            $date = $date_diff->d . ' days ago';
        }elseif($date_diff->h > 0){
            $date = $date_diff->h . ' hours ago';
        }else{
            $date = $date_diff->i . ' minutes ago';
        }
        $data[] = [
            'id' => $events->id,
            'type' => 'event',
            'image' => ($events->user) ? $events->user->user_avatar : '',
            'user' => ($events->user) ? $events->user->first_name .' '. $events->user->last_name : '',
            'user_id' => ($events->user) ? $events->user->id : '',
            'key' => '',
            'client' => $events->booking->booking_name,
            'status' => 'created',
            'updated_at' => $events->created_at,
            'old_value' =>'',
            'new_value' =>'',
            'time_diff' => $date,
            'priority' => $events->status,
            'location' => $events->booking->location_trashed->name,
            'event_type' => $events->contactus->event_type_trashed->name
        ];
    }

    usort($data, function ($a, $b){
        $dateA = \DateTime::createFromFormat('Y-m-d H:i:s', $a['updated_at']);
        $dateB = \DateTime::createFromFormat('Y-m-d H:i:s', $b['updated_at']);
        return $dateB >= $dateA;
    });

    return $data;
}

Sorry if this is a bad question and please tell me if I need to include anything else

CodePudding user response:

This error occurs when there's no relational record found. Like in your code you've a relation "locationTrashed". When lead don't have any record related to it in location_trashed table it'll return error. In Laravel 8 you can return default model result if not results available against record or just simply use ($param ?? null).

CodePudding user response:

You have a lot going on there! I have some suggestions that might make your life easier and your code cleaner. But first, the missing 'name' error...

'location' => $leads->locationTrashed->name,

Relationship Name

First thing I noticed about this relationship is the name should be 'location_trashed' instead of the camelCase 'locationTrashed'. In your other models, it is 'location_trashed', so make sure this is correct. I'll continue to reference it as locationTrashed, since this is what your current code reflects.

Finding the Cause

You're probably correct in identifying this line as causing the error. The issue is probably that the locationTrashed doesn't exist. You should look for the locationTrashed_id (or location_trashed_id) to figure out what the id is, and make sure the item exists in the database and hasn't been deleted.

Which Object Doesn't Exist?

If you aren't sure which object is causing the error, you can try dumping the object if the relationship doesn't exist. Laravel has convenient methods like has() and doesntHave() to make this easy. Put this right above the '$data[] = [' line.

https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence

if($leads->doesntHave('locationTrashed')) {
    dd($leads);
}
$data[] = [
    'id' => $leads->id,
    'type' => 'lead',
...

This will let you see the object in question and determine which related 'locationTrashed' is missing.

Or... ignore it

If you need the relationship, use the above to try to figure it out. However, if the relationship isn't there because it doesn't always exist, set it to be ignored.

You can use an exists() method on the relationship to check if it exists.

'location' => ($leads->locationTrashed()->exists()) ? $leads->locationTrashed->name : ''

Now some suggestions:

Carbon for Dates

You should really look into using Carbon. This will take the 8 lines of code you have and reduce it to:

$date_diff = Carbon::parse($history->updated_at)->diffForHumans();

https://carbon.nesbot.com/docs/#api-humandiff

Attribute Accessors

Your user model has a first_name and last_name attribute that you're putting together to display their full name. If you do this often, you can set up an attribute accessor so you don't have keep doing it.

// User Model
public function getFullNameAttribute() {
    return $this->first_name.' '.$this->last_name;
}

// Controller
'user' => $history->userResponsible->full_name

https://laravel.com/docs/8.x/eloquent-mutators#accessors-and-mutators

Laravel Collections

When working with arrays, you can instead convert them into collections and take advantage of the many useful methods that it provides. Instead of ordering the data items yourself, you can use the sortBy() method:

$collection = collect($data)->sortBy('updated_at');
$collection = collect($data)->sortByDesc('updated_at'); // or descending

https://laravel.com/docs/8.x/collections

  • Related