4

I am trying to implement canActivate for user routes, before that I want to check whether the access token is still valid or not. Therefore I implement something like this

export class AuthGuard implements CanActivate {
  data:Array<Object>;
  constructor(private base: BaseService){}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): boolean {

    var session: any = { token: localStorage.getItem('abc') };   

    this.base.valid(session).subscribe(result => {
      this.data=result;
      console.log(this.data); <-- first 
    });

    console.log(this.data); <-- second
    return true;
  }
}

here I can get the data variable inside the subscribe method when I console it but outside this method is give undefined value. How can I access it outside the method.

Ashish Jambhulkar
  • 1,374
  • 2
  • 14
  • 26

4 Answers4

7

That won't be possible. The reason being, you are trying to render a value whose value is continuously changed by Observable.

Now, when you are trying to read outside console.log, you get undefined as the value is yet to be set by Observable streams. when the value is changed (let's say after 1 sec ), the outer console.log has already been executed and so you won't see any changes of the this.data

For monitoring the change in its value, put the function call in the subscribe block itself.

Update 1

As per your comment, You can refer this link

Shashank Vivek
  • 16,888
  • 8
  • 62
  • 104
  • ok, but how can i get this value, I want to return boolean based upon the value. – Ashish Jambhulkar Apr 10 '18 at 09:45
  • basically I am calling api to check the access token is valid or not. server return the `state`, now based on this state i am trying to return boolean value in canActivate method. here I am calling base api and then in subscribe I am checking state so that I can return boolean based on state – Ashish Jambhulkar Apr 10 '18 at 09:50
  • @AshishJambhulkar: Rather than checking the state in `canActivate`, you can move that **validation** logic to `BaseService` , lets say: `validRouting()` . Now this `validRouting()` can be returned itself from `canActivate` service (since it can return Observable) which will be of type `observable`. I hope you got my point. – Shashank Vivek Apr 10 '18 at 09:57
1

The BaseService.valid returns an Observable which emits after the canActivate method returns.

The console.log after the subscribe block executes first, when this.data is still undefined.

canActivate(
  next: ActivatedRouteSnapshot,
  state: RouterStateSnapshot): boolean {
  // 1.
  var session: any = { token: localStorage.getItem('abc') };   

  this.base.valid(session).subscribe(result => {
    // 3.
    this.data=result;
    console.log(this.data); 
  });


  // 2.
  console.log(this.data); 
  return true;
}
Tomasz Kula
  • 16,199
  • 2
  • 68
  • 79
0
public new_data:any=[];
this.base.valid(session).subscribe(result => {
  this.data=result;
  for(let data of this.data) {
    this.new_data.push(id:data.id, name:data.name)
  }
    console.log(this.new_data); <-- first
});
 console.log(this.new_data); <-- Second
ihsan
  • 29
  • 6
  • you have to store the subscriber result in the new array using for loop as above and you have to declare the new array as public as given in the above code – ihsan Jul 18 '19 at 11:28
0

Well to be able to push data to the array you have defined, first you have to initialize it as an empty array so:

Instead of :

data:Array<Object>

try this:

data: Array<any> = new Array<any>();

This is what i use, hope it helps.