6

I have this vue.js component that uses axios to retrive a json array of joke objects :

<template>
  <div id="show-jokes-all">
        <h2>Showing all jokes</h2>
        <div v-for="joke in jokes">
                <h2>{{joke.title}}</h2>
                <article>{{joke.body}}</article>
            <hr>
        </div>  

  </div>
</template>

<script>
import axios from 'axios';

    export default {
        name: 'showJokes',

      data () {
        return {
            jokes:[]

        }
      },

      methods: {

      },

      created() {
        axios.get('http://127.0.0.1:8090/api/jokes).then(function(data){    
       //console.log(data); works fine
        this.jokes = data.body;
        });
    }
}
</script>

When I log the result in console it's fine but when I try to put it in jokes array I get

Uncaught (in promise) TypeError: Cannot set property 'jokes' of undefined

This may be a trivial error but as a newbie to vue.js I'm stock on this so appreciate your hints.

Karlom
  • 13,323
  • 27
  • 72
  • 116
  • 1
    Possible duplicate of [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Bert Aug 17 '17 at 19:21
  • Essentially, `.then(data => this.jokes = data.body)` instead of the function you have. Or use a closure or bind as described in the above link. – Bert Aug 17 '17 at 19:27
  • @Bert, I followed this tutorial, and that's how it used data: https://youtu.be/aoWqFLGCK60?list=PL4cUxeGkcC9gQcYgjhBoeQH7wiAyZNrYa – Karlom Aug 17 '17 at 19:31
  • 1
    That tutorial uses VueResource (`this.$http`) instead of `axios`. `this` is treated differently inside the callbacks of those two libraries. – Bert Aug 17 '17 at 19:34
  • I see! but using `.then(data => this.jokes = data.body)` while removes the error, but no data is being displayed. Any idea why? – Karlom Aug 17 '17 at 19:38
  • What comes back in `data.body`? – Bert Aug 17 '17 at 19:40
  • an array of jokes in json format. – Karlom Aug 17 '17 at 19:41
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/152195/discussion-between-bert-and-karlom). – Bert Aug 17 '17 at 19:41
  • 3
    One clarification for any future readers; I said `.then(data => this.jokes = data.body)` above, but it should have been `.then(response => this.jokes = response.data)`. – Bert Aug 17 '17 at 19:50

2 Answers2

18

You are out of this context. You should store this context on a variable.

 created() {
    let self = this
    axios.get('http://127.0.0.1:8090/api/jokes').then(function(data){    
   //console.log(data); works fine
    self.jokes = data.body;
    });
}

There are many ways in How to access the correct this inside a callback? . You can refer here for many ways.

thanks to Bert on comments

Community
  • 1
  • 1
Cholowao
  • 947
  • 12
  • 18
  • 3
    It's 2018, there's no need to do `let self = this` anymore :) Use an [arrow function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) instead! `axios.get('http://127.0.0.1:8090/api/jokes').then(data => { ... });` – lucascaro Oct 27 '18 at 03:20
3

yes,you can use ES6 .

<template>
    <div id="show-jokes-all">
        <h2>Showing all jokes</h2>
        <div v-for="joke in jokes">
            <h2>{{joke.title}}</h2>
            <article>{{joke.body}}</article>
            <hr>
        </div>  
    </div>
</template>

<script>
import axios from 'axios';
  export default {
    name: 'showJokes',
    data () {
      return {
        jokes:[]
      }
    },
    methods: {
    },
    created() {
      axios.get('http://127.0.0.1:8090/api/jokes').then((data) => {    
      // console.log(data); // works fine
      this.jokes = data.body;
    });
  }
}
</script>
Prashant Barve
  • 4,105
  • 2
  • 33
  • 42
Jian Lan
  • 31
  • 3