Each category with the quantity of posts

What seems to be the problem:
I am trying to get the quantity of posts in each category.

Steps to Reproduce:
I have a livewire component, which displays side menu of categories. I have added a line

$this->postsCount = Post::where(‘category_id’, ‘=’, $id)->count();

to get the quantity of posts in each category.
Here is my component:

<?php

namespace App\Http\Livewire;

use App\Models\Post;
use Livewire\Component;
use App\Models\Category;

class Cats extends Component
{
    public $categories, $postsCount;

    public function mount(Category $id)
    {
        $this->categories = Category::all();
        $this->postsCount = Post::where('category_id', '=', $id)->count();
    }

    public function render()
    {
        return view('livewire.cats');
    }
}

Here is my view of the side menu

@foreach($categories as $category)
    <ul class="list-group list-group-flush">
        <li class="list-group-item">
            <a href="{{ route('category', $category->id) }}" style="font-size:16px;color: black">
                {{ $category->name }} {{ $category->postsCount }}
            </a>
        </li>
    </ul>
@endforeach

So, I get just 0 near each category.
Relationships between posts and categories are the following:

public function category()
    {
        return $this->belongsTo(Category::class);
    } 

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

Are you using the latest version of Livewire:
Yes

Guys, pls help🙏

Hi, you can achieve this by this way
In your category model create your relation like this

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

then to get how many post per category you do this

Category::select(‘name’)->withCount(‘post’)->get();

You will get two fields the category name: name and the count like this post_count,
with this you will get what you looking for

Here you’re binding (Category $id) so it’s a Category entity or object, and after you’re trying to use that $id like a identifier, and that’s wrong. So, or you made $id->id or change the binded name like $category and after trigger it by the id like $category->id

Hey, @nataly

You are using dependency injection to get the category collection, so you have two options here:

First Method

public function mount(Category $category)
{
   $this->postsCount = Post::where('category_id', $category->id)->count();
} 

Second Method (Recommended)

Use a relationship like this

In Category.php Model create a method with hasMany relationship

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

and in your livewire component

public function mount(Category $category)
{
 $this->postsCount = $category->posts->count();
}

For more info take a look here:
https://laravel.com/docs/8.x/controllers#dependency-injection-and-controllers

And here for relationships:
https://laravel.com/docs/8.x/eloquent-relationships#one-to-many

1 Like

My solution is very very simple!! Here look. I have added just {{ $category->posts->count() }}. And that’s it!

@foreach($categories as $category)
    <ul class="list-group list-group-flush">
        <li class="list-group-item">
            <a href="{{ route('category', $category->id) }}" style="font-size:16px;color: black">
                {{ $category->name }} {{ $category->posts->count() }}
            </a>
        </li>
    </ul>
@endforeach

I make nothing in controllers and models. This is my categories controller. It is so simple! It just render all the categories. I deleted the line, regarding an extra variable $postsCount

<?php

namespace App\Http\Livewire;

use App\Models\Post;
use Livewire\Component;
use App\Models\Category;

class Cats extends Component
{
    public $categories;

    public function mount(Category $id)
    {
        $this->categories = Category::all();
    }

    public function render()
    {
        return view('livewire.cats');
    }
}

So, you’re not using dependency injection…don’t need the mount anymore or the parameter in this function…in facts since the first question you made changes there, but thx anyway for share your worries. :sweat_smile: :upside_down_face:

I am new to Livewire. And to programming at all. I know nothing, that’s why I am stuck at easy questions. I have no idea, what injections are. I read about them today in the first time and have understood nothing.
After your replies I thought that my solution would have to be easier. That’s it.
Now I have another challenge with likes. After some days I will ask again​🤣

All we, always are new in everything…so I would be glad for help you any way. But it’s important, even in the simple things, that you understand the logic behind your code and when, where and how use every statement to avoid undesired behaviors. Read the docs, try to use examples and see why providers recommend everything…after that, let fly your creativity! :star_struck: :crazy_face: :rofl:

Yeah you are right! I read the docs every day. And thank you for offering help)

1 Like