I am creating a eCommerce application, where product of each category has their own attributes and specifications, which can be filtered by the user.
| Product Category | Attributes |
|---|---|
| Desktop PC | Processor, Processor speed, RAM memory, Graphcis card, etc |
| Phones | Battery, Screen size, RAM, Memory |
| Televisions | Brand, Screen size, Color, |
Each category-based product has a set value of the specifications in the attribute_product table that has columns product_id, attribute_id and attribute_value.
In the class below I set if condition if some atributte is selected to filter
My SearchComponent class
class SearchComponent extends Component
{
use WithPagination;
public $search = '';
public $categoryId;
public $filters = [
];
public function mount($categoryId){
$this->category_id = $categoryId;
}
public function render()
{
$q = Product::query();
if($this->filters){
$q->whereHas('attributes', function ($q) {
foreach ($this->filters as $key => $values) {
$q->where(function($q) use ($key, $values) {
$q->where('attribute_id', $key)->whereIn('attribute_value', $values);
});
}
});
}
$products = $q->where('category_id',$this->category_id)
->whereLike('name', $this->search ?? '')
->paginate(12);
$specifications = Attribute::
join('attribute_category','attributes.id','=','attribute_category.attribute_id')
->where('attribute_category.category_id',$this->category_id)
->select(['attributes.*'])
->get();
return view('livewire.search-component',compact('products','specifications'));
}
}
The product model has relationships BelongsToMany with a table attribute_product containing the set values attributes
My livewire search-component.blade
@foreach($specifications as $spec)
<div class="sidebar-widget mt-30">
<h4 class="pro-sidebar-title">{{ $spec->attribute_name }} </h4>
@if($spec->type_id == "1")
<div class="pro-sidebar-search mb-50 mt-25">
<div class="pro-sidebar-search-form">
<input type="text" wire:model="filters.{{ $spec->id }}" placeholder="Search here..." />
</div>
</div>
@endif
@if($spec->type_id == "2")
<ul>
<li>
<div class="sidebar-widget-list-left">
<input wire:model="filters.{{ $spec->id }}" type="checkbox" value=""> {{ $spec->attribute_name }}
</div>
</li>
</ul>
@endif
@if($spec->type_id == "3")
<select wire:model="filters">
<option value="">Select {{ $spec->id}}</option>
@foreach(explode(',',$spec->options) as $key=>$row)
<option value="{{$row}}">{{ $row }}</option>
@endforeach
</select>
@endif
</div>
</div>
@endforeach
I get the error "count(): Argument #1 ($value) must be of type Countable|array, string given" when I select any attribute to filter.
I tried some combinations but without success. Does anyone have any suggestions on how to solve this problem?