Altering a laravel pagination object

Viewed 25

I set up server side pagination for some of my views. Given this code in the blade template:

<div class="col-sm-12 col-md-12">
  {{ $sale_history->links('vendor.pagination.bootstrap-5') }}
</div>

I'm curious why this controller works

class SaleController extends Controller
{
    public function index()
    {
        $sale_history = Sale::orderByDesc('date')->paginate(15);

        $sale_history->each(function(&$sale) {
            
            $sale->customer_name = User::find($sale->customer_id)->displayname ?? "";
            $sale->product_name = $sale->product()->pluck('title')->first();
            $sale->product_expiry = $sale->subscription()->pluck('expiry_date')->first() ?? '';
            $sale->payment_amount = Money::EUR($sale->payment_gross()); //
            $sale->sale_points = $sale->points() ?? 0;
            $sale->sale_status = Str::ucfirst($sale->status);
        });

        return view('layouts.sales.index')->with(compact('sale_history'));
    }
}

But this doesn't

class SaleController extends Controller
{

    private function prepare_data($list){

        return $list->each(function(&$sale) {
            
            $sale->customer_name = User::find($sale->customer_id)->displayname ?? "";
            $sale->product_name = $sale->product()->pluck('title')->first();
            $sale->product_expiry = $sale->subscription()->pluck('expiry_date')->first() ?? '';
            $sale->payment_amount = Money::EUR($sale->payment_gross());
            $sale->sale_points = $sale->points() ?? 0;
            $sale->sale_status = Str::ucfirst($sale->status);
        });
    }


    public function index()
    {
        $sale_history = Sale::orderByDesc('date')->paginate(15);
        $sale_history = $this->prepare_data($sale_history);

        return view('layouts.sales.index')->with(compact('sale_history'));
    }
}

and produces this error:

Method Illuminate\Database\Eloquent\Collection::links does not exist.

So.. why does passing my data to a function as an argument causes it to lose its pagination references?

1 Answers

You are reassigning the value of $sale_history in the second example but not the first example. The value returned from each in your examples is the Collection contained within the Paginator instance; there is no each method for a Paginator, it forwards the call to the Collection it contains. The each method of Collections returns itself. So the return value from each is not the Paginator but a Collection so you should not be assigning that value to $sale_history as you now don't have a reference to the Paginator.

Also you don't need to reference the value being passed into the closure you are using, it is an object so it is already going to alter the object, not a copy of it.

TLDR: You are assigning the return value of each, which returns a Collection, to your variable. You don't need to reassign the variable as you want $sale_history to remain as the Paginator object.

Related