Enthu
Enthu

Reputation: 532

Getting response from async 1st api call(takes time to get the response) and passing it on to the 2nd async api in order to get the final response

Both 1st and 2nd api calls are post calls

someFunction(floor){
floor.entities.forEach(elementId => {
                        let desiredTempForZone;
                        this.getDesiredHeatingTemp(elementId._id).subscribe((des) => 
                                {
                                    desiredTempForZone = des
                                });
                        console.log(desiredTempForZone);
})
}

getDesiredHeatingTemp(eleId){
    //1st api call
    return this.siteService.getScheduleParamsByRoomRef('temp and air and desired and heating', eleId)
    .pipe(
    switchMap(a => {
        console.log(a)
        const obs = a.forEach((m)=>{
          //console.log(m)

        //this is custom function
        let pointId = this.helperService.stripHaystackTypeMapping(m.rows[0]['id']).split(' ')[0];

        //2nd api call
        return this.siteService.getHisPointData(pointId, 'current')
      })
      return forkJoin(obs)
  }))
}

The response which I get from 1st api call looks like

a=
cols: (23) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
meta: {ver: "2.0"}
rows: [{…}]

a=
 cols: (23) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
 meta: {ver: "2.0"}
 rows: Array(1)
      0:
       air: "m:"
       desired: "m:"
       id: "r:5d906-9600-desire"
       kind: "Number"
       __proto__: Object
       length: 1
       __proto__: Array(0)

//2nd api call

  return this.siteService.getHisPointData(pointId, 'current').subscribe(e => console.log(e))

ISSUE
I am also able to get response from 2nd api call but only when I subscribe(as above) to (getHisPointData) api whereas I wanted to pass this response to obs which would inturn be passed to the below calling function

this.getDesiredHeatingTemp(elementId._id).subscribe((des) => 
                                {
                                    desiredTempForZone = des
                                });

But obs is undefined

The 2nd api call response

       {meta: {…}, cols: Array(2), rows: Array(1)}
     cols: (2) [{…}, {…}]
     meta: {ver: "2.0", id: "r:5d8df1fc3942df083a4539d5", hisStart: "n:0.0", hisEnd: "n:0.0"}
     rows: Array(1)
        0:
          ts: "t:2019-09-30T13:40:58.761Z UTC"
          val: "n:65"
          __proto__: Object
          length: 1
        __proto__: Array(0)
    __proto__: Object
   {meta: {…}, cols: Array(2), rows: Array(1)}
     cols: (2) [{…}, {…}]
     meta: {ver: "2.0", id: "r:5d8df1fc3942df083a4539d5", hisStart: "n:0.0", hisEnd: "n:0.0"}
     rows: Array(1)
        0:
          ts: "t:2019-09-30T13:40:58.761Z UTC"
          val: "n:70"
          __proto__: Object
          length: 1
        __proto__: Array(0)
    __proto__: Object
           {meta: {…}, cols: Array(2), rows: Array(1)}
     cols: (2) [{…}, {…}]
     meta: {ver: "2.0", id: "r:5d8df1fc3942df083a4539d5", hisStart: "n:0.0", hisEnd: "n:0.0"}
     rows: Array(1)
        0:
          ts: "t:2019-09-30T13:40:58.761Z UTC"
          val: "n:90"
          __proto__: Object
          length: 1
        __proto__: Array(0)
    __proto__: Object

Older implementation where I was getting final value

 this.siteService.getScheduleParamsByRoomRef('temp and air and desired and heating', eleId).subscribe(({ rows }) => {
       if (rows.length > 0) {
           rows.forEach((row) => {
               let pointId = this.helperService.stripHaystackTypeMapping(row['id']).split(' ')[0];

               this.siteService.getHisPointData(pointId, 'current').subscribe(({ rows }) => {
                   if (rows.length > 0) {
                       let HeatingDesired = this.helperService.stripHaystackTypeMapping(rows[0].val);

                   }
               });
           });

       }

   });

Upvotes: 1

Views: 123

Answers (2)

Yash Rami
Yash Rami

Reputation: 2317

You can try like this,

someFunction(floor){
floor.entities.forEach(elementId => {
  let desiredTempForZone;
   this.getDesiredHeatingTemp(elementId._id).subscribe((des) => 
   {
     desiredTempForZone = des
   });
 })
}

getDesiredHeatingTemp(eleId){
    //1st api call
    return this.siteService.getScheduleParamsByRoomRef('temp and air and desired and 
      heating', eleId)
    .pipe(
    switchMap(a => {
        let secondApiCallUrlList = [];
        const obs = a.rows.forEach((m)=>{
          //this is custom function
          let pointId = this.helperService.stripHaystackTypeMapping(m.rows[0] 
            ['id']).split(' ')[0]; // here we dont need to create the asynchronisation block because as you said before older implemention is working as expected 

        //2nd api call
       secondApiCallUrlList.push(this.siteService.getHisPointData(pointId, 'current'));
      })
      return forkJoin(secondApiCallUrlList); // so here we are passing the whole array so while you subscribe you will get all response once all api call finished 
  }))
}

let me know if it is not woking :)

Upvotes: 1

mbojko
mbojko

Reputation: 14679

First problem, here:

const obs = a.forEach((m)=> {

that'll be undefined, because undefined is the only thing a forEach returns. You need to use a map instead

const obs = a.map((m) => {

and forkJoin the returned observables:

return forkJoin(...obs)

And the same pattern for someFunction: map an array into an array of observables (don't subscribe inside the mapping functions, return observables, not subscriptions), forkJoin the created array of observables, finally subscribe and consume the results.

Upvotes: 1

Related Questions