lara28580's avatar

Query with pagination does not work

I wanna search default, popular and recent on my articles table but I dont get this to work. Until now I tried it with recent and created_at but not even that works. If recent is in my url it only works for the first page. Someone knows what I have to do?

Link

<li class="nav-item"><a class="nav-link" href="/?recent">{{ __('Recent') }}</a></li>

Controller

 public function index(Categorie $categorie = null) {

        $orderBy = request()->exists('recent') ? 'created_at' : 'votes_count';

        $articles = Article::with('user', 'categorie')
            ->withCount('votes')
            ->forCategorie($categorie)
            ->where('approved', 1)
            ->orderBy($orderBy, 'desc')
            ->paginate(20);

        return view('pages.article.articles', compact('articles'));

View

<div class="container">
    <div class="row">
        <div class="col-md-10">
            @forelse($articles  as $article)
            <button data-id="{{ $article->id }}" class="btn vote {{ Auth::check() && Auth::user()->votedFor($article) ? 'btn-success' : 'btn-default' }}">{{ $article->votes->count() }}</button>
            <div class="headline">
                <h1 class="title"><a href="{{ $article->link }}">{{ $article->title }}</a></h1>
                <a href="/article/categorie/{{ $article->categorie->slug }}" class="badge badge-secondary" style="background: {{ $article->categorie->color }}">{{ $article->categorie->title }}</a>
                <p class="meta text-muted">
                  <span>{{ $article->updated_at->diffForHumans() }} by <a href="/user/{{ $article->user->id }}">{{ $article->user->username}}</a></span> &middot;
                  <a class="text-muted" href="{{ url('/article', $article->id) }}">{{count($article->comments)}} Comments</a>
                </p>
            </div>
            @empty
            <h2>There are no entries, sorry!</h2>
            @endforelse

          <div class="pagination-container">
            {{ $articles->appends(request()->query())->links() }}
          </div>
        </div>
    </div>
</div>
0 likes
8 replies
jlrdw's avatar

Does the query work without paginating.

lara28580's avatar

yes it even works with pagination but only for the first page.... I mean 'recent' here, votes_count works perfectly

click's avatar

That is because your 'recent' query parameter has a null value and is not appended to the next/prev link.

If you change it to something like ?sort=recent it does work.

The reason is that Laravel uses http_build_query() internally and this removes the null values. See this simple example:

$q = [
    'A' => '',
    'B' => null,
    'C' => 1
];
dd(http_build_query($q));

it gives you the url: A=&C=1

1 like
jlrdw's avatar

Pass an appends array to view instead of:

{{ $articles->appends(request()->query())->links() }}

Replace request()->query() with a good array.

1 like
jlrdw's avatar

In controller example:

$params = ['dogid' => $dogid];  // can add more to array as needed

$params passed to view normal way.

View example:

echo '<td>' . $dogs->appends($params)->links() . '</td>';

But convert yours to blade.

lara28580's avatar

How should I get the params in my $orderBy variable? How should it looks like? Added $params in my Controller like you said @jlrdw

click's avatar
click
Best Answer
Level 35

Just read the param from the query, if not set fallback to a default.

You could do something like:

$orderBy = 'votes_count';
$allowedOrderBy = ['created_at','some_other_field'];
if (in_array(request()->query('order'), $allowedOrderBy)) {
    $orderBy = request()->query('order');                       
}

Your url will look like: ?page=3&sort=created_at

And what you dit with appends() was already good. So no need to change anything there I think.

 {{ $articles->appends(request()->query())->links() }}
1 like

Please or to participate in this conversation.