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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.