0

Im exploring vue and new javascript tools - things are a bit convoluted for me, in the sense I struggle to debug and understand what is going on.

I am trying to fetch data via a simple API, using axios as suggested here: https://v2.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html#Real-World-Example-Working-with-the-Data

turns out, if I use "normal" javascript, data will not be set.

It must have something to do with interpreting "this" element.

Instead, if I use arrows functions, data are set.

data () {
  return {
     query : {
        info : null
     }          
}

methods : {
    
   test : function(query) {
             params = {
               origin : '*',
               action : 'query',   
               prop : 'pageimages',
               pithumbsize : 400,
               pilimit : 'max',
               list : 'search',
               srsearch : query,
               utf8 : true,
               format : 'json'

              }

              axios.get('https://en.wikipedia.org/w/api.php', {
                params : params 
              })
              .then(function (response) {
                
                // won't work :     this.query.info // undefined        

                this.query.info = response.data.query.search
               
              })
              .then( 
               // this.query.info is set
               response => {
                        this.query.info = response.data.query.search
                      }
              )
  

   }

} 

Can you explain why?

I helped myself with answer in : What does "this" refer to in arrow functions in ES6? - "this refers to the enclosing context" :

  • what does this refer to in the pattern then(function(response){ this.[...]) and in the patter then( response => this.[...]) ?

  • how could I use syntax without arrows functions, and use this referring to the data() model of vue ?

Would you mind to also suggest working practices to keep code clean and simple?

I came from using native javascript and jquery, and despite a bit more verbose, I could understand well what was going on and easily debug.

Instead with these new tools, despite powerful, I am a bit lost for it seems there is an overload of other tools to use to get things done.

While learning I still would prefer to code a bit more verbosely and use web console to debug, instead of nodes plugin and syntax that must be compiled by frameworks.

__

Edited

Upon comments, I tried:

            .then(function(response){

            // won't work : here thisArg should be the vue app,
            // so self.query.info should bind to 
            // [App data()].query.info 
            // still, query.info is undefined
            // though response was successfully fetched

            var self = this

            self.query.info = response.data.query.search
          })

Edited 2 (Answer)

I found this answer helpful: https://stackoverflow.com/a/29881419/305883

so I realised above patter was wrong, for writing var self =this within the then() means I am still referenceing the this of the promise object, which is undefined.

so with "normal" functions, I should write something like:

var self = this; // now self is referenced to the external object, the Vue app

              fetchResponseFromApi(query)
              .then(function(response){
                
                self.query.info = response.data.query.search
              }) 

This answer address my question (no pun for "this" answer, hohoho :).

In other answers I read comments not to pass around the thisArg, like into encapsulated functions:

comments about clarifying about good coding patterns will be of good for others to.

tony19
  • 125,647
  • 18
  • 229
  • 307
user305883
  • 1,635
  • 2
  • 24
  • 48
  • Always use `var self = this` to avoid ambiguous `this` statements – Simon Hyll Jan 13 '19 at 14:23
  • 1
    @Bergi it's unfortunate that it's pretty hard to find some authoritative source like MDN that *explicitly* describes how `this` is bound when a `.then()` callback is invoked from the queue. – Pointy Jan 13 '19 at 14:34
  • 1
    @Pointy `then` calls its callbacks as normal functions, i.e. passing `undefined` for the `thisArg`. (I don't see how this is relevant to this question, though) – Bergi Jan 13 '19 at 14:37
  • @Bergi I agree it isn't important for this but it's the sort of pointless detail that this site has made me want to know. I guess a 10 second experiment in the console would answer the question :) – Pointy Jan 13 '19 at 15:04
  • I tried what was suggested by @Simon Hyll, but still response is not set – user305883 Jan 13 '19 at 17:17
  • @Bergi I did not understand the comments between you and Pointy - would you like elaborate, so to clarify what has been already answered for the question (duplicate) and what is instead irrelevant ? In fact, I don't understand why data is not set, I suspected it is because the use of `thisArg` and post question for a clearer understanding of both (data is unset with "regular" functions, use of this ) – user305883 Jan 13 '19 at 17:21
  • 1
    @user305883 The comment by Pointy and my response have nothing to do with your question, sorry for the distraction – Bergi Jan 13 '19 at 17:48
  • 2
    @user305883 The answers to the canonical questions should explain why `function` doesn't work, why `=>` works instead, and what the general problem with accessing `this` in callbacks is. – Bergi Jan 13 '19 at 17:50
  • 1
    Sorry OP - Bergi is right; because `this` will be `undefined` in an old-school `function` function, it's not useful then. With an `=>` function, it will *probably* be useful because invoking an `=>` function will use the same `this` as in the outer context where the `=>` function is defined. That is, whatever `this` is *outside* the `=>` function definition, that's what it'll be inside. – Pointy Jan 13 '19 at 22:46

0 Answers0