profile object from auth0 is empty until the page is loaded

619 views Asked by At

I have follow the documentation of auth0 to implement profile picture and other profile data. The profile object from auth0 is empty until the page is loaded. Here is my code to call profile data from navbar component,

ngOnInit() {
    if (this.auth.userProfile) {
        this.profile = this.auth.userProfile;
        return;
    }
    if (this.auth.authenticated) {
        this.auth.getProfile((err, profile) => {
            this.profile = profile;
        });
    }
}

Here is getProfile method from auth.service,

public getProfile(cb): void {
    const accessToken = localStorage.getItem('access_token');
    if (!accessToken) {
        throw new Error('Access token must exist to fetch profile');
    }    
    const self = this;
    this.auth0.client.userInfo(accessToken, (err, profile) => {
        if (profile) {
            self.userProfile = profile;
        }
        cb(err, profile);
    });
}

After login, i get the error 'Access token must exist to fetch profile' but if i reload it i dont see it.

1

There are 1 answers

0
Chris A On

I had the same issue as @Kaws

It works in the tutorial but when I try and implement it in my solution, I want to show the "nickname" in a navbar which is loaded before the access token is stored.

The solution to this is to use an observable as suggested by chenkie

AuthService.ts:

import { Observable, Observer } from 'rxjs';
// ...
private observer: Observer<string>;
userImageChange$: Observable<string> = new Observable(obs => this.observer = obs);
// ...
public handleAuthentication(): void {
  this.auth0.parseHash((err, authResult) => {
    if (authResult && authResult.accessToken && authResult.idToken) {
      window.location.hash = '';
      this.setSession(authResult);
      this.getProfile();
      this.router.navigate(['/controlpanel']);
    } else if (err) {
      this.router.navigate(['/controlpanel']);
      console.log(err);
    }
  });
}

public getProfile(): void {
  const accessToken = localStorage.getItem('access_token');
  if (!accessToken) {
    throw new Error('Access token must exist to fetch profile');
  }
  const self = this;
  this.auth0.client.userInfo(accessToken, (err, profile) => {
  if (profile) {
      this.observer.next(profile.picture);
    }
  });
}

Then in your getProfile call in the component:

 userImage: string;

  constructor(private auth: AuthService) {}

  ngOnInit() {
    this.auth.userImageChange$.subscribe(image => this.userImage = image);
  }