gilbitron / laravel-vue-pagination

A Vue.js pagination component for Laravel paginators
https://laravel-vue-pagination.org
MIT License
749 stars 144 forks source link

Invalid prop: type check failed for prop "data". Expected Object, got Array. #18

Closed dainemedia closed 2 years ago

dainemedia commented 6 years ago

When passing a Laravel paginator response to the data prop of this component I receive the following error:

Invalid prop: type check failed for prop "data". Expected Object, got Array.

The problem is, the data passed to the data prop is, in fact, an object and is indicated as so in Vue DevTools.

Screenshot

As you can see from the screenshot above, it is indeed an object, as expected by the component and indicated in the docs.

I'm using Vue 2.

Unless the type check is on the data property of the paginator response, then something is going wrong here.

That said, in the docs, it gives an example of the type of response required, and the data property of the paginator response is an array:

{
    current_page: 1,
    data: [],
    from: 1,
    last_page: 1,
    next_page_url: null,
    per_page: 10,
    prev_page_url: null,
    to: 1,
    total: 0,
}
GitzJoey commented 6 years ago

understand that this only a [Vue-Warn] but its would be nice if it can compatible with the laravel json response (without any warn shown)

gilbitron commented 6 years ago

I've just tested this with the latest version of Laravel and couldn't recreate the issue. I've updated the README.md to be more in line with current Vue/Laravel standards (i.e. using axios instead of vue-resource). Maybe having a look at the refreshed README.md might help?

The only things I can think of that might be causing this issue:

getResults(page = 1) {
    axios.get('example/results?page=' + page)
        .then(response => {
            this.laravelData = response.data;
        });
}

In this example:

GitzJoey commented 6 years ago

I'm using the latest laravel and also using the axios, you can check in my project https://github.com/GitzJoey/TKBARU/blob/master/resources/assets/js/apps/supplier.js (line 51)

I can provide you a test pen in my project github if want

abr4xas commented 6 years ago

I have this problem too...

This is my response:

{
    current_page: 1, 
    data: Array(10), 
    first_page_url: "http://localhost:8000/admin/post?page=1", 
    from: 1, 
    last_page: 17,
    ...
}

Error:

[Vue warn]: Invalid prop: type check failed for prop "data". Expected Object, got Array.

Btw:

With laravel 5.6.x

getResults(page = 1) {
    axios.get('example/?page=' + page) // <-- this 
        .then(response => {
            this.laravelData = response.data;
        });
}
sunscreem commented 6 years ago

I had the same problem.

I solved it by making sure I changed this:

<li v-for="post in laravelData" ...

to this:

<li v-for="post in laravelData.data" ...

palidaa commented 6 years ago

try to change initial value in data() from [] to {}.

GitzJoey commented 6 years ago

nope. still showing the warn i tried

laravelData : Object laravelData.data : Object

laravelData : Array laravelData.data : Object

sunscreem commented 6 years ago

Can you share your code, maybe we can spot that issue for you?

GitzJoey commented 6 years ago

@sunscreem https://github.com/GitzJoey/TKBARU/blob/master/resources/assets/js/apps/supplier.js

note: its standard live laravel project also if you care to run it (i can guide you to run it also)

sunscreem commented 6 years ago

@GitzJoey You see here:

https://github.com/GitzJoey/TKBARU/blob/c26742fae6fc15533d01c00ecabe3e471aa7f104/resources/assets/js/apps/supplier.js#L62

Can you show me a console.log on this.supplierList please?

ettiennelouw commented 6 years ago

I had the same issue but i was using a Resource to return my json then it gives you the output in this format instead of the norm.

screenshot 2018-06-15 12 30 49

From the Laravel Documentation

Data Wrapping And Pagination When returning paginated collections in a resource response, Laravel will wrap your resource data in a data key even if the withoutWrapping method has been called. This is because paginated responses always contain meta and links keys with information about the paginator's state:

https://laravel.com/docs/5.6/eloquent-resources#data-wrapping

gilbitron commented 6 years ago

@ettiennelouw Good shout. I've raised a separate issue for supporting Laravel's API Resources #22.

GitzJoey commented 6 years ago

@sunscreem hi, sorry for late response, here;s the console.log on line 62

capture
Hujjat commented 6 years ago

It's because your data is an array. It should be an object.

Yours is like this

data : [10]

It should be

data : {}

For me, it fixed the warning.

dieterc commented 5 years ago

I had the same problem.

I solved it by making sure I changed this:

<li v-for="post in laravelData" ...

to this:

<li v-for="post in laravelData.data" ...

This was also the fix for me

nazaninhesari commented 5 years ago

not work in laravel 5.5 larvael return default type of paginate , how i can convert it to object ?

BoraVivek commented 5 years ago

Make sure you are setting the data in variable as object instead of array

Firstly variable in data should be having {} instead of []

change : posts:[]

to posts:{}


If you have data.data in http call:

axios.get("api/post").then(({ data }) => (this.posts = data.data));

Change it to :

axios.get("api/post").then(({ data }) => (this.posts = data));


and in loop

if you have this :

<tr v-for="post in posts" :key="post.id">

add the data here like this :

<tr v-for="post in posts.data" :key="post.id">

ManojKiranA commented 5 years ago

try to change initial value in data() from [] to {}.

its worked like a charm

AliN11 commented 5 years ago

try to change initial value in data() from [] to {}.

How do you do that properly?

cvhainb commented 5 years ago

I have the same error. I have solved with this.

<div v-if="posts.total > 0">
    <pagination :data="posts" @pagination-change-page="getPaginationResults"></pagination>
</div>
rahmanrezaee commented 4 years ago

1: instead [] use {} 2: getResults(page = 1) { axios.get('example/?page=' + page) // <-- this .then(response => { this.laravelData = response.data; }); } 3:instead <tr v-for="post in posts" :key="post.id"> us <tr v-for="post in posts.data" :key="post.id">

uxweb commented 4 years ago

Just a quick note about this issue:

TLDR; I'm sure this issue is related on how json_encode() works and can be tweaked by passing it some options or taking care of the structure of data we sending the response

I've tested the following scenarios for passing data from a Laravel response to Vue component props:

Empty PHP Array:

An empty PHP Array will be converted to a JS empty Array.

// PHP
[]

// JS
[]

Associative PHP Array (with string index):

An associative PHP Array will be converted to a JS Object.

// PHP
[
    'index1' => 'Hello',
    'index2' => [ 'item1', 'item2' ]
]

// JS
{
    index1: 'Hello',
    index2: [ 'item1', 'item2' ]
}

This is the weird case, the prop is set to expect an Array, because that is what you are returning in the Laravel response, but get an object if the array has associative keys, and guess what? If the array is empty you get an array!

Multidimensional PHP Array (with numeric index):

A multidimensional PHP Array with numeric index will be converted to a JS Array

// PHP
[
    [ 'name' => 'foo', 'messages' => [ 'message1', 'message2' ] ],
    [ 'name' => 'bar', 'messages' => [ 'message1', 'message2' ] ],
]

// JS
[
    { name: 'foo', messages: [ 'message1', 'message2' ]},
    { name: 'bar', messages: [ 'message1', 'message2' ]},
]
bismarck4lves commented 4 years ago

You are declaring one type of list, and when you consume it from the API it goes over another type. To fix the problem, you can declare multiple forms of the list as: props: { data: [array, object] } in this way, Vuejs will read any list you can give!

samoudwfr commented 4 years ago

I had had the same warning, and now it's working perfectly. juste replace data: [ ] by data: { }

mhlanga-joseph commented 4 years ago

@BoraVivek Answer worked for me. Thanks

atefrihane commented 4 years ago

I'm passing a prop from the laravel blade to vue component how can I convert it into an object ? I'm not using axios.. props: ['data'], // always returning array

mukramin97 commented 4 years ago

[Vue warn]: Error in render: "TypeError: Cannot read property 'data' of undefined"

i have some warning too, i am passing 2 tables from laravel to axios, how to make these 2 data into an object? i got no problem with other pagination with only 1 table passed

Controller : public function index() {
$groupOne = Santri::with('Asrama')->paginate(5); $groupTwo = Asrama::all();

    return (compact('groupOne', 'groupTwo'));
}

Santri.vue: getResults(page = 1) { axios.get('api/santri?page=' + page) .then(response => { this.santris = response.data; }); }, loadSantri(){ axios.get("api/santri").then(({ data }) => (this.santris = data ));

        },

data(){ return { editMode: false, santris : { } }

ebaguma commented 4 years ago

I had the same issue but i was using a Resource to return my json then it gives you the output in this format instead of the norm.

screenshot 2018-06-15 12 30 49

From the Laravel Documentation

Data Wrapping And Pagination When returning paginated collections in a resource response, Laravel will wrap your resource data in a data key even if the withoutWrapping method has been called. This is because paginated responses always contain meta and links keys with information about the paginator's state:

https://laravel.com/docs/5.6/eloquent-resources#data-wrapping

I followed this solution to solve my problem by opting to use database views for all cases where i was using resources. Hope that helps someone having similar issues

bugohoss12 commented 3 years ago

I have solved the issue by wrapping the api response into: Object.assign({}, response);

romeldev commented 3 years ago

use the following structure in your vue data: dataItems: { data: [] }

get back your axios data

axios.get(yourApiUrl).then (res => {
    this.dataItems = res.data
})

in your paging component set: :data = "dataItems"

and to list your data in a table or html list use: v-for="(item, key) in dataItems.data"

NOTE: works for paginated laravel responses and paginated laravel resources too, good luck!

devfolorunso commented 3 years ago

Fixed!

So I was able to use Javascript Object.fromEntries() method to parse the data to an Object since the package is reading it as an array.

Laravel Controller

return response()->json(["applicants" => $applications], 200);

Vue file

data: () => ({
applicants:{}
})

//Method
getJobApplicants(){
   this.applicants = response.data.applicants.data;
}
//<div body></div>
 <pagination
          :data="Object.fromEntries(applicants)"
          @pagination-change-page="getJobApplicants"
      >
          <span slot="prev-nav">Previous </span>
          <span slot="next-nav">Next</span>
  </pagination>
github-actions[bot] commented 2 years ago

This issue is stale because it has been open for 90 days with no activity.

github-actions[bot] commented 2 years ago

This issue was closed because it has been inactive for 30 days since being marked as stale.