laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.21k stars 10.89k forks source link

forPage wrong formating #18844

Closed deiks closed 7 years ago

deiks commented 7 years ago

Description:

Hi,

When returning posts from database and when using forPage, it returns array of objects (post object) when current page is set to 1, but if >= 2, it returns object of objects with preset keys. So we must do array_values to get it proper.

Steps To Reproduce:

->forPage(1, 10)

and

->forPage(2, 10)

themsaid commented 7 years ago

@deiks please post a full example of your code, how you start the query and how you get the results make a big difference.

deiks commented 7 years ago

Hello @themsaid

Thanks for answering. This is code:

`<?php

private function populateListingsData($listings, $paginate = true) { $userId = Auth::id() ?: false; $wishlist = [];

if ($userId) {
    $wishlist = new Wishlist;
    $wishlist = $wishlist->where('wishlist.user_id', $userId)->get();
}

$listings = $listings->whereNull('listings.deleted_at')
->leftJoin(
    'cities',
    'cities.id',
    '=',
    'listings.city_id')
->leftJoin(
    'city_parts',
    'city_parts.id',
    '=',
    'listings.city_part_id')
->leftJoin(
    'characteristic_listing',
    'characteristic_listing.listing_id',
    '=',
    'listings.id')
->leftJoin(
    'listing_types',
    'listing_types.id',
    '=',
    'listings.listing_type_id')
->leftJoin(
    'offer_types',
    'offer_types.id',
    '=',
    'listings.offer_type_id')
->leftJoin(
    'regions',
    'regions.id',
    '=',
    'listings.region_id')
->leftJoin(
    'gallery',
    'gallery.listing_id',
    '=',
    'listings.id')
->select(
    'listings.*',
    'cities.name as city_name',
    'city_parts.name as city_part_name',
    'listing_types.name as listing_type_name',
    'offer_types.name as offer_type_name',
    'regions.name as region_name',
    DB::raw('(GROUP_CONCAT(gallery.name ORDER BY gallery.position ASC)) as `gallery`'),
    DB::raw('(GROUP_CONCAT(characteristic_listing.listing_characteristic_id)) as `characteristics`'))
->orderBy('listings.created_at', 'desc')
->groupBy('listings.id')
->get();

$listings = collect($listings)->map(function ($listing) use ($userId, $wishlist) {
// format price
    $listing->price_formatted = $listing->price
    ? number_format($listing->price, 0, '', '.')
    : NULL;

// check if is in wishlist
    $listing->in_wishlist = false;
    if ($userId && !empty($wishlist)) {
        foreach ($wishlist as $item) {
            if ($listing->id == $item->listing_id) {
                $listing->in_wishlist = true;
            }
        }
    }

// generate gallery array
    if (! $listing->gallery) {
        $listing->gallery = [];
    } else {
        $listing->gallery = explode(',', $listing->gallery);
    }

// generate listing characteristics
    if (! $listing->characteristics) {
        $listing->characteristics = [];
    } else {
        $listing->characteristics = explode(',', $listing->characteristics);
    }

    return $listing;
});

if ($paginate) {
    return $listings->forPage($this->currentPage, $this->itemsPerPage);
}

return $listings;

}`

themsaid commented 7 years ago

You need to call ->values() after forPage() to reset the array keys for every page, having non sequential keys or an array that doesn't start with a 0 index will cause the behaviour you just described when the result is converted to JSON.

deiks commented 7 years ago

Can I ask what's point of that laravel doesn't resets by itself?