Background
In my angular2
application I am using Auth0
to authenticate
. After the redirect
back to my website I display some of the user's data
to them in the component
. When the page renders
it does not show the user's email
or gravatar
/ image. But at that point if I refresh the page the gravatar
and email
shows.
Setup
In app.component.html I am adding the breadcrumb component directly under the navigation but directly on top of the router-outlet
.
The breadcrumb is shown on every page. If someone is not logged in it shows a Login / Register
link. If someone is logged in it is supposed to show a picture of the user and their email which is returned in the auth0
profile
saved to the localStorage
.
Inside the component that is rendered to the router-outlet
all of the data that is in localStorage
is show in the page. This page renders perfectly. But the breadcrumb
component
does not update with the correct data from localStorage
.
It is obvious that the problem here is that the breadcrumb
component
is being rendered while the profile
in localStorage
is still null
.
Code Example
I am displaying the data like this,
breadcrumb.component.html
<ul class="nav navbar-nav pull-right" *ngIf="!auth.authenticated()">
<li class="nav-item">
<a class="nav-link" (click)="auth.login()">Login / SignUp</a>
</li>
</ul>
<ul class="nav navbar-nav pull-right" *ngIf="auth.authenticated()">
<li class="nav-item">
<a class="aside-toggle" href="#" role="button" aria-haspopup="true" aria-expanded="false">
<span *ngIf="auth.userProfile.nickname" class="profile-name">{{auth.userProfile.nickname}}</span>
<span *ngIf="!auth.userProfile.nickname" class="profile-name">Account</span>
<i class="icon-bell"></i><span class="tag tag-pill tag-danger profile-alerts">5</span>
<img *ngIf="auth.userProfile.picture" [src]="auth.userProfile.picture" class="img-avatar profile-picture" alt="User profile picture">
<img *ngIf="!auth.userProfile.picture" src="assets/img/avatars/gravatar-default.png" class="img-avatar profile-picture" alt="Default profile-picture">
</a>
</li>
</ul>
Please notice I have tried verifying and assigning the data in multiple different ways using built in NG2
features.
breadcrumb.component.ts
import { Component, OnInit, AfterViewInit, OnChanges } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Auth } from './../services/auth.service';
@Component({
selector: 'breadcrumbs',
templateUrl: './breadcrumb.component.html'
})
export class BreadcrumbsComponent implements OnInit, AfterViewInit, OnChanges {
private gravatar: string
private email: string;
constructor(private router:Router, private route:ActivatedRoute, private auth: Auth) {
if (this.auth.authenticated()) {
var userProfile = JSON.parse(localStorage.getItem('profile'));
this.gravatar = userProfile.picture;
this.email = userProfile.email;
}
}
ngOnChanges() {
if (this.auth.authenticated()) {
var userProfile = JSON.parse(localStorage.getItem('profile'));
this.gravatar = userProfile.picture;
this.email = userProfile.email;
}
}
ngOnInit() {
if (this.auth.authenticated()) {
var userProfile = JSON.parse(localStorage.getItem('profile'));
this.gravatar = userProfile.picture;
this.email = userProfile.email;
}
}
ngAfterViewInit() {
if (this.auth.authenticated()) {
var userProfile = JSON.parse(localStorage.getItem('profile'));
this.gravatar = userProfile.picture;
this.email = userProfile.email;
}
}
}
When I check the local storage the data does exist. So this leads me to believe that the page is rendering before the data is able to be placed in the local storage.
This is the majority of my auth0 service
.
authorize.service.ts
@Injectable()
export class Auth {
lock = new Auth0Lock(myConfig.clientID, myConfig.domain, options, {});
userProfile: Object;
logreg: LogReg;
user: User;
constructor(private router: Router, private http: Http ) {
this.userProfile = JSON.parse(localStorage.getItem('profile'));
this.user = JSON.parse(localStorage.getItem('user'));
this.lock.on('authenticated', (authResult: any) => {
localStorage.setItem('access_token', authResult.idToken);
this.lock.getProfile(authResult.idToken, (error: any, profile: any) => {
if (error) {
console.log(error);
return;
}
// Login Or Register User On Our Server
this.logreg = new LogReg(profile.email_verified, profile.email);
this.checkRegister(this.logreg).subscribe(
(res)=>{
console.log("Hey this runs");
console.log(res);
if (res.email_verified === false) {
localStorage.removeItem('profile');
localStorage.removeItem('api_key');
localStorage.removeItem('access_token');
localStorage.removeItem('user');
this.userProfile = null;
this.user = null;
this.router.navigate(['/verify-email']);
}
else if (res.api_key_exist === false) {
console.log("Hey this works")
localStorage.setItem('profile', JSON.stringify(profile));
this.userProfile = profile;
console.log(this.userProfile);
this.user = new User(profile.email, '', '', '', '', '', '', '', '', '', '', res.api_key_exist, '')
localStorage.setItem('user', JSON.stringify(this.user));
this.router.navigate(['/profile']);
} else if (res.api_key_exist === true) {
this.user = new User(res.user.email,
res.user.first_name,
res.user.middle_name,
res.user.last_name,
res.user.dob,
res.user.phone,
res.user.street_address,
res.user.city_address,
res.user.state_address,
res.user.zip_address,
res.user.client_ss,
res.api_key_exist,
res.api_key);
console.log(this.user);
localStorage.setItem('api_key', JSON.stringify(res.api_key));
localStorage.setItem('user', JSON.stringify(this.user));
localStorage.setItem('profile', JSON.stringify(profile));
this.router.navigate(['/overview']);
}
},
(err)=>{ console.log(err);}
);
});
this.lock.hide();
});
}
public checkRegister(model: LogReg) {
// Parameters obj-
let params: URLSearchParams = new URLSearchParams();
params.set('email', model.email);
params.set('email_verified', model.email_verified);
return this.http.get(STATICS.API_BASE + STATICS.API_LOGIN,
{ search: params }).map((res:Response) => res.json());
}
public login() {
this.lock.show();
}
}
Question
How would I go about making sure the data exist before completing the rendering of the page when someone logs in? This way I can make sure the correct data is displayed to the user.