3

I need user ID in almost all REST requests.

When I log-in a user, I pass token to local storage and ID to user.service.ts (by function setUserId(userId);) but when I authenticate user only by token (user is logged but page was refreshed) I try to get userId from User object (get user object from REST request by token).

This part of my code look like:

getUser() {
    var authToken = localStorage.getItem('authorization')

    if(!this.userPromise){
      let headers = new Headers();
      headers.append('Content-type', 'application/json');
      headers.append('Authorization', authToken);

      this.userPromise = this.http.get(
        'http://localhost:8080/api/user',
        { headers }
      ).toPromise()
        .then((res) => res.json());
    }

    return this.userPromise;
  };




getUserId(){
    var $self = this;

    if($self.userId){
      return $self.userId;
    } else {
      $self.getUser().then(function(result){
        $self.setUserId(result.id);
        console.log(result.id);
        return result.id;
      });
    }
  }

When any request ask for user ID i use getUserId() and I check if user Id is defined. If is defined i response with this data, but if not - I want get this data from getUser() function.

I can't solve one problem - this request is async and for example "task" service set userId value as undefined - doesn't wait on this new value.

How can I manage with this problem?

---EDIT

Hire is a request - it doens't wait on response;

 getUserTasks() {
    // return this.userService.getUserId();
    var userId = this.userService.getUserId();

    return this.http.get(
      'http://localhost:8080/api/private/'+userId+'/tasks'
      // 'http://localhost:8080/api/private/1/tasks'
    )
    .toPromise()
      .then((res) => res.json());
  }
5
  • could you provide a plnker please ? Commented Jun 16, 2017 at 18:44
  • Can you show how you are using the value in the template? So I can give you the fastest way to achieve it. You seem to do too much work for a small task. Commented Jun 16, 2017 at 19:09
  • In my template I have only this: {{data | async}} I know - i can load everythink in frame with ng-if="user.id" but it not good solutions in this case. Commented Jun 16, 2017 at 19:32
  • If you use arrow function () => {} instead of function() {}, then you don't need to use the ugly $self hack and can instead just use this. Commented Jun 17, 2017 at 15:18
  • Thanks @GünterZöchbauer for your suggestion. Sometimes I forgot about this in ES6 because I code a lot in old standard where this is necessary. Commented Jun 17, 2017 at 18:07

1 Answer 1

4

I found solutions - only one thinks to do is a proper way to use async/await function on getUserTasks():

 async getUserTasks() {
    let userId = await this.userService.getUserId();

    return this.http.get(
      'http://localhost:8080/api/private/'+userId+'/tasks'
    )
    .toPromise()
    .then((res) => res.json());
  }

--- EDIT ---

Finally - if somebody find the same problem I move my changes level up - to authentication process. In this way I have access to userId from any part of my application by services UserService.getUserId();

When user is log-in I have time to put all data to variable, but when i make only authentication i modify isLoggedIn() function to be async/await. If ticket exist i send authentication request to get User object.

If I get user object I return true and put userId to userId services. When I get error (no credentials) I make log-out action in getUser() function.

I think that this is the best solutions - it provide all necessary data and give additional verification process in guard.

async isLoggedIn() {
    var $self = this;

    if(localStorage.getItem("authorization")){
      var user = await $self.getUser();
      this.setUserId(user.id);

      return true;
    } else {
      return false;
    }
  }
Sign up to request clarification or add additional context in comments.

2 Comments

Glad to hear, Just to let you know, async/away uses promises under the hood. here is a good post if you want to know more about it
Thanks for your help @Omri Luzon

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.