Reputation: 532
At three places I am making API calls (I have numbered it (1),(2),(3)).
getCMPortsMapping(siteRef: string) {
Object.keys(cmBoardPortsEnum).forEach(port => {
let queryParams = "output and system and enabled and config and " + cmBoardPortsEnum[port];
let cmBoardPortsMappings = new CMBoardPortsMappings("", "", false, "", "");
// ------- (1) --------
this.siteService.getDetailsBySiteRef(queryParams, siteRef).subscribe(portsDetail => {
if (portsDetail && portsDetail.rows.length > 0) {
cmBoardPortsMappings.type = cmBoardPortsEnum[port];
//Check if port is enabled ------ (2) --------
this.siteService.getWritablePointData(this.helperService.parseRef(portsDetail.rows[0].id)).subscribe(portEnable => {
if (portEnable && portEnable.rows.length) {
//got data for port
if (portEnable.rows[0] && portEnable.rows[0].val) {
//got port enable/disbale
let val = this.helperService.TypeMapping(portEnable.rows[0].val)
switch (val) {
case "1.0":
cmBoardPortsMappings.isEnabled = true;
//Get the port mapping
let mappingQuery = "system and cmd and " + cmBoardPortsEnum[port];
// ----------- (3) -----------
this.siteService.getDetailsBySiteRef(mappingQuery, siteRef).subscribe(mappingDetails => {
if (mappingDetails && mappingDetails.rows.length) {
mappingDetails.rows[0].dis.split("SystemEquip-")[1] != "" ? cmBoardPortsMappings.mapping = mappingDetails.rows[0].dis.split("SystemEquip-")[1] : '';
this.helperService.parseRef(mappingDetails.rows[0].id) != "" ? cmBoardPortsMappings.ref = this.helperService.parseRef(mappingDetails.rows[0].id) : '';
if (cmBoardPortsMappings.mapping != "") {
cmBoardPortsMappings.param = cmBoardPortsMappings.mapping.toLowerCase().replace(/\s/g, "")
}
}
else {
throw new Error("In correct port mapping read from haystack")
}
});
break;
case "0.0":
cmBoardPortsMappings.isEnabled = false;
cmBoardPortsMappings.mapping = "";
break;
default:
throw new Error("In correct port val read from haystack")
}
this.cmBoardPortsMappingsCollection.set(cmBoardPortsEnum[port], cmBoardPortsMappings);
}
}
});
}
});
});
}
I had used switchmap in some other piece of code as well
this.siteService.getFloorRooms(this.floorRef).pipe(
switchMap(res => {
const rest = res
let elementId = [];
res.rows.forEach((element) => {
elementId.push(element.id)
});
for (const color of elementId) {
this.roomref = (color).split(":")[1].split(" ")[0];
}
return this.siteService.checkPairedRooms(this.roomref)
})
).subscribe(m => {
this.rooms = m.rows;
if (m.rows.length == 1) {
this.paired = true;
}
this.getExistingFloorPlan();
});
Should I use mergemap
, concatmap
, switchmap
? What is the correct way to implement it? As pointed out by someone foreach inside switchmap will not return , so using forkjoin
and other utilities would help but I haven't used these rxjs utility functions.
Upvotes: 0
Views: 80
Reputation: 14099
It doesn't matter whether you use mergemap
, concatmap
, switchmap
with http requests, because they only emit once and complete.
Create an array of concatenated http requests mapping each request to the next one and the final one to your desired output. Then pass that array to forkJoin
. Enjoy.
getCMPortsMapping(siteRef: string) {
forkJoin(Object.keys(cmBoardPortsEnum).map(port => {
let queryParams = "output and system and enabled and config and " + cmBoardPortsEnum[port];
return this.siteService.getDetailsBySiteRef(queryParams, siteRef).pipe(
filter(portsDetail => portsDetail && portsDetail.rows.length > 0),
switchMap(portsDetail => this.siteService.getWritablePointData(this.helperService.parseRef(portsDetail.rows[0].id))),
filter(portEnable => portEnable && portEnable.rows.length && portEnable.rows[0] && portEnable.rows[0].val),
switchMap(portEnable => {
const cmBoardPortsMappings = new CMBoardPortsMappings("", "", false, "", "");
cmBoardPortsMappings.type = cmBoardPortsEnum[port];
const val = this.helperService.TypeMapping(portEnable.rows[0].val)
switch (val) {
case "1.0":
cmBoardPortsMappings.isEnabled = true;
return enrichCmBoardPortsMappings(cmBoardPortsMappings, siteRef);
case "0.0":
cmBoardPortsMappings.isEnabled = false;
cmBoardPortsMappings.mapping = "";
return of(cmBoardPortsMappings);
default:
return throwError('In correct port val read from haystack');
}
})
)
})).subscribe(cmBoardPortsMappingsArray => cmBoardPortsMappingsArray.forEach(cmBoardPortsMappings =>
this.cmBoardPortsMappingsCollection.set(cmBoardPortsMappings.type, cmBoardPortsMappings)
));
}
enrichCmBoardPortsMappings(cmBoardPortsMappings: CMBoardPortsMappings, siteRef: string): Observable<CMBoardPortsMappings> {
let mappingQuery = "system and cmd and " + cmBoardPortsMappings.type;
return this.siteService.getDetailsBySiteRef(mappingQuery, siteRef).pipe(
tap(mappingDetails => {
if(!(mappingDetails && mappingDetails.rows.length)) throw new Error('In correct port mapping read from haystack') ;
}),
map(mappingDetails => {
if (mappingDetails.rows[0].dis.split("SystemEquip-")[1] != "") {
cmBoardPortsMappings.mapping = mappingDetails.rows[0].dis.split("SystemEquip-")[1];
}
if (this.helperService.parseRef(mappingDetails.rows[0].id) != "") {
cmBoardPortsMappings.ref = this.helperService.parseRef(mappingDetails.rows[0].id);
}
if (cmBoardPortsMappings.mapping != "") {
cmBoardPortsMappings.param = cmBoardPortsMappings.mapping.toLowerCase().replace(/\s/g, "")
}
return cmBoardPortsMappings;
})
)
}
Upvotes: 1