2

I am trying to do the following from my HTML:

var vm = new Vue({
      el: '#loginContent',
      data: {
        main_message: 'Login',
        isLoggedIn: false,
        loginError: '',
        loginButton:'Login'
      },
      methods: {
        onLogin: function() {
          //this.$set(loginSubmit, 'Logging In...');
          var data = {
            email: $('#email').val(),
            password: $('#password').val(),
          };
          $.ajax({
            url: '/api/login',
            data: data,
            method: 'POST'
          }).then(function (response) {
            if(response.error) {
              console.err("There was an error " + response.error);
              this.loginError = 'Error';
            } else {
              //$('#loginBlock').attr("hidden",true);
              console.log(response.user);
              if(response.user) {
                this.isLoggedIn = true;
              } else {
                this.loginError = 'User not found';
              }
            }
          }).catch(function (err) {
            console.error(err);
          });
        }
      }
    });

Basically user presses the login button, onLogin method is called that sends a post to my API. The post is working fine and I do get the response back in the .then() promise.

But, trying to do things like this.isLoggedIn = true; does not update my DOM with what I am expecting the HTML to do when the user logs in.

Could be that I am in some sort of background thread (sorry, mobile developer here) when I get the response in the promise and it can't find the "vm" instance?

Thanks

Felipe Caldas
  • 2,492
  • 3
  • 36
  • 55

3 Answers3

6

It is probably happening because your this is not pointing to correct scope, scope of this changes inside an $.ajax call, so you just have to do something like following:

  methods: {
    onLogin: function() {
      //this.$set(loginSubmit, 'Logging In...');
      var data = {
        email: $('#email').val(),
        password: $('#password').val(),
      };
      var that = this
      $.ajax({
        url: '/api/login',
        data: data,
        method: 'POST'
      }).then(function (response) {
        if(response.error) {
          console.err("There was an error " + response.error);
          that.loginError = 'Error';
        } else {
          //$('#loginBlock').attr("hidden",true);
          console.log(response.user);
          if(response.user) {
            that.isLoggedIn = true;
          } else {
            that.loginError = 'User not found';
          }
        }
      }).catch(function (err) {
        console.error(err);
      });
    }
  }
Saurabh
  • 71,488
  • 40
  • 181
  • 244
  • Thank you so much for this! The `var that = this` line was really key for me! I couldn't figure out why everything kept falling out of scope! – Taylor Liss Jun 20 '20 at 06:57
0

I would propose another method use ES6 Arrow Functions like '=>'. It is simple and do not need extra variable.Like following:

      $.ajax({
        url: '/api/login',
        data: data,
        method: 'POST'
      }).then((response) => {
        if(response.error) {
          console.err("There was an error " + response.error);
          this.loginError = 'Error';
        } else {
          //$('#loginBlock').attr("hidden",true);
          console.log(response.user);
          if(response.user) {
            this.isLoggedIn = true;
          } else {
            this.loginError = 'User not found';
          }
        }
      }).catch(function (err) {
        console.error(err);
      });
gy134340
  • 566
  • 5
  • 19
0

You might want to take a look at axios. I used $.ajax and got it working, but found axios and prefer axios over the ajax library.

drsnark
  • 2,813
  • 2
  • 15
  • 19