slickness

I changed it and cleaned the routes. Now I have a new error:

"Invalid argument supplied for foreach () (View: ...views \ profiles \ profile.blade.php)"

tykus
tykus
1 month ago (471,560 XP)

Are you still using @foreach($post as $posts) instead of @foreach($posts as $post)? Or @forelse if you have gone that way?

slickness

What is the right way now? i use @forelse

This:

public function index($slug)
    {
      $user = User::where('slug', $slug)->first();

      return view('profiles.profile')
            ->with('user', $user)
            ->with('posts', $user->posts);

    }


    public function getpost()
    {
        $posts = auth()->user()->posts()->whereIn('type', [4, 5])->latest()->get();

        return view('profiles.profile')
            ->with('posts', $posts);

    }

or this:

    public function index($slug)
    {
      $user = User::where('slug', $slug)->first();
      $posts = auth()->user()->posts()->whereIn('type', [4, 5])->latest()->get();

      return view('profiles.profile')
            ->with('user', $user)
            ->with('posts', $posts);

    }

view:

@forelse ($posts as $post)
                                  @if ($post->type === 4) //prints posts with type 4
                                  <a class="img-hover" href="#">
                                      <img class="br-3 img-fluid" src="{{ Storage::url($post->image) }}" alt="" />
                                  </a>
                                  @else //prints posts with type 5
                                  <a class="img-hover" href="#">
                                      <img class="br-3 img-fluid" src="{{ Storage::url($post->video) }}" alt="" />
                                  </a>
                                  @endif
                              @empty
                                  No Posts are available //your custom msg
                              @endforelse
tykus
tykus
1 month ago (471,560 XP)

Invalid argument supplied for foreach () suggests that the $posts variable is not a Collection instance as expected. If you do not have a posts relationship on User model, then $user->posts will return null and potentially result in the error you are seeing!!!

Either controller method will work depending on what posts you want to display - you are potentially getting a different user's posts in this case:

$user = User::where('slug', $slug)->first();
$posts = auth()->user()->posts()->whereIn('type', [4, 5])->latest()->get();

return view('profiles.profile')
    ->with('user', $user) // this user might not be the same as auth()->user()
    ->with('posts', $posts); // these posts belong to auth user

whereas, this way you are finding a user and then getting his posts:

$user = User::where('slug', $slug)->first();

return view('profiles.profile')
    ->with('user', $user)
    ->with('posts', $user->posts); // posts belong to the user found above via posts() relationship
slickness

@tykus Thanks for your explanations.

I just want to display the type 4 and 5 from the posts and the latest ones first.

Would that have to work that way?

    public function index($slug)
    {
      $user = User::where('slug', $slug)->first();

      return view('profiles.profile')
            ->with('user', $user)
            ->with('posts', $user->posts->whereIn('type', [4, 5])->latest);

    }

That's my relationship between the models:

User Model

    public function post()
    {
      return $this->hasMany('App\Post');
    }

Post Model

  public function user()
  {
    return $this->belongsTo(User::class, 'user_id');
  }
tykus
tykus
1 month ago (471,560 XP)

Call the relationship posts since there are many posts associated with the user:

public function posts()
{
    return $this->hasMany('App\Post');
}

In the controller, load posts scoped to the user and with your required constraints:

public function index($slug)
{
    $user = User::where('slug', $slug)->first();
    $posts = $user->posts()->whereIn('type', [4, 5])->latest()->get();

    return view('profiles.profile')
        ->with('user', $user)
        ->with('posts', $posts);

    }

You could eager-load using with but it amounts to the same number of queries, so the solution above is just fine

slickness

@tykus Thank you so much it works. I have another question: If I need all the posts in the same view (profile) but in another tab, what's the best implementation?

Please sign in or create an account to participate in this conversation.