47

Here's my data:

data: function(){
    return {
        contas: [{id: 3,
            nome: "Conta de telefone",
            pago: false,
            valor: 55.99,
            vencimento: "22/08/2016"}] //debug test value
    };
},

And here's my get request:

beforeMount() {
    axios.get('http://127.0.0.1/api/bills')
        .then(function (response) {
            console.log("before: " + this.contas);
            this.contas = response.data;
            console.log("after: " + this.contas);
        });
},

The problem is I can't access this.contas from within axios.get(). I've tried Vue.set(this, 'contas', response.data); and window.listaPagarComponent.contas = response.data; without success.

My console shows:

before: undefined
after: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object]

But Vue Devtools shows only:

contas: Array[1]
  0: Object
    id: 3
    nome: "Conta de telefone"
    pago: false
    valor: 55.99
    vencimento: "22/08/2016"

Here's my full code.

Guilherme Pressutto
  • 785
  • 2
  • 6
  • 18
  • 1
    Try to use `created()` hook instead `beforeMount()`.And if you already have defined some data in contas array, then I think into promise you should do array.push. – Belmin Bedak Dec 06 '16 at 13:51
  • 1
    Okay, could you please create new array in data model, and set response data to it ? And then checkout, does items are stored in array.Unfortunately I don't work with Axios, I'd rather go with Vue resource. – Belmin Bedak Dec 06 '16 at 14:00
  • 1
    @Belmin Nothing changes... And it's only a debug test value. I don't want this value. The problem is I can't use `this.contas` to refer to component's data `contas`. No function works. I think axios is a "object", so when I use `this`, it refers to axios. – Guilherme Pressutto Dec 06 '16 at 14:01
  • Yeah, already tried with a string. String `var test = ''`. Then nothing changes. I think `this` is refering to axios somehow. Vue resource doesn't work with Vue.js 2 – Guilherme Pressutto Dec 06 '16 at 14:02
  • 1
    Not sure, sorry as I said I never worked with Axios.Vue Resource works perfectly with Vue 2.I used it in many projects.Check this https://jsbin.com/jeqekexiqa/edit?html,js,console,output – Belmin Bedak Dec 06 '16 at 14:04
  • Ok, now I've replaced `beforeMount () {}` with `mounted: function () {}` and the console shows the first log as `[__ob__: Observer]`. Now I can push one of my objects `this.contas.push(response.data[0]);`. But I can't set my object to be **equal** my response.data with `this.contas = response.data;`. Do I need to post another question? – Guilherme Pressutto Dec 06 '16 at 15:27
  • @Belmin has the trick, if you write `console.log(this)` inside of the promise, the result is `window`, you need store the `this` reference in a auxiliar var and use the reference var to set the values. .... `var that = this`; `that.contas = response.data;` – chalo Mar 02 '17 at 18:15

2 Answers2

136

In option functions like data and created, vue binds this to the view-model instance for us, so we can use this.contas, but in the function inside then, this is not bound.

So you need to preserve the view-model like (created means the component's data structure is assembled, which is enough here, mounted will delay the operation more):

created() {
    var self = this;
    axios.get('http://127.0.0.1/api/bills')
        .then(function (response) {
                self.contas = response.data;
                });
}

Or you can use arrow function in ES6 standard if you only aim to support modern browsers(or using a transpiler like babel), like:

created() {
    axios.get('http://127.0.0.1/api/bills')
        .then((response) => {
                this.contas = response.data;
                });
}

this inside arrow functions are bound according to lexical context, which means the this in the above snippet is the same as the one in created, which is what we want.

JJPandari
  • 3,454
  • 1
  • 17
  • 24
24

To be able to access this.contas inside axios.get() do you need binding "this" to keep variable usage scoped:

mounted() {
    axios.get('http://127.0.0.1/api/bills')
     .then(function (response) {
        console.log("before: " + this.contas);
        this.contas = response.data;
        console.log("after: " + this.contas);
     }.bind(this));
}
Fred Sousa
  • 1,121
  • 13
  • 17