Получение ответа от асинхронного вызова 1-го API (требуется время, чтобы получить ответ) и передача его во 2-й асинхронный интерфейс API для получения окончательного ответа - PullRequest
1 голос
/ 30 сентября 2019

1-й и 2-й вызов API - это почтовые вызовы

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)
  }))
}

Ответ, который я получаю от 1-го вызова API, выглядит как

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)

// 2-й вызов API

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

ВЫПУСК
Я также могу получить ответ от второго вызова API, но только когда я подписываюсь (как указано выше) на (getHisPointData) api , тогда как я хотелпередать этот ответ на obs , который в свою очередь будет передан следующей вызывающей функции

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

Но obs не определено

2-й вызов APIответ

       {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

Старая реализация, где я получал окончательное значение

 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);

                   }
               });
           });

       }

   });

Ответы [ 2 ]

1 голос
/ 30 сентября 2019

Вы можете попробовать вот так,

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 
  }))
}

, дайте мне знать, если он не проснулся :)

1 голос
/ 30 сентября 2019

Первая проблема, здесь:

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

, которая будет undefined , потому что undefined - единственное, что forEach возвращает. Вам нужно использовать map вместо

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

и forkJoin возвращаемых наблюдаемых:

return forkJoin(...obs)

И тот же шаблон для someFunction: map массива вмассив наблюдаемых ( не подписывается внутри функций отображения, возвращает наблюдаемые, а не подписки), forkJoin созданный массив наблюдаемых, наконец подписывается и использует результаты.

...