Angular 6 Observable chaining and error handling

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Angular 6 Observable chaining and error handling



I am getting the param via observable and if it is of proper enum type then i fetch data. I am not using snapshot for getting the param. This needs to use observable.



Also, there is a refresh button on the page and it just calls the second data method directly since we'll have the correct enum available to fetch data for.



Currently the following works for me.


export class MaintainComponent implements OnInit, OnDestroy
grouptType: zGroupTypes;
title: string = "";
isError: boolean = false;
errorMessage: string = "";
groupList: Group;

//handles to destroy the observables manually
activatedRouteSubscription: Subscription;
groupSubscription: Subscription;

constructor(private activatedRoute: ActivatedRoute, private router: Router, private dataService: DataService)

ngOnInit()
this.title = "";
this.isError = false;
this.errorMessage = "";
this.groupList = ;

this.checkAndGetData();


ngOnDestroy()
this.activatedRouteSubscription.unsubscribe();
this.groupSubscription.unsubscribe();


onRefresh()
this.getGroupInfo();


checkAndGetData()

this.activatedRouteSubscription = this.activatedRoute.params.subscribe(
(params: Params) =>
this.grouptType = <zGroupTypes>params['type'];
if (this.grouptType && this.grouptType in zGroupTypes)
//good
this.title = zGroupTypes[this.grouptType];
//get the group info
this.getGroupInfo();

else
//error - redirect to resource missing
this.router.navigate(['resource-missing']);


);


getGroupInfo()
this.groupList = ;
this.isError = false;
this.errorMessage = "";

const params = new HttpParams().set('groupType', this.grouptType.toString());
this.groupSubscription = this.dataService.pull<Group>(`$this.dataService.endPointGroup/GetGroupByAttributeId`, params).subscribe(
res =>
//res is of type Group
if (!res ,
error =>
this.isError = true;
this.errorMessage = "Error happened"; //console.log(error);

);





I want to rewrite this so that i don't use an observable inside an observable. After some reading, i have to use mergeMap but then how to



I found an example online to do chaining which looks like


export class AppComponent
homeworld: Observable<>;
constructor(private http: HttpClient)

ngOnInit()
this.homeworld = this.http.get('/api/people/1').pipe(
mergeMap(character => this.http.get(character.homeworld))
);




but then this doesn't show how to handle errors.



I started some thing like following but i am kind of lost since i am still relatively new to angular and operators are still not my strong point.


getData()
let singleCall = this.activatedRoute.params.pipe(
map(params =>
this.grouptType = <zGroupTypes>params['type'];
),
filter(() => this.grouptType && this.grouptType in zGroupTypes),
mergeMap(() =>
const paramToPass = new HttpParams().set('groupType', this.grouptType.toString());
this.dataService.pull<Group>(`$this.dataService.endPointGroup/GetGroupByAttributeId`, paramToPass)
.... how to proceed here
)
);



or is it safe to say that my original approach is still proper way of handling this situation.




1 Answer
1



In map function, you must return new value. Don't assign side-effect inside it. Moreover, in this case, you should use switchMap instead of mergeMap


map


switchMap


mergeMap


getData()
let singleCall = this.activatedRoute.params.pipe(
map(params => params.type),
tap((groupType) => this.groupType = groupType),
filter((groupType) => groupType && groupType in zGroupTypes),
switchMap(() =>
const paramToPass = new HttpParams().set('groupType', this.grouptType.toString());
return this.dataService.pull<Group>(`$this.dataService.endPointGroup/GetGroupByAttributeId`, paramToPass)
)
);



EDIT: If you want to switch case of groupType, you can extend to 2 Observable


groupType


Observable


const param$ = this.activatedRoute.params.pipe(
map(params => params.type),
tap((groupType) => this.groupType = groupType),
);

param$.pipe(
filter((groupType) => !(groupType && groupType in zGroupTypes)),
).subscribe(() =>
console.error("Failed")
);

param$.pipe(
filter((groupType) => groupType && groupType in zGroupTypes),
switchMap(() =>
const paramToPass = new HttpParams().set('groupType', this.grouptType.toString());
return this.dataService.pull<Group>(`$this.dataService.endPointGroup/GetGroupByAttributeId`, paramToPass)
)
).subscribe((results) =>
// to do
);





what is getData() returning, is it observable? So, if groupType isn't good then switchMap will not execute, am i correct? and i am going to handle error in the refresh and ngonInit, some thing like this.getData.observable( res => ..., error => ...);
– learning...
Aug 12 at 5:54


this.getData.observable( res => ..., error => ...);





Yes, it is. However, if you want getData return Observable, run must replace let singleCall = to return. Moreover, the correct syntax is this.getData.subscribe, not this.getData.observable. You can subscribe after pipe too, no need to return getData as Observable
– hgiasac
Aug 12 at 6:15



getData


let singleCall =


return


this.getData.subscribe


this.getData.observable





this.grouptType is undefined inside switchMap. filter has groupType but it is not being assigned to this.groupType
– learning...
Aug 12 at 6:18


this.grouptType





If you want to set this.groupType, you can append tap((groupType) => this.groupType = groupType) after map (see my example)
– hgiasac
Aug 12 at 6:23


this.groupType


tap((groupType) => this.groupType = groupType)


map





I think the step of getting param don't affect much about performance. However, if you want to use cached this. groupType on refreshing, you can use expression like this: const param$ = this. groupType ? of(this.groupType) : this.activatedRoute.... of function will wrap the value into observable. The remain code is the same
– hgiasac
Aug 12 at 7:45


this. groupType


const param$ = this. groupType ? of(this.groupType) : this.activatedRoute...


of






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard