Framework: Pagination links() not preserving query string in url

Created on 1 Jun 2017  路  18Comments  路  Source: laravel/framework

  • Laravel Version: 5.4.24
  • PHP Version: 7.0.19/7.1.2
  • Database Driver & Version: 5.7.17

Description:

Unlike stated at https://laravel.com/docs/5.4/pagination#displaying-pagination-results, I'm not able to preserve query string in the links generated by this function. The links() function only adds ?page=n with n the page index(es), but removes all other query strings params.

Steps To Reproduce:

Paginate a query result in a page containing some query string parameters in GET (e.g. http://www.mydomain.com/posts/search?user_id=29&sort=1), and, in the corresponding view, call the
links() function on the LengthAwarePaginator object.

Controller:

public function search(Request $request){
    // Create a query which looks for Posts with the parameters of $request
    // ........
    $posts = $query->paginate(12);
    return view("posts.search")
        ->with("posts", $posts);
}

View:

{{ $posts->links() }}

This will generate (for page 2) the link http://www.mydomain.com/posts/search?page=2 - instead of the expected http://www.mydomain.com/posts/search?user_id=29&sort=1&page=2

Workaround:

I've found this workaround: I pass all Input parameters, except page, to the appends() function.

{{ $posts->appends(Illuminate\Support\Facades\Input::except('page'))->links() }}

Most helpful comment

A simplier way is to use {{ $posts->appends(request()->except('page'))->links() }}. That's the behaviour since 4.2 and I think it's correct.

All 18 comments

A simplier way is to use {{ $posts->appends(request()->except('page'))->links() }}. That's the behaviour since 4.2 and I think it's correct.

If that is the correct behaviour, then the documentation lacks some details:

The links method will render the links to the rest of the pages in the result set. Each of these links will already contain the proper page query string variable.

And what do you think is wrong?

proper page query string variable

Means ?page variable not another variables.

You're right, @decadence , I misread the docs, putting an extra (s) at the end of "variable".

You can just do {{ $users->appends(request()->query())->links() }}, no need for except()

This seems the closest to what im trying to do, in the middleware im trying to append a debug query param, if its set, and pass it to any link thats clicked, automatically, so you dont have to add it back to the url each time to toggle it back on. Basically if i have the param ?debug=true set, i want it to remain. Im using the middleware on 5.4 to achieve this, but im getting stuck on how to add the parameter into teh return $next($request); in the handle() method.

How can i append the parameter to remain in the url. Does this just need to be added in the routes web.php instead and added to all links, or can i inject this somehow to remain in the middleware?

handle method

    public function handle($request, Closure $next)
    {
      $queryString = \Request::getQueryString();
        if($queryString)
        {
          // Check if have ?debug=true
          if(\Request::get('debug') &&
            strtolower(\Request::get('debug')) == 'true')
          {
            /**
             * only run this if on stage env, less processsing, and only if there
             *  is an error
             */
              if(config('app.env') === 'stage')
              {
                config(['app.debug' => 'TRUE']);
                /**
                 * Switching this to debug apparently has no greater output to the
                 *  email, but leaving this since it might be useful in the event
                 *  the stage log needs to be referenced.
                 */
                config(['app.log_level' => 'debug']);
              }
          }
        }
        // ->fullUrlWithQuery(["debug"=>"true"])
        return $next($request);
    }

How can i inject the debug=true parameter here to remain on the browser address on all clicks until its removed? Im simply having a hard time grappling the $request i think, not knowing how to manipulate it to my needs.

thanks guys you all been a great help..

problem with this is, if i get query param city='Brisbane+City' when i click on pagination link it changes to city='Brisbane%20City' which is not right. I am trying to fix it using urlencode but it does not retain.. anyone got solution?

Works like a charm, thank you folks. Saved by day!
This works as well
{{ $users->appends(Request::except('page'))->links() }}

What if There is laravel custom pagination is implemented?

Did anyone find solution for URL encoding issue?

I have to use appends everywhere, why this is not the default behaviour?

I'd also like to learn why this is not the default behaviour. There must be a reason since this use case is obvious. @driesvints

Until then, here is a workaround:

in the boot() method of your AppServiceProvider :

$this->app->resolving(LengthAwarePaginator::class, static function (LengthAwarePaginator $paginator) {
    return $paginator->appends(request()->query());
});
$this->app->resolving(Paginator::class, static function (Paginator $paginator) {
    return $paginator->appends(request()->query());
});

Do not forget to import :

use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;

@webacers and @rajjanorkar I'm looking for an answer to the URL encoding issue as well. Any success?

When there is same key in URL dublicate will be removed when using appends(request()->query()) for example:

?business_model=physical&business_model=www

become

?business_model=www&page=2

@RomkaLTU It is the correct behaviour, passing twice the same key in url is not a good idea in general.

in your view where you display pagination...

{{ $results->appends(Request::except('page'))->links() }}

It success for me!
I hope it can help you

In Laravel 7.x you can use it like this:

{{ $results->withQueryString()->links() }}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SachinAgarwal1337 picture SachinAgarwal1337  路  3Comments

felixsanz picture felixsanz  路  3Comments

kerbylav picture kerbylav  路  3Comments

PhiloNL picture PhiloNL  路  3Comments

YannPl picture YannPl  路  3Comments