I\'m building a site that has a pretty standard RESTful web service to handle persistence and complex business logic. The UI I\'m building to consume this service is using A
I made a google-login component if you want an example.
ngOnInit()
{
this.initAPI = new Promise(
(resolve) => {
window['onLoadGoogleAPI'] =
() => {
resolve(window.gapi);
};
this.init();
}
)
}
init(){
let meta = document.createElement('meta');
meta.name = 'google-signin-client_id';
meta.content = 'xxxxx-xxxxxx.apps.googleusercontent.com';
document.getElementsByTagName('head')[0].appendChild(meta);
let node = document.createElement('script');
node.src = 'https://apis.google.com/js/platform.js?onload=onLoadGoogleAPI';
node.type = 'text/javascript';
document.getElementsByTagName('body')[0].appendChild(node);
}
ngAfterViewInit() {
this.initAPI.then(
(gapi) => {
gapi.load('auth2', () =>
{
var auth2 = gapi.auth2.init({
client_id: 'xxxxx-xxxxxx.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
scope: 'profile email'
});
auth2.attachClickHandler(document.getElementById('googleSignInButton'), {},
this.onSuccess,
this.onFailure
);
});
}
)
}
onSuccess = (user) => {
this._ngZone.run(
() => {
if(user.getAuthResponse().scope ) {
//Store the token in the db
this.socialService.googleLogIn(user.getAuthResponse().id_token)
} else {
this.loadingService.displayLoadingSpinner(false);
}
}
);
};
onFailure = (error) => {
this.loadingService.displayLoadingSpinner(false);
this.messageService.setDisplayAlert("error", error);
this._ngZone.run(() => {
//display spinner
this.loadingService.displayLoadingSpinner(false);
});
}
It's a bit late but I just want to give an example if someone want to use google login api with ng2.
For your first problem solution is to use arrow function which will preserve context of this :
onGoogleLoginSuccess = (loggedInUser) => {
this.userAuthToken = loggedInUser.getAuthResponse().id_token;
this.userDisplayName = loggedInUser.getBasicProfile().getName();
console.log(this);
}
Second issue is happening because third-party scripts run outside the context of Angular. Angular uses zones so when you run something, for example setTimeout(), which is monkey-patched to run in the zone, Angular will get notified. You would run jQuery in zone like this:
constructor(private zone: NgZone) {
this.zone.run(() => {
$.proxy(this.onGoogleLoginSuccess, this);
});
}
There are many questions/answers about the zone with much better explanations then mine, if you want to know more, but it shouldn't be an issue for your example if you use arrow function.
Include the below file in your index.html
<script src="https://apis.google.com/js/platform.js" async defer></script>
login.html
<button id="glogin">google login</button>
login.ts
declare const gapi: any;
public auth2:any
ngAfterViewInit() {
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: '788548936361-h264uq1v36c5ddj0hf5fpmh7obks94vh.apps.googleusercontent.com',
cookiepolicy: 'single_host_origin',
scope: 'profile email'
});
this.attachSignin(document.getElementById('glogin'));
});
}
public attachSignin(element) {
this.auth2.attachClickHandler(element, {},
(loggedInUser) => {
console.log( loggedInUser);
}, function (error) {
// alert(JSON.stringify(error, undefined, 2));
});
}
Try this package -
npm install angular2-google-login
Github - https://github.com/rudrakshpathak/angular2-google-login
I've implemented Google login in Angular2. Just import the package and you are ready to go.
Steps -
import { AuthService, AppGlobals } from 'angular2-google-login';
Supply providers -
providers: [AuthService];
Constructor -
constructor(private _googleAuth: AuthService){}
Set Google client ID -
AppGlobals.GOOGLE_CLIENT_ID = 'SECRET_CLIENT_ID';
Use this to call the service -
this._googleAuth.authenticateUser(()=>{
//YOUR_CODE_HERE
});
To logout -
this._googleAuth.userLogout(()=>{
//YOUR_CODE_HERE
});
The selected answer by Sasxa also helped me but I found that I can bind this to the onSuccess function using .bind(this), that way I don't have to create the function with a fat arrow.
ngAfterViewInit() {
var loginProxy = $.proxy(this.onGoogleLoginSuccess, this);
// Converts the Google login button stub to an actual button.
gapi.signin2.render(
this.googleLoginButtonId,
{
"onSuccess": loginProxy.bind(this),
"scope": "profile",
"theme": "dark"
});
}