I am having an issue rendering a template after calling router.navigate inside a callback for auth0lock
loginComponent.ts
import {Component, Inject} from 'angular2/core';
import {Router, ComponentInstruction} from 'angular2/router';
import {Auth} from '../auth';
declare var Auth0Lock;
@Component({
selector: 'login',
templateUrl: '/tpls/login/login.html'
})
export class LoginComponent {
private lock = new Auth0Lock('xxx', 'xxx.auth0.com');
constructor(@Inject(Router) private router: Router, @Inject(Auth) private auth: Auth) { }
logError = (err) => {
console.log(err);
}
loginSuccess = (data) => {
if(this.router.parent.lastNavigationAttempt !== undefined && this.router.parent.lastNavigationAttempt !== '/Login') {
this.router.navigateByUrl(this.router.parent.lastNavigationAttempt);
} else if(data.user.req_update) {
this.router.navigate(['Profile']);
} else {
this.router.navigate(['Home']);
}
}
ngOnInit() {
this.lock.show((err: Error, profile: any, id_token: string) => {
if(err) return this.logError(err);
return this.auth.login(profile, id_token);
});
this.auth.loginSuccess.subscribe(
data => this.loginSuccess(data),
err => this.logError(err)
);
}
}
auth.ts
import {Injectable, Inject, EventEmitter, Output } from 'angular2/core';
import {Http, Headers} from 'angular2/http';
@Injectable()
export class Auth {
...
@Output() loginSuccess = new EventEmitter();
login = (profile, id_token) => {
...
this.addUser(profile).subscribe(
data => {
this.loginSuccess.next(data.json());
},
err => {
console.log(err);
this.loginSuccess.error(err.json());
}
);
}
addUser = (user: any) => {
let body = JSON.stringify(user);
return this.http.post('/api/user/add', body, { headers: this.headers});
}
}
homeComponent.ts
import {Component, Inject, OnInit} from 'angular2/core';
import {Http} from 'angular2/http';
import {ROUTER_DIRECTIVES} from 'angular2/router'
import {Auth} from '../auth';
import {Post} from '../post/Post';
import {IPost} from '../post/IPost';
import {AuthorComponent} from '../author/authorComponent';
@Component({
selector: 'home',
templateUrl: '/tpls/home/home.html',
directives: [ROUTER_DIRECTIVES, AuthorComponent]
})
export class HomeComponent implements OnInit {
private postService: Post;
private posts: IPost[];
constructor(@Inject(Http) private http: Http, @Inject(Auth) private auth: Auth) {
console.log('constructor');
this.postService = new Post(this.http, this.auth);
this.getPosts();
}
getPosts = () => {
this.postService.all().subscribe(
data => this.getPostsCallback(data.json()),
err => this.logError(err)
);
}
getPostsCallback = (data) => {
console.log('callback');
this.posts = data;
}
logError = (err) => {
console.log(err);
}
ngOnInit() {
console.log('init');
//this.postService = new Post(this.http, this.auth);
//this.getPosts();
}
}
I am including the cdn script for authlock in my index page. Seems like any route I navigate to after login does not render. The callback from this.lock.show works and I can read the variables. Any advice is greatly appreciated.
basic concept: https://plnkr.co/edit/Oz8lY7v6q8GpH71WLtAK
This Should fix your problem.
then inside your callback , call this
Thanks to this auth0 article I found a solution to the problem, since
NgZone
wasn't working for me.Wrapping the request in
bindNodeCallback
did the trick. This function wraps the Auth0 request with Zone.js and thus doing the request in the Angular zone.My code was:
But that resulted in not navigating to any page due to being out of Angular scope. I replaced that code with a Zone.js wrapped version to make it work:
And editing the request result can be done in the
subscribe
or via themap
functions.Versions
For the code above I am using the following versions:
Angular
6.1.7
auth0-js
9.8.0