0

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.

kaws
  • 1
  • 1
  • Are you setting the accessToken in the localStorage? and how? – Prav Jul 24 '17 at 19:49
  • yes, this is tutorial iam following https://auth0.com/docs/quickstart/spa/angular2 accessToken is set because the profile is fetched, if the page is reloaded. – kaws Jul 24 '17 at 19:55
  • Did you change the token expiry time in the setSession method? I belive their example it expire after a second. – Prav Jul 24 '17 at 19:59
  • The profile data is accessed if the page is reloaded. – kaws Jul 24 '17 at 20:03
  • I would guess that the getProfile method is being called before the login transaction fully finishes and there is an access token saved in local storage. Are you able to arrange things so that you can be sure that the access token has been saved before you try to get the profile? – kaws Jul 24 '17 at 20:04
  • It throws the error because a token is not available in the local storage and you didn't tell us how did you save it. Also you should provide us the information what did you do to obtain the access token because some api requires additional callto get a token after login. – Roman C Jul 24 '17 at 20:09
  • i did , i follow the tutorial from this link auth0.com/docs/quickstart/spa/angular2 – kaws Jul 24 '17 at 20:11

1 Answers1

0

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);
  }
Chris A
  • 144
  • 2
  • 11