I'm having trouble with my query when using pagination and offset in Livewire 3. My query is supposed to display the latest articles, but I want to offset 4 articles because I've already created a display of the 4 latest articles in the section above.
However, when I add ->offset(4), it doesn't work at all. Why is that? Or am I doing something wrong?
<?php
namespace App\Livewire\Web\Post;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;
class ArticleIndex extends Component
{
use WithPagination;
public $lang;
public $dataCategories;
#[Url('c')]
public $filterCategory = null;
#[Url('y')]
public $filterTrending = null;
public $filterSearch = null;
public function mount()
{
$this->dataCategories = DB::table('taxonomy_terms')->where('taxonomy', 'article_categories')->get();
}
public function render()
{
$dataArticle = DB::table('entries')->where('collection', 'article')
->when($this->filterSearch, function ($query) {
return $query->whereRaw("LOWER(JSON_UNQUOTE(JSON_EXTRACT(data, '$.title'))) LIKE ?", ['%' . strtolower($this->filterSearch) . '%']);
})
->when($this->filterCategory, function ($query) {
return $query->whereJsonContains('data->article_categories', \Str::slug($this->filterCategory));
})
->where('site', $this->lang == "en" ? "english" : "indonesia")
->orderBy('date', 'desc')
->where('published', true)
->offset(4)
->paginate(5);
return view('livewire.web.post.article-index', compact('dataArticle'));
}
public function search()
{
$this->resetPage();
$this->filterSearch == $this->filterSearch;
}
public function updatedFilterCategory()
{
$this->resetPage();
}
public function updatedFilterYear()
{
$this->resetPage();
}
}
->offset(4)->paginate(5)
this won't do what you expect, because paginate()
always resets the SQL OFFSET
. in simple term OFFSET(4)
is immediately overwritten.
Since you need to skip 4 articles, I would suggest this way
$entries = DB::table('entries')
->where('collection','article')
->where('site', $this->lang == 'en' ? 'english' : 'indonesia')
->where('published', true)
->orderBy('date','desc')
->limit(4) # you can remove this if its matches the above conditions. (Ex: when you have more item to skip)
->get();
# take IDs
$entriesIds = $entries->pluck('id')->all();
$dataArticle = DB::table('entries')
->where('collection','article')
->where('site', $this->lang == 'en' ? 'english' : 'indonesia')
->where('published', true)
->when($this->filterSearch, fn($q) =>
$q->whereRaw("LOWER(JSON_UNQUOTE(JSON_EXTRACT(data,'$.title'))) LIKE ?", ['%'.strtolower($this->filterSearch).'%'])
)
->when($this->filterCategory, fn($q) =>
$q->whereJsonContains('data->article_categories', Str::slug($this->filterCategory))
)
->whereNotIn('id', $entriesIds) # skipp in here
->orderBy('date','desc')
->paginate(5);