0

This is the code from my last question:

getUserRole() {
  const headers = new Headers();
  headers.append('Authorization', `Bearer ${this.getToken()}`);
  console.log(this.getToken());
  const options = new RequestOptions({ headers: headers});

  return this.http.get(`${this.baseURL + this.loginApiRoot}/GetUserRoles`,options).pipe(map(res => res.json()))
    .subscribe(data => {
      this.userRole = JSON.stringify(data);
      if (this.userRole === 'parent') {
        this.logout();
      } else if (this.userRole === 'school') {
        this.isUser = true;
        this.isAdmin = false;
        this.cookieService.set('isSchool', '1');
      } else if (this.userRole === 'admin') {
        this.isUser = false;
        this.isAdmin = true;
        this.cookieService.set('isAdmin', '1');
      }
    });
}

But when I am trying to access userRole after calling this function, I get userRole undefined, maybe due to it gets returned before .subscribe gets hit.

As a result I get this as undefined:

var result = this.getUserRole(token);
console.log('Call from login ' + result);

So, I have changed the approach to be something like this:

getUserRole(roletoken: string) {
  const headers = new Headers();
  headers.append('Authorization', `Bearer ${roletoken}`);
  const options = new RequestOptions({ headers: headers});
  var result = this.http.get(`${this.baseURL + this.loginApiRoot}/GetUserRoles`, options).pipe(map(res => res.json()));
  console.log(result);
  return result;
}

But here I am getting result as [object object].

May I know which approach should I go with to immediately get userRole assigned by either method.

In second method I am not able to convert [object object] into the value.

The data I receive from API is something like this:

["school"]

This is the calling:

this.getUserRole(token);
console.log('Call from login ' + this.userRole);

This is inside getUserRole function:

var result = this.http.get(`${this.baseURL + this.loginApiRoot}/GetUserRoles`, options).subscribe(data => {
  this.userRole = JSON.stringify(data);
  console.log(data);
});

And this is the sequence of console I am getting:

Call from login undefined

Response {_body: "["school"]", status: 200, ok: true, statusText: "OK", headers: Headers, …}

So, even trying the code with subscribe, the assignment of userRole is getting latter by calling from login.

2
  • Are you using Http or HttpClient? Commented Jun 13, 2018 at 10:06
  • I am using Http Commented Jun 13, 2018 at 10:08

2 Answers 2

2

getUserRole returns an Observable. As you've seen you need to subscribe to it to make the HTTP call and receive the data. Since you're using the legacy Http class, instead of HttpClient, you need to convert the response to the actual JSON data. The code below should work:

getUserRole(roletoken: string) {
  const headers = new Headers();
  headers.append('Authorization', `Bearer ${roletoken}`);
  const options = new RequestOptions({ headers: headers});
  return this.http.get(`${this.baseURL + this.loginApiRoot}/GetUserRoles`, options).pipe(map(response => response.json()));
}

It's important to understand the asynchronous nature of Observables, and HTTP requests. this.userRole is only set after the request has completed. Thus, if you want to do something with this.userRole and want to be certain it has a value, you should use it inside of the subscribe function:

this.getUserRole(token).subscribe(userRole => { 
  this.userRole = userRole;
  console.log('Call from login ' + this.userRole);
});
Sign up to request clarification or add additional context in comments.

9 Comments

it is saying undefined
What is saying undefined when and where? How do you expect to use the value of getUserRole?
Note that any usage of this.userRole outside of the function passed to subscribe could result in undefined. This is due to the asynchronous nature of HTTP calls. The right answer really depends on how you want to use this.userRole.
userRole is globally declares for the export class, the getUserRole is simply storing role in this variable and login function is accessing the same. And I did what you exactly suggested.
I understand this.userRole refers to a property on the class. Could you provide the code that uses this property?
|
0

what I would have done would be, if your rest api send you a json

    userRole: UserRole // here you set the type of userRole as UserRole that you defined earlier or in an other file
    getUserRole() {
  const headers = new Headers();
  headers.append('Authorization', `Bearer ${this.getToken()}`);
  console.log(this.getToken());
  const options = new RequestOptions({ headers: headers});
  return this.http.get<UserRole>(`${this.baseURL + this.loginApiRoot}/GetUserRoles`,options)
  .subscribe(data => {
  this.userRole = data;
    if (this.userRole === 'parent') {
      this.logout();
  } else if (this.userRole === 'school') {
    this.isUser = true;
    this.isAdmin = false;
    this.cookieService.set('isSchool', '1');
  } else if (this.userRole === 'admin') {
    this.isUser = false;
    this.isAdmin = true;
    this.cookieService.set('isAdmin', '1');
  }
  });

}

if your api send you a list of json I would do, (it can be a list of a one json something like [{name: 'name', first_name:'first_name'}])

    userRole: UserRole // here you set the type of userRole as UserRole that you defined earlier or in an other file
    getUserRole() {
  const headers = new Headers();
  headers.append('Authorization', `Bearer ${this.getToken()}`);
  console.log(this.getToken());
  const options = new RequestOptions({ headers: headers});
  return this.http.get<UserRole[]>(`${this.baseURL + this.loginApiRoot}/GetUserRoles`,options)
  .subscribe(data => {
  this.userRole = data[0];   // of course here if you want them all you will make a loop and use this.userRoles set as userRoles: UserRole[]
    if (this.userRole === 'parent') {
      this.logout();
  } else if (this.userRole === 'school') {
    this.isUser = true;
    this.isAdmin = false;
    this.cookieService.set('isSchool', '1');
  } else if (this.userRole === 'admin') {
    this.isUser = false;
    this.isAdmin = true;
    this.cookieService.set('isAdmin', '1');
  }
  });

}

it seems like your api don't give you a json if it really give you something like ['school'] and not something like [{role: 'school'}] I would try

    getUserRole() {
  const headers = new Headers();
  headers.append('Authorization', `Bearer ${this.getToken()}`);
  console.log(this.getToken());
  const options = new RequestOptions({ headers: headers});
  return this.http.get(`${this.baseURL + this.loginApiRoot}/GetUserRoles`,options).pipe(map(res => res.json()))
  .subscribe(data => {
  this.userRole = JSON.stringify(data[0]);  // data is a list you take the first element 
    if (this.userRole === 'parent') {
      this.logout();
  } else if (this.userRole === 'school') {
    // same 

}

or

    getUserRole() {
  const headers = new Headers();
  headers.append('Authorization', `Bearer ${this.getToken()}`);
  console.log(this.getToken());
  const options = new RequestOptions({ headers: headers});
  return this.http.get(`${this.baseURL + this.loginApiRoot}/GetUserRoles`,options).pipe(map(res => res.json()))
  .subscribe(data => {
  this.userRole = JSON.stringify(data);  // data is a list you take the first element 
    if (this.userRole[0] === 'parent') {
      this.logout();
  } else if (this.userRole[0] === 'school') {
    // same but you take the first element of the list

}

I am not sure of the last 2 as I used to get json response from my apis but that's what I would check in a first time and see what I get

don't forget you can debug and see the value of your variable at each step using a browser debugger like you have in chrome just set a breakpoints at the beginning of your function and follow it ;)

3 Comments

Yeah I know I am getting result from API as object and NOT json and achieved the same by getting the value. But question is not this. The point is I will get my variable assigned just after using it from the calling method. Pl read my comments for Sajeetharan
oh so you mean the issue is this.userRole is defined after you you would like to use it ? if so how do you call this function in an other ts file or in a html file ?
if you are using Http did you check that stackoverflow.com/questions/42905990/… it seems like you should map but not subscribe, in your function definition

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.