0

I'm having a little trouble setting one of my this.values within my Vue application. I believe I'm either not understanding async axios calls correctly, or how async works within axios.

I have the following axios post method within my Vue application:

postRequest: async function(event) {
    event.preventDefault();
    let config = {
        headers: {
            "X-CSRFToken": this.csrfToken,
            "Content-Type": 'application/x-www-form-urlencoded',
        }
    }

    let formData = new FormData();

    formData.append('data', someData);

    await axios.post('{{ request_absolute_uri }}', formData, config).then(function(response) {
            this.responseMessage = response.data.message;
        }).catch(function(error) {
            console.log(error);
        });
    }
    console.log(this.responseMessage)
    return this.responseMessage;
}

My response.data.message is being passed back from my framework as True/true but it seems I'm not returning anything from the postRequest function? The post definitely hits the server as logging shows everything I want - then returns back message = true in json response context (using console.log(this.responseMessage) directly before returning the same value. However, nothing on the template changes or updates from this....

I'm assuming at this point that I have missed something incredibly simple!

GCien
  • 2,221
  • 6
  • 30
  • 56
  • Possible duplicate of [Axios can't set data](https://stackoverflow.com/questions/40996344/axios-cant-set-data) – yuriy636 Aug 27 '18 at 14:16

2 Answers2

2

Hmmm. I think I know what is going on here: because you're using a standard function, your this inside the .then() callback is not refering to the instantiated object...instead, this. is the calling the context of that function - with your original code, i.e., the Promise returned by the axios .post method.

Instead, I would advise using an arrow function instead so that the this is inherited from the outer scope, something along these lines:

await axios.post('{{ request_absolute_uri }}', formData, config).then( (response) => {
  this.responseMessage = response.data.message;
})

N.B. With arrow functions, the this. is always inherited from the outer scope, rather than depending on the calling context of the arrow function - so you can reference this.message or this.someFunction() with ease.

  • I'm sorry - I'm not sure exactly what is different about this answer from the code in my question...? – GCien Aug 27 '18 at 14:25
  • @GCien Hi, you're missing the arrow function `=>`, without using this your `this.` will always refer to the one returned by the `post` request and not the context provided by your `Vue` application... –  Aug 27 '18 at 14:26
  • Yep - I see that now, template is now updating on the new message! – GCien Aug 27 '18 at 14:39
1

I believe the "this" is out of scope inside .then statement. If you add the line:

var self = this;

at the top of your postRequest function, and then when assigning the response message use:

self.responseMessage = response.data.message;

I think that should work.

Jayem163
  • 110
  • 5