Reputation: 540
I am trying to make login with google in vue by following google document and everything worked but i cant access method inside attachClickHandler.
new Vue({
el: '#loginModal',
data: { ...
},
methods: {
gInit: function() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: 'MY-Client-id.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
//scope: 'additional_scope'
});
auth2.attachClickHandler(document.getElementById('googleBtn'), {},
function(googleUser) {
const profile = googleUser.getBasicProfile();
const gplusObj = {
name: profile.getName(),
email: profile.getEmail(),
provider: 'google',
image: profile.getImageUrl(),
provider_user_id: profile.getId()
};
this.socialLogin(gplusObj);
},
function(error) {
alert(JSON.stringify(error, undefined, 2));
});
});
},
socialLogin: function(data) {
axios.post(`${this.api}/api/sociallogin`, data)
.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
});
},
},
mounted: function() {
this.gInit();
}
})
Here calling a function socialLogin()
inside attachClickHandler()
is giving error this.socialLogin is not a function
is not defined. Why this is not working?
Upvotes: 1
Views: 238
Reputation: 5329
Because you didn't save this
,try :
new Vue({
el: '#loginModal',
data: { ...
},
methods: {
gInit: function() {
let self = this // new added
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: 'MY-Client-id.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
//scope: 'additional_scope'
});
auth2.attachClickHandler(document.getElementById('googleBtn'), {},
function(googleUser) {
const profile = googleUser.getBasicProfile();
const gplusObj = {
name: profile.getName(),
email: profile.getEmail(),
provider: 'google',
image: profile.getImageUrl(),
provider_user_id: profile.getId()
};
console.log(e);
self.socialLogin(gplusObj); //updated
},
function(error) {
alert(JSON.stringify(error, undefined, 2));
});
});
},
socialLogin: function(data) {
axios.post(`${this.api}/api/sociallogin`, data)
.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
});
},
},
mounted: function() {
this.gInit();
}
})
this
wouldn't be passed automatically and you should already know this before learning vue.
Also,you can use arrow function
to avoid this
being changed:
new Vue({
el: '#loginModal',
data: { ...
},
methods: {
gInit: function() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: 'MY-Client-id.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
//scope: 'additional_scope'
});
auth2.attachClickHandler(document.getElementById('googleBtn'), {},
(googleUser) => { //updated
const profile = googleUser.getBasicProfile();
const gplusObj = {
name: profile.getName(),
email: profile.getEmail(),
provider: 'google',
image: profile.getImageUrl(),
provider_user_id: profile.getId()
};
console.log(e);
this.socialLogin(gplusObj);
},
function(error) {
alert(JSON.stringify(error, undefined, 2));
});
});
},
socialLogin: function(data) {
axios.post(`${this.api}/api/sociallogin`, data)
.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
});
},
},
mounted: function() {
this.gInit();
}
})
Upvotes: 0
Reputation: 8716
It's because the this.socialLogin
call is located in a callback function. This function creates a new context so this
changes and won't be your component anymore.
Use arrow functions. They won't change this
.
Edit: Change your code like this:
gInit() {
gapi.load('auth2', () => {
...
auth2.attachClickHandler(document.getElementById('googleBtn'), {}, (googleUser) => {
...
this.socialLogin(gplusObj);
}, (error) => {
alert(JSON.stringify(error, undefined, 2));
});
});
},
More on that topic: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions, see "No separate this".
Upvotes: 2