Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot read property 'length' of undefined"

I am getting the error below. The weird part is that I'm positive the data is there because in my vue add on I can see that it successfully grabs the information from the vuex store. My initial guess is that somehow the data is not yet grabbed from the store, at the point that it creates the template?

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

The data: 'spaces' is grabbed from the store.

    export default {
        name: "myspaces",
        data() {
            return {
                filterMaxLength: 3,
                selectedSpace: 0,
                selectedRoom: 0
            }
        },
        created() {
            // Default selected space (first in json)
            this.selectedSpace = this.spaces[0].id;

            // Default selected room (first in json)
            this.selectedRoom = this.spaces[0].rooms[0].id;
        },
        computed: {
            // Get 'spaces' from store.
            ...mapState([
                'spaces'
            ])
    }

Template:

<template>
      <div>  
         <v-flex v-if="spaces.length < filterMaxLength">
              <v-btn v-for="space in spaces">
                 <h4> {{space.name}} </h4>
              </v-btn>
         </v-flex>
     </div>
<template>

The store:

    import Vuex from 'vuex'

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        spaces:[
            {
                id:1,
                name:'House in Amsterdam',
                rooms:[
                    {
                        id:1,
                        name:'Bedroom Otto',
                    },
                    {
                        id:2,
                        name:'Bedroom Mischa'
                    }
                ]
            },
            {
                id:2,
                name:'Office in Amsterdam',
                rooms:[
                    {
                        id:1,
                        name:'Office 1',
                    },
                    {
                        id:2,
                        name:'Office 2'
                    }
                ]
            }
        ]} });

The vue chrome add on says this information is in the component:

enter image description here

like image 702
Otto Avatar asked Jul 03 '18 12:07

Otto


2 Answers

Always before check length, be sure your property its set then check length

<v-flex v-if="spaces && spaces.length < filterMaxLength">

Update ECMAScript 2020

You can use Optional chaining for this purpose too

<v-flex v-if="spaces?.length < filterMaxLength">
like image 140
Mohsen Avatar answered Sep 25 '22 14:09

Mohsen


You should use Object.keys(spaces).length, such as:

<template>
      <div>  
         <v-flex v-if="typeof spaces !== 'undefined' && typeof spaces === 'object' && Object.keys(spaces).length < filterMaxLength">
              <v-btn v-for="space in spaces">
                 <h4> {{space.name}} </h4>
              </v-btn>
         </v-flex>
     </div>
<template>
like image 39
Max Avatar answered Sep 24 '22 14:09

Max