TimiAde's avatar

Pagination links not working in livewire

 public function paginate($items,$perPage)
    {
        $pageStart = \Request::get('page', 1);
        // Start displaying items from this number;
        $offSet = ($pageStart * $perPage) - $perPage; 

        // Get only the items you need using array_slice
        $itemsForCurrentPage = array_slice($items, $offSet, $perPage, true);

        return new LengthAwarePaginator($itemsForCurrentPage, count($items), $perPage,Paginator::resolveCurrentPage(), array('path' => Paginator::resolveCurrentPath()));
    }
    public function render()
    {
        $this->userchoice = $this->more_polls();

        return view('livewire.winning-states-poll' , ['userchoice' => 
            $this->paginate($this->userchoice, 30)
    
        ]);
    }

i am having a paginate method because $this->userchoice is an array not a collection

0 likes
26 replies
TimiAde's avatar

@webrobert when i use WithPagination. my query changes when i click the links

http://127.0.0.1:8000/morepolls?sortAsc=true&page=4

but the pages data dont change.

Sinnbeck's avatar

Why are you implementing your own pagination? It seems you are loading all items from the database in memory and then slicing it with php. Laravel was built in pagination that can do this on the database level

TimiAde's avatar

@jlrdw i have changed it to Collection and it is now working well

jlrdw's avatar

@TimiAde Just remember you don't want tens of thousands of records in a collection, I suggest let the database do the work. I would say no more than around 500, but not more.

TimiAde's avatar

@jlrdw Why? I might end up having such in this database. this is what i am using for the pagination.

public function paginate($items,$perPage = 5, $page = null, $options = [])
    {
        $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
        $items = $items instanceof Collection ? $items : Collection::make($items);
        return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
    }
Sinnbeck's avatar

@TimiAde There is a huge difference between having thousands of records in the database and in memory in php.

TimiAde's avatar

@Sinnbeck Okay. So how can i do it. Does collection store the data in php instead of database.

Sinnbeck's avatar

@TimiAde Yes. How are getting the data from the database in that code ? You should be able to just call. Replace x = 1 with the proper database query

        return view('livewire.winning-states-poll' , ['userchoice' => 
            Poll::where('x', 1)->paginate(30).
    
        ]);
TimiAde's avatar

@Sinnbeck i used array sorting since $userchoice is an array

 public function render()
    {
        $userchoice = $this->more_polls();
        if (!empty($this->sortField)) { 

            if($this->sortAsc){
                usort($userchoice, array($this, "asc"));
            } else {
                usort($userchoice, array($this, "desc"));
            }

        }
        return view('livewire.winning-states-poll' , ['userchoice' => 
            $this->paginate($userchoice, 30)
    
        ]);
    }

Please how can i solve the issue of Collection. What should i use for the pagination

Sinnbeck's avatar

@TimiAde it's hard when I still don't know the query. Maybe show the full component?

TimiAde's avatar

@Sinnbeck It is an array like this

[
  {
    "wins": [
      "Abia",
      "Akwa Ibom",
      "Anambra",
      "Bauchi",
      "Bayelsa",
      "Borno",
      "Cross River",
      "Ekiti",
      "FCT - Abuja",
      "Gombe",
      "Imo",
      "Jigawa",
      "Kano",
      "Katsina",
      "Kogi",
      "Lagos",
      "Plateau",
      "Rivers",
      "Sokoto",
      "Zamfara"
    ],
    "name": "Bradley Corwin",
    "party": "All Progressives Congress",
    "candidate": "Asiwaju Bola Tinubu",
    "count": 20
  },
...
]
Sinnbeck's avatar

@TimiAde so it does not come from the database at all? It's just a static array?

TimiAde's avatar

@Sinnbeck it comes from the database

$winnings = DB::table('users')
                        ->join('candidates', 'users.candidate_id', '=', 'candidates.id')
                        ->join('parties', 'candidates.party_id', '=', 'parties.id')
                        ->join('predictions', 'users.id', '=', 'predictions.user_id')
                        ->join('states', 'predictions.state_id', '=', 'states.id')
                        ->select('users.name', 'candidates.name as candidate','parties.fullname','predictions.user_prediction', 'states.state')
                        ->get()
                        ->groupBy('name');
Sinnbeck's avatar

@TimiAde ah so this is what you needed groupBy for. Can I suggest you reread my article and plan how this is going to look if you do the groupBy in the database (before the ->get ())

TimiAde's avatar

@Sinnbeck yes thanks a lot your article helped. So how can i use Databaase in the Array Paginate function instead of Collection

TimiAde's avatar

@jlrdw

public static function makeLengthAware($collection, $total, $perPage, $appends = null)
    {
        $paginator = new LengthAwarePaginator(
                $collection, $total, $perPage, Paginator::resolveCurrentPage(), ['path' => Paginator::resolveCurrentPath()]
        );

        if ($appends)
            $paginator->appends($appends);

        return str_replace('/?', '?', $paginator->render());
        
    }

should i use this for the paginate method as explained in your link, but my collection is an array ooo

TimiAde's avatar

@jlrdw i first got the result from the database using query builder then rearranged data from it and put it in an array or should i just arrange the query. Datatables are kind of difficult to work with.

$winnings = DB::table('users')
                        ->join('candidates', 'users.candidate_id', '=', 'candidates.id')
                        ->join('parties', 'candidates.party_id', '=', 'parties.id')
                        ->join('predictions', 'users.id', '=', 'predictions.user_id')
                        ->join('states', 'predictions.state_id', '=', 'states.id')
                        ->select('users.name', 'candidates.name as candidate','parties.fullname','predictions.user_prediction', 'states.state')
                        ->get()
                        ->groupBy('name');

then did this

 $userchoice = array();
        foreach ($winnings as $key => $value) {
            # code...
            $winning = [];
            $winning['wins'] = array();
            foreach ($value as $user) {
                # code...
                $winning['name'] = $user->name;
                $winning['party'] = $user->fullname;
                $winning['candidate'] = $user->candidate;
                if($user->user_prediction > 50){
                    array_push($winning['wins'], $user->state);
                }
                if( !next( $value ) ) {
         
                   $winning['count'] = count($winning['wins']);
                }
            }

            array_push($userchoice, $winning);
        }

Maybe i should rearrange the query result $winnings then

jlrdw's avatar

@TimiAde Don't use array or collection, just use orderby (ORDER BY) and paginate as needed.

Please or to participate in this conversation.