2

I have the following but I get error Cannot read property 'push' of undefined:

 var vm = new Vue({
        el: '#root',
        data: {
            posts: [],
            newPost: {}
        },
        createPost: function() {
               axios.post("api/posts/create", this.newPost).then(function (response) {
                    this.posts.push(response.data);
                })
        }
 });

In my network tab in chrome dev tools I can see response.data is clearly an object:

{
  "id": 131,
  "postContent": "<p>test</p>\n",
}

So why I'm i getting this error?

adam78
  • 9,668
  • 24
  • 96
  • 207
  • where did you initialized `this.posts`? – gurvinder372 Nov 29 '17 at 10:01
  • 1
    Your posts array variable is inside data. So I think you should use this.data.posts.push() instead of this.posts.push() – Lalit Nov 29 '17 at 10:02
  • 2
    Just answered it here....have a look....https://stackoverflow.com/q/47549346/7814783 – Vamsi Krishna Nov 29 '17 at 10:02
  • @VamsiKrishna you are right. I added the `=>` syntax and now It works. Thanks. – adam78 Nov 29 '17 at 10:25
  • @VamsiKrishna Why does the arrow function not work in IE11? I'm using webpack and bundling the javascript using the `"babel-preset-es2015": "^6.24.1",` and ` "es6-promise": "^4.1.1",`. – adam78 Dec 10 '17 at 21:12

2 Answers2

7

That's because this context is assigned incorrectly which means that this does not point on the Vue component. To solve this problem, you can use => syntax which simply means a sophisticated way of this self = this outside of the target callback.

createPost: function() {
  axios.post("api/posts/create", this.newPost).then((response) => {
     this.posts.push(response.data);
  })
}
IzumiSy
  • 1,508
  • 9
  • 17
2

As IzumiSy said, this very common problem when using axios or even setTimeout function. You can use es6 arrow synax, create temporary local variable with vm or bind it to the function.

ES6

createPost: function() {
 axios.post("api/posts/create", this.newPost).then((response) => {
    this.posts.push(response.data);
 })
}

Temporary variable

createPost: function() {
let vm = this;
  axios.post("api/posts/create", this.newPost).then(function (response) {
     vm.posts.push(response.data);
  })
}

Binding

createPost: function() {
  axios.post("api/posts/create", this.newPost).then(function (response) {
     this.posts.push(response.data);
  }.bind(this))
}
El Danielo
  • 780
  • 1
  • 8
  • 18