Получить значение внутри наблюдаемого - PullRequest
0 голосов
/ 10 мая 2018

Я делаю запрос к серверу и получаю ответ как наблюдаемый. Внутри данных у меня есть идентификатор, который ссылается на другой документ, и мне нужно отправить еще один запрос для извлечения данных и добавления его к данным родительского объекта Observable. Как этого добиться?

С Promise я могу использовать async / await для этого, но я хочу знать, как этого добиться с помощью Observables

Образец с обещанием

async func_name() {
  let data1 = await <first_server_call_returns_promise>();
  let data2 = await <second_call_with_data1.id_returns_promise>();
  data1.value = data2;
  return data1;
}

Как достичь вышеуказанного с помощью Observables?

Редактировать 1

Основываясь на ответе @TeddySterne, код, который я написал, приведен ниже, но я получаю наблюдаемое в подписке вместо фактических данных, которые мешают мне присвоить наблюдаемое html

this.blogDoc.snapshotChanges().pipe(
    exhaustMap((blogs) => {
        return blogs.map(blog => {
          const data = blog.payload.doc.data();
          const id = blog.payload.doc.id;
          return this.userService.getUserById(data.uid).pipe(
            map((user) => {
              const name = user.name;
              return { id, name, ...data}
            }),
          )
        })
    }),
  )
  .subscribe(finalData => {
    finalData.subscribe(data => console.log(data));
  });

Редактировать 2

Ниже обновленный код, который у меня сейчас

this.blogDoc.snapshotChanges().pipe(
      exhaustMap((blogs: any[]) => {
        return zip(blogs.map((blog) => {
          const data = blog.payload.doc.data();
          const id = blog.payload.doc.id;
          console.log(data);
          return this.userService.getUserById(data.uid).pipe(
            map((value) => {
              console.log(value);
              return value;
            })
          )
        })).pipe(first())
      })
    ).subscribe(values => console.log("Values: ", values));

The console.log(data) печатает данные правильно, но console.log(value) не печатается и не console.log("Values: ", values)

Когда я использую подписку на this.userService.getUserById(data.uid), он возвращает ожидаемый однопользовательский документ.

Что мне здесь не хватает?

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Я попробовал приведенный выше код, но то, что я получаю в fullQualifiedData, является другой наблюдаемой, которую я не могу использовать непосредственно для * ngFor в html-файле.

Это обсуждаетсяв Angular docs, но по сути у вас есть два решения:

Использование async pipe

Канал async подпишется на наблюдаемое для вас и затем предоставит данные.Это просто в использовании, но обратите внимание, что каждый канал async создаст новую подписку, что в случае HTTP-запросов может означать запуск этого запроса несколько раз.Поэтому используйте с осторожностью.

@Component({ … })
export class YourComponent {
  public data$ = this.http.getFoo();

  constructor(private http: Http) {}
}
<ng-container *ngIf="data$ | async as data">
    {{ data.foobar }}
</ng-container>

Управление подпиской вручную

@Component({ … })
export class YourComponent implements OnInit {
  public data: Data;

  constructor(private http: Http) {}

  public ngOnInit() {
    this.http.getFoo().subscribe(data => this.data = data);
  }
}
{{ data?.foobar }}

или

<ng-container *ngIf="data">
  {{ data.foobar }}
</ng-container>
0 голосов
/ 10 мая 2018

Вы можете использовать exhaustMap для передачи данных во второй http-вызов, а затем объединить данные, когда они вернутся.

Пример

import { zip } from 'rxjs/observable/zip';

this.http.get('/data1').pipe(
  exhaustMap((data1Arr: any[]) => {
    return zip(...data1Arr.map((data1) => {
      return this.http.get('/data2/' + data1.id).pipe(
        map((data2) => {
          data1.value = data2;
          return data1;
        }),
      );
    }).pipe(first());
  }),
).subscribe((fullQualifiedData) => {
  // do stuff with the data
});

Пример

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...