Westwick
Westwick

Reputation: 2497

Angular route paramMap switchMap stops working after 404

In my component's ngOnInit, I am using paramMap as suggested in the documentation to re-use a component but switch based on the user id provided in the route:

    this.route.paramMap
        .switchMap((params: ParamMap) => {
            this.errors = false;
            this.busy = true;
            return this.userService.getUser(params.get('id'));
        })
        .subscribe((user) => {
            this.busy = false;
            this.errors = false;
            // do something with user object...
          }, (error) => {
            this.busy = false;
            this.errors = true;
            if (error.status === 404) {
                this.errorMsg = 'User not found';
            }
        });

However as soon as the userService.getUser() method throws a 404 error, .switchMap() stops firing when the route params change, to a new user id for example. I've tried throwing .catch() into both the service as well as the component but it seems to have no effect, and it still stops working after a 404. Am I going about this incorrectly?

Upvotes: 1

Views: 1610

Answers (3)

baruhari
baruhari

Reputation: 11

I had same problem while working on Angular Heroes app, Issue got resolve by importing the switchMap operator.

import 'rxjs/add/operator/switchMap';

Upvotes: 1

DJDJ
DJDJ

Reputation: 1866

Note - I just started working with Angular a few months back.

However, I think the following will fix your problem (I think the whole point of using switchmap is to remove the subscribes).

Try the following:

user$: Observable<user>;

user$ = this.route.paramMap
        .switchMap(params => {
            this.errors = false;
            this.busy = true;
            return this.userService.getUser(params.get('id'));
        })
        .do(next => {
            this.busy = false;
            this.errors = false;
            // do something with user object...
          })
        .catch(error => {
            this.busy = false;
            this.errors = true;
            if (error.status === 404) {
                this.errorMsg = 'User not found';
            }
            return Observable.of(null);
        });

Then, in your template, use the async pipe like this:

( user$ | async ) as user

The "as user" may be optional depending on your use case.

Hope this helps.

Upvotes: 0

fastAsTortoise
fastAsTortoise

Reputation: 641

I had the same problem even though i am subscribing to the activatedRoute observables they only trigger once so i have to do this

router.events.subscribe(event:Event => {
    if(event instanceof NavigationEnd) {
   // your route code here
   this.route.paramMap
        .switchMap((params: ParamMap) => {
            this.errors = false;
            this.busy = true;
            return this.userService.getUser(params.get('id'));
        })
        .subscribe((user) => {
            this.busy = false;
            this.errors = false;
            // do something with user object...
          }, (error) => {
            this.busy = false;
            this.errors = true;
            if (error.status === 404) {
                this.errorMsg = 'User not found';
            }
        });
    }
    })

Upvotes: 0

Related Questions