I am trying to utilize rxJs concatMap inside my angular 9 application. Basically I need to make two web api calls using http, both return observables, populate other values. The first call need to return some values, which will be used as parameter for second api call and then supposed to continue. I tried to utilize the concatMap for this using tap, but no luck. When the method(checkForRenewal()) is called, the first line gets hit, but waiting for completion of api call or go to second api call , it moves to other lines.
The program is either not waiting for the first to finish and second call don't execute correctly and the control move to next lines (after 2 web api calls). After few seconds, I see the first API is triggered and the values are read, but it is too late.
I have other api calls following the contactMap...but excluding from this post.
How to achieve this or what is wrong ? Do i need a final subscribe after concatMap ? Sample code below.
checkForRenewal(): void {
this.ls.getSoftwareModules() //first web api call
.pipe(
tap((data) => {
{
try {
const dataXml = data.filter((data) => data.SoftwareModuleName == 'Activation')[0].XmlConfig;
if (dataXml) {
const config = xmlToJson(dataXml);
this.autoRenewalEnabled =
config['configuration'].appSettings.param.filter(
(data) => data.name == 'AutoRenewalEnabled',
)[0].value === 'true';
this.autoRenewalCheckingFrequencyInHours = config[
'configuration'
].appSettings.param.filter(
(data) => data.name === 'AutoRenewalCheckingFrequencyInHours', //this line not hitting first, but later gets hit
)[0].value;
}
} catch (e) {
}
}
}),
concatMap(() => this.ls.checkForRenewalAlreadyRan(this.autoRenewalCheckingFrequencyInHours, true)), //2nd web api call
tap((data2) => {
this.skipKeyRenewal = data2;
console.log('checkForRenewalAlreadyRan-->' + data2);
}),
)
.subscribe((resp) => {
console.log(resp);
});
if (this.skipKeyRenewal) { //issue ...control seem to reach here first before making the above api calls using concatMap
console.log('auto renewal program already ran in last 24 hours, so processing will not resume!');
return;
} else {
console.log('process continue for auto renewal...');
}
this._activationService.getActivationSites().subscribe({
next: (resp) => {
this.sites = resp;
this.siteName = this.sites[0].SiteName;
this.siteID = this.sites[0].SiteID;
},
error: (err) => {
console.log(`err-->${err}`);
},
});
this._activationService.getUuidPartial().subscribe({
next: (resp) => {
this.hardwareID = resp;
this.decimalHardwareID = parseInt(this.hardwareID, 16);
},
error: (err) => {
console.log(`err-->${err}`);
},
});
hData = this._activationService.getProductActivations('ProductA', this.showKeys);
gData = this._activationService.getProductActivations('ProductB', this.showKeys);
//other stuff goes here on wards
==============================================
//two api calls returning observables in service ( lookup.service.ts)
//1st web api
getSoftwareModules(where: string = '', orderBy: string = ''): Observable<SoftwareModule[]> {
const url = `${this.config.host}${GLOBAL.SV_GET_MODULE_LIST}sessionID=${this.appSession.session.SessionID}&where=${where}&orderby=${orderBy}`;
return this.http.get<SoftwareModule[]>(url);
}
//2nd web api
checkForRenewalAlreadyRan(frequencyInHoures: number, isApiReady: boolean): Observable<boolean> {
const url = `${this.config.host}${GLOBAL.SV_GET_KEY_RENEWAL_SETTINGS}sessionID=${this.appSession.session.SessionID}&frequencyInHoures=${frequencyInHoures}&isApiReady=${isApiReady}`;
return this.http.get<boolean>(url);
}