I am having a problem in calling/accessing a in-class function AND a service function from a function which calls a external js lib/code… But I am able to access class variable using the ‘this’ keyword in angular 2 component
FB <- is the facebook sdk function to get the facebook communicated values of the logged user
Here’s the code
statusChangeCallback(resp: any) {
if (resp.status === 'connected') {
this.access_token = resp.authResponse.accessToken; // this variable gets the correct value in it
FB.api('/me?fields=name,email', function (resp: any) {
this.email = resp.email; // this variable gets the correct value in it
if (this.email !== '' && this.access_token !== '') {
console.log('under if statement');
var auth = {};
auth['accesstoken'] = this.access_token;
auth['emailid'] = this.email;
console.log(auth);
this.send_registeration(auth); // this function throws ERROR
// this.http.fb_register(this.email, this.access_token);
}
}, { scope: 'email,public_profile' });
} else if (resp.status === 'not_authorized') {
} else {
}
}
Here’s Error Description shown in chrome
zone.js:260 Uncaught TypeError: this.send_registeration is not a function
here’s the full component code to checkout
import {Component, OnInit, Output} from '@angular/core';
import {ROUTER_DIRECTIVES, Router} from '@angular/router-deprecated';
import { HttpService } from '../../Service/http.service';
declare const FB: any;
@Component({
selector: 'facebook-login',
template: `
<div>
<button class="btn btn-facebook" (click)="onFacebookLoginClick()">
<i class="fa fa-facebook"></i>Sign in with Facebook
</button>
</div>
`,
providers: [HttpService],
directives: [ROUTER_DIRECTIVES]
})
export class FacebookLoginComponent implements OnInit {
access_token: string = '';
email: string = '';
constructor(private http: HttpService) {
FB.init({
appId: '****APP ID **********',
cookie: false, // enable cookies to allow the server to access
// the session
xfbml: true, // parse social plugins on this page
version: 'v2.5' // use graph api version 2.5
});
}
onFacebookLoginClick() {
FB.login(this.statusChangeCallback);
}
statusChangeCallback(resp: any) {
if (resp.status === 'connected') {
this.access_token = resp.authResponse.accessToken;
// var self = this;
FB.api('/me?fields=name,email', (resp: any) => {
this.email = resp.email;
if (this.email !== '' && this.access_token !== '') {
var auth = {};
auth['accesstoken'] = this.access_token;
auth['emailid'] = this.email;
console.log(auth);
this.send_registeration(auth); //throws Error
// this.http.fb_register(this.email, this.access_token); // this Service function also throws Error just the same way
}
}, { scope: 'email,public_profile' });
} else if (resp.status === 'not_authorized') {
} else {
}
}
send_registeration(auth: any) {
this.http.postRequest(auth, 'fbinvestors')
.subscribe(
data => {
console.log('Server respond is ');
console.log(data);
}
);
}
}
Here’s the updated function … Facebook sdk callback doesnt seems to be earlier as stated earlier … but the problem still exits
statusChangeCallback(resp: any) {
if (resp.status === 'connected') {
this.access_token = resp.authResponse.accessToken;
FB.api('/me?fields=name,email,first_name,last_name,age_range,gender,picture', (resp: any) => {
this.email = resp.email;
}, { scope: 'email,public_profile' });
}
var self = this;
setTimeout(function () {
if (this.email !== '' && this.access_token !== '') {
console.log('under if statement');
var auth = {};
auth['accesstoken'] = this.access_token;
auth['emailid'] = this.email;
console.log(auth); // show variable output as required
// no problem till here
}
self.http.postRequest(auth, 'fbinvestors') // this line throws error as shown below
.subscribe(
data => {
console.log('Server respond is ');
console.log(data);
}
);
}, 7000);
}
the new Error is similiar to the old one … but now its not calling the service method – Error shown is
TypeError: Cannot read property 'postRequest' of undefined
UPDATE: on line self.http.postRequest(auth, ‘fbinvestors’) … self is undefined basically … so now I solve this problem if
1. I can pass class scope (‘this’) as a parameter to this callback function
2. If I can provide a array of callback functions instead of just one callback function
Please help – I am trying this to get solved from 2 days now….
3
Answers
I changed the original function
to this
Waiting for the response from fb via recursion callback is obviously not a good idea ... but for now it has solved by problem until I do not find the right solution
should be
otherwise
this.
won’t point to your current component instance.See also https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Take a look at this excellent Stackoverflow thread. It explains the issue you’re having and the solution to it.
The
this
in your callback function is referring to the wrong context, because it is eventually being called from somewhere inside the facebook API code, not your class. Thus, you cannot access your other class functions with thisthis
.Thankfully, the solution to this is pretty simple:
By putting
this
in a temorary variable, and using that inside of the callback, you will be referring to the right context.