MicroDroid / vue-materialize-datatable

A fancy Materialize CSS datatable VueJS component.
https://overcoder.dev/vue-materialize-datatable
MIT License
179 stars 67 forks source link

Cannot read property 'sort' of undefined #24

Closed clnt closed 7 years ago

clnt commented 7 years ago

Hi,

I've spent a lot of time trying to get this working in a Laravel 5.4 application but not having much luck. I've had a fair few errors which I have managed to sort out but this one I cannot seem to get rid of - and I am unable to get anything to display on my page. I am very new to Vue so forgive me if this issue is an error on my part.

The error I am getting is: app.js:75598 [Vue warn]: Error in render function: "TypeError: Cannot read property 'sort' of undefined"

app.js:75685 TypeError: Cannot read property 'sort' of undefined
    at VueComponent.processedRows (app.js:43334)
    at Watcher.get (app.js:78000)
    at Watcher.evaluate (app.js:78107)
    at VueComponent.computedGetter [as processedRows] (app.js:78384)
    at VueComponent.paginated (app.js:43376)
    at Watcher.get (app.js:78000)
    at Watcher.evaluate (app.js:78107)
    at VueComponent.computedGetter [as paginated] (app.js:78384)
    at Object.get (app.js:76796)
    at Proxy.render (app.js:74752)

I had the same error with 'window' which I resolved by adding it to the instance, but attempting to do the same for sort does not work (requiring local copy to fix perPage default error):

Vue.component('data-table', require('./components/DataTable.vue'));

const app = new Vue({
    el: '#app',
    data: {
        window: {
            data: []
        },
        sort: ''
    }
});

Component in blade template: <data-table :columns="window.data.columns" :rows="window.data.rows" />

If I do console.log(window.data) I can see the data I am expecting to see.

I think I have added all the relevant code but if I've missed something let me know.

Vue Version: 2.4.2

Thanks in advance!

thepill commented 7 years ago

Could you please post a snippet of your window.data values.

MicroDroid commented 7 years ago

Your are probably loading window.data.columns and/or window.data.rows via AJAX. This is where the problem is. Vue tries to render the component before your data loads, and thus, those two variables are essentially undefined, which causes the error.

Try setting v-if="window.data.rows" for instance to your component, it should work.

clnt commented 7 years ago

Thanks for the replies.

Here is the contents of my window.data: http://i.imgur.com/s8duFsb.png

I'm confident that my data is loaded, but as you say it could not be loaded at the correct time. I tried adding it in the header of the website and in the footer but it hasn't made a difference. I am using this package to pass PHP variables to the view as Js variables: Laracasts/PHP-Vars-To-Js-Transformer

I tried adding that v-if="window.data.rows", it removes the error from console but still nothing at all is displayed on my page which I believe is because the if statement stops it from getting loaded?

MicroDroid commented 7 years ago

First of all, orderable and searchable in your columns are booleans, and you're using strings there. It's true, and not "true"

Next to that, the v-if checks if window.data.rows is a thing. If the whole datatable is disappearing, it means that window.data.rows is falsy (i.e. is undefined or null)

Now for the last thing, window is a global object, it's a reserved name, you cannot use it as a data property name in Vue, it will conflict. See this. This is probably the issue

Basically, use some other name than window in your data.

Also try hardcoding your rows and columns straight in your JS code, and check with VueJS inspection tools extension to see what your data looks like in the component, it will give you a better idea on that.

clnt commented 7 years ago

Thanks for the brilliant response, really well explained. That rookie error with the booleans is a little embarrasing!

Using window global object was indeed the issue, once I changed this namespace to a custom one then re-ran webpack I had a table getting displayed, but with no data.

To fix the data issue I had to edit my instance so that data{} was properly defined:

const app = new Vue({
    el: '#app',
    data: {
        cms: {
            data: {
                rows: cms.data.rows,
                columns: cms.data.columns
            }
        }
    }
});
MicroDroid commented 7 years ago

Glad that it worked!

clnt commented 7 years ago

I hope you don't mind me posting this here, I have included a link back to this repo in the README.

I created a Laravel package to assist in creating the JSON data and binding it to the view: Laralabs/datatablejson

Cheers!

MicroDroid commented 7 years ago

@CLINT0N Not at all! In fact, thanks for the link back, it helps make this library better :)