'Laravel 8: Attempt to read property "id" on null

I am facing this error 'Attempt to read property "id" on null' in Laravel 8. It was working fine before but in my view I changed $user->id to $user->profile->id and now this is happening. I am logged in the app and I have changed my route accordingly to match profile id, I have also tried clearing cache etc.

Here is my Code:

User Model:

    class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var string[]
     */
//    protected $fillable = [
//        'name',
//        'email',
//        'password',
//    ];

    protected $table = 'users';
    protected $guarded = [];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function setPasswordAttribute($password)
    {
        $this->attributes['password'] = bcrypt($password);
    }

    public function posts ()
    {
        return $this->hasMany(Post::class);
    }

    public function profile()
    {
        return $this->hasOne(Profile::class);
    }
}

Profile Model:

class Profile extends Model
{
    use HasFactory;

    protected $table = 'profiles';
    protected $guarded = [];

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

ProfilesController:

class ProfilesController extends Controller
{
    public function show(User $user)
    {
        return view ('profiles.index', compact('user'));
    }
    
    public function edit(User $user)
    {
        return view ('profiles.index', compact('user'));
    }
}

Route:

    Route::get('profile/{profile}', [ProfilesController::class, 'show'])->middleware('auth');
Route::get('profile/{profile}/edit', [ProfilesController::class, 'edit'])->middleware('auth');

View:

<x-layout>
<section class="py-8 max-w-4xl mx-auto">
    <h1 class="text-lg font-bold mb-8 pb-2 border-b">
        @if ($user->id == auth()->user()->id)
        Hello {{ $user->name }}, welcome to your profile.
        @else
        {{ $user->name }}'s Profile.
        @endif
    </h1>
    <div class="flex">
        <aside class="w-48 flex-shrink-0">
            <h4 class="font-semibold mb-4">
                Navigation
            </h4>
            <ul style="max-width: 75%">
                <li>
                    <a href="/profile/{{ $user->profile->id }}" class="{{ request()->is('profile/'.$user->profile->id) ? 'text-blue-500' : '' }}">View Profile</a>
                </li>
                <li>
                        @if ($user->id == auth()->user()->id)
                            <a href="/profile/{{ $user->profile->id }}/edit" class="{{ request()->is('profile/'.$user->profile->id.'/edit') ? 'text-blue-500' : '' }}">Edit Profile</a>
                        @endif
                </li>
            </ul>
        </aside>
        <main class="flex-1">
            <x-panel>
                <div class="flex flex-col">
                    <div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
                        <div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
                            <div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
                                <div class="flex flex-row grid-cols-12">
                                    <div class="flex flex-col col-span-4 row-span-full justify-items-start flex-grow-0 flex-shrink-0 grid-cols-4">
                                        <div class="flex flex-row">
                                            <img src="http://i.pravatar.cc/60?u={{ $user->profile->id }}" alt="" width="" height="" class="rounded-full h-24 w-24 flex m-2">
                                        </div>
                                    </div>
                                    <div class="flex flex-col col-span-8 justify-right grid-cols-8 text-sm">
                                        <div class="flex flex-row">
                                            <div class="flex flex-col col-span-2 font-semibold">
                                                <div class="pt-3">Name:</div>
                                                <div class="pt-3">Email:</div>
                                                <div class="pt-3">About:</div>
                                            </div>
                                            <div class="flex flex-col col-span-10">
                                                <div class="pt-3 pl-4 text-justify">{{ $user->profile->name }}</div>
                                                <div class="pt-3 pl-4 text-justify">{{ $user->profile->email }}</div>
                                                <div class="pt-3 pl-4 text-justify"><p>{{ $user->profile->description }}</p></div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </x-panel>
        </main>
    </div>
</section>


Solution 1:[1]

I think the problem is that you are passing a Profile model as indicated by your routes, but the method is looking for a User model.

Show and Edit have a User Model as a parameter. If you pass the Profile id, the method is gonna find the User model by id but with the id of the Profile model and not the user_id of the Profile model.

You will need to change the methods to:

public function show(Profile $profile)
{
    $user = $profile->user;
    return view ('profiles.index', compact('user'));
}

public function edit(Profile $profile)
{
    $user = $profile->user;
    return view ('profiles.index', compact('user'));
}

With this code the Profile model is found and via the relationship the User is obtained and passed to the view.

Solution 2:[2]

public function edit($id)
    {
        $table = Table::find($id);
        return view('tables.edit', compact('table'));
    }

    public function update(Request $request, $id)
    {
        $table = Table::find($id);
        $table->update($request->all());
        return redirect('/tables');
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Laurel
Solution 2 Simon Fairio