[Vuejs]-Vue reloads/sends XHR request every time key is pressed in text field

0👍

TL;DR

Replace

set: setTimeout(function (val) {
  return this.updateAttachment([this.attachment.id, { ignoreAttachment: !val }]);
}, 3000)

with

set: function (val) {
  let self = this;
  setTimeout(function(){
    self.updateAttachment([self.attachment.id, { ignoreAttachment: !val }]); 
  }, 3000)
}

[Vue warn]: Error in render: "TypeError: Setter must be a function: 3" means set: property of attachmentAccepted must be a function. Something like set: function(){}.

Uncaught TypeError: Cannot read properties of undefined (reading 'id') means the program cannot read .id of an object. In this case, this.attachment object is undefined, so you cannot do this.attachment.id.

this.attachment is undefined because,

set: function /* <<< SCOPE A function declaration */ (val) {
  
  /* "this" right here is a thing that referring to SCOPE A, and... */
  console.log(this)

  setTimeout(function() /* <<< SCOPE B function declaration */ {
    
    /* ... "this" right here is another thing that referring to SCOPE B. 
      And because of the same name, SCOPE A's "this" cannot be used anymore. */
    console.log(this)

    return this.updateAttachment([this.attachment.id, { strValue: val }])
  }, 3000)
}

So just pass SCOPE A’s this to SCOPE B. One of the solution is using var self = this; inside SCOPE A. Now you can use SCOPE A’s this inside SCOPE B with the self variable.

set: function /* SCOPE A */ (val) {
  let self = this;
  setTimeout(function /* SCOPE B */ (){
    self.updateAttachment([self.attachment.id, { ignoreAttachment: !val }]); 
  }, 3000)
}

// OR

set: function /* SCOPE A */ (val) {
  let SCOPE_A_THIS = this;
  setTimeout(function /* SCOPE B */ (){
    SCOPE_A_THIS.updateAttachment([SCOPE_A_THIS.attachment.id, { ignoreAttachment: !val }]); 
  }, 3000)
}


Bonus: Understanding "this" in javascript with arrow functions

Leave a comment