1

If I have data like so in Vue JS 2:

data : {
  newBus: {
    name: '',
    hours: {
      sunday: '',
    }
  }
}

And I set it here:

<input v-model="newBus.hours.sunday" type="text" placeholder="Sunday">

Adding a business this way works, the issue comes when I try to update them. The user clicks on the item from a list and then the saved data fills in the form like so:

<div v-for="bus in businesses" v-on:click="editBus(bus)" class="list-group-item bus-list-item">{{bus.name}}</div>

Method:

editBus: function (bus) { 
    /*Set post values to form*/
    this.newBus = bus
  },

But I get the error:

vue.js:1453 TypeError: Cannot read property 'sunday' of undefined

This happens immediately when the item to be updated is clicked. Any ideas?

EDIT: It appears to be related to the hours property not being avaliable on bus. If I console.log(bus) it doesn't show. But I need to add this data to this business. Is there a way to have it ignore data it doesn't yet have? What I don't understand is that if it was not nested...aka sunday: '' instead of hours: { sunday: ''} it works fine.

EDIT: Here is the CodePen recreation.

7
  • v-on:click="editBus(bus)" is that a typo? I think you mean editBus(business) or v-for="bus in businesses" Commented Apr 21, 2017 at 23:25
  • Yes, v-for bus in businesses... my mistake. Commented Apr 21, 2017 at 23:27
  • Do you still have the problem? If so, you should provide more code samples to help understand what's going on. Commented Apr 21, 2017 at 23:34
  • Yup, I just typed it wrong in question. I'll update with more content. Commented Apr 21, 2017 at 23:35
  • @Robodude I was able to hack together the same error in CodePen Error is in the console. Adding CodePen to original question. Commented Apr 22, 2017 at 0:12

1 Answer 1

2

The problem here isn't really a Vue problem it's a Javascript problem. You cannot access a property of undefined.

Using the example data structure from your pen.

newComment: {
    name: '',
    comment: '',
    votes:  0,
    time:  timeStamp(),
    subcomment: {
        name: ''
    }
}

In this case, you've set everything up with a defined value, so everything is going to be resolved. The problem comes when you are clicking your edit button, the object received looks like this:

{
    name: "some name",
    comment: "some comment",
    time: "4/5/2017",
    votes: 145,
    .key: "-Kh0PVK9_2p1oYmzWEjJ"
}

Note here that there is no subcomment property. That means that the result of this code

newComment.subcomment

is undefined. But in your template, you go on to reference

newComment.subcomment.name

So you are essentially trying to get the name property of undefined. There is no name property of undefined. That is why you get your error.

One way you can protect yourself from this error is to check to make sure the subcomment property exists before rendering the element using v-if (forgive me if this is the wrong pug syntax-I'm not that familiar with it)

input#name(type="text")(placeholder="Name")(v-model="newComment.subcomment.name")(v-if="newComment.subcomment")

That will prevent the error.

Alternatively in your editComment method, you could check to see if subcomment exists, and if it doesn't, add it.

if (!comment.subcomment)
    comment.subcomment = {name: ''}
this.newComment = comment

Finally, you ask, why does it work if it's not nested data. The key difference is this: if newComment exists, say like this

newComment: {}

and you try to get newComment.name then the returned value of name is undefined. If you have a template that has something like v-model="newComment.name" nothing is going to crash, it's just going to set the value of the input element to undefined, and when you change it, newComment.name will get the updated value.

In other words, when you try to reference newComment.subcomment.name you are trying to reference the name property of something that doesn't exist whereas when you try to reference newComment.name, the object exists, and it doesn't have the name property.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the awesome explanation! And you even provided me a way to add the data which is what I would need in my case to work with existing data. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.