faserx
faserx

Reputation: 317

Subscription function in Angular 4

I have a question regarding observables and subscriptions. I was developing a method that when I received an http 401 status, updates the signal and updates the function, but this does not work and the method update function does not run

This is the function with subscription method:

 ngOnInit() {

    this.licenceList = new Array<License>();

    this.subscription = this._phpService.tokenRefreshed$.subscribe(value =>{
      if(value === true){
        this._license.getLicenseList().subscribe(licenses => this.licenceList = licenses);
      }
    });

    this._license.getLicenseList().subscribe(licenses => this.licenceList = licenses);

  }

here I declare the observable

private tokenRefreshed: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
tokenRefreshed$  = this.tokenRefreshed.asObservable();

and with this method I refresh the token

interceptMex(message)
{
        switch(message.status){
            case 401:
                ++PhpService.tokenQueue;
                if(PhpService.tokenQueue >  1 ){
                    return message.json();
                }else{
                     this.refreshToken();
                }
            case 404:
                return message.json();
            default:
                return message.json();
        }

}

refreshToken(){
    let url = "auth/refresh/self";
    this.post(url, localStorage.getItem('refresh_token')).subscribe(res =>{
        window.localStorage.setItem('access_token', res['access_token']);
        window.localStorage.setItem('refresh_token', res['refresh_token']);
        this.tokenRefreshed.next(true);
    });

}

UPDATE

Post function:

post(url, parameters): Observable<any>
    {
        PhpService.layoutService.updatePreloaderState('active');
        PhpService.loaderQueue++;
        let apiDomain = this.config.settings.urlController;

        let phpUrl = apiDomain + url;
        let headers = new Headers({'Content-Type' : 'application/json'});

        if(localStorage.getItem("access_token") != null){
            headers.append('Authorization' ,localStorage.getItem('access_token'));
        }

        return this.http.post(phpUrl, '', {headers: headers, body: parameters})
            .map(message => this.interceptMex(message))
            .catch( error =>  Observable.of( this.interceptMex(error)))
            .finally(() => PhpService.stopLoader());
    }

can someone help me?

Upvotes: 1

Views: 959

Answers (2)

ippi
ippi

Reputation: 10167

I know almost no rxjs, and this is probably not the answer to your question but I can still point out something that has to be wrong:

Every subscribe()-call you make creates a new subscription. Meaning every time tokenRefreshed$ triggers with a value of true, you are creating a new subscription without any heed to the old subscription(s);

I would assume something like this would make more sense:

this.tokenSubscription = this._phpService.tokenRefreshed$.subscribe(value =>{
  if(value === true){     
    this.licenceSubscription.unsubscribe();
    this.licenceSubscription = this._license.getLicenseList().subscribe(licenses => this.licenceList = licenses);
  }
});
this.licenceSubscription = this._license.getLicenseList().subscribe(licenses => this.licenceList = licenses);

Since the subscription-handlers are identical I wouldn't recreate those either:

// This creates the handler once, instead of a new one every time you subscribe.
this.handler = licenses => this.licenceList = licenses; 

this.tokenSubscription = this._phpService.tokenRefreshed$.subscribe(value =>{
  if(value === true){      
     this.licenceSubscription.unsubscribe();
     this.licenceSubscription = this._license.getLicenseList().subscribe(this.handler);
  }
});
this.licenceSubscription = this._license.getLicenseList().subscribe(this.handler);

The reason is that if subscriptions are anything at all like EventListeners (wild assumption, I know), then trying to add an existing handler to a subscription would be ignored - effectively preventing leaks and unintentionally triggering multiple handlers.

And on a very minor note: I think you'll make your world easier if you spell license the same everywhere.

I think none of the above is related to the problem you are asking about though so hang in there for a real answer. (there is just so much you can cram into one comment so I made this into an answer instead. )

Upvotes: 1

user9903
user9903

Reputation:

Nothing seems obviously wrong in your code snippets.

This seems like a more generic debugging question:

  1. check the documentation for handling errors in Angular
  2. check the docs for how .catch() works with Observables
  3. insert a breakpoint in the JavaScript debugger in your web browser to make sure that the method isn't being called or if it is, to step through and figure out what values the variables have at that point
  4. use the good old console.log method and insert that at a few spots in the code to trace the flow of the code and see what's being returned
  5. check the network requests to see what the response status and payload are; maybe you aren't actually receiving a 401 error response at any point?

Upvotes: 0

Related Questions