0

This may be a simple question but I feel like I need some clarification... I have vuejs running on a single page of my site. The vm app is running in the footer script of the page (I am not using an app.js file or templates/components etc.)

Inside one of my vue methods, this works fine:

newContainer(){
   this.attribute = 'value'; //this works!
}

I am also using axios and inside its functions I have to do this instead:

axios.post('my/route', {
        attribute: this.attribute //this works
    }).then(function (response) {
        vm.attribute = 'value'; //this works
        this.attribute = 'value'; //this does not work
    });

I realise this is probably due to it being in a function that this.attribute does not work while vm.attribute does work. However... why is this and is there a better way to do it?

Adam Lambert
  • 1,311
  • 3
  • 24
  • 45

3 Answers3

0

You can see the following after code

    export default{
        data(){
            return{
                title:"Form Register",
                formdata:{},
                message:"",
                success:0,
            }
        },
        methods:{
           register(){
                this.axios.post("http://localhost:8888/form-register",this.formdata).then((response) => {
                       console.log(response);
                       if(response.data.success>0){
                           this.message="You register success";
                           this.success=response.data.success;
                       }
                       else{
                           this.message="Register to failed";
                           this.success=response.data.success;
                       }
                  });
                    
            },
 
        }
    }
skipperhoa
  • 431
  • 3
  • 7
0

If you use arrow functions like () => {...} it binds current context. And this will point to right context. So if you use it instead of function() {...} where context is not binded it will work. Like

.then(response => {this.attribute = 'value'}

Makarov Sergey
  • 932
  • 7
  • 21
0

This is a really common stumbling block for developers. The reason is that inside an axios function your code out of scope of the object containing the axios method call. This can more easily be see if you rewrite this block of code to be like the one below it:

 var vm = {
      function doWork(){
        axios.post('my/route', {
              attribute: this.attribute //this works
        }).then(function (response) {
              vm.attribute = 'value'; //this works
              this.attribute = 'value'; //this does not work
         });
      }
 }

is functionally equivalent to:

 var vm = {
      function doWork(){
          axios.post('my/route', {
                attribute: this.attribute //this works
           }).then(followOnWork(response));
      }
 }

 function followOnWork(response){
      vm.attribute = 'value'; //this works
      this.attribute = 'value'; //this does not work
 }

As you can see in this refactored code, followOnWork is running totally independently of the vm object. So any use of a this variable in followOnWork isn't going to relate to the vm object. Where as vm is the actual name of the object and once the object is created it can be accessed from anywhere via the vm variable.

You can get around this "out of scope" problem by using an arrow function (as mentioned by @MakarovSergey) if ES6 is an option for you.

RonC
  • 31,330
  • 19
  • 94
  • 139