Angular / angularfire2 - прочитать наблюдаемый документ и сохранить данные в объекте. Нет asyn c pipe - PullRequest
0 голосов
/ 03 августа 2020

Я застрял над этой проблемой довольно долго, и я не уверен, как решить ее, используя метод, который мне нужен.

По сути, у меня есть коллекция под названием pages, которая содержит все страницы документов. Меня интересует запрос на одну из страниц. Я хочу прочитать один из документов как наблюдаемый и с помощью директивы NgModel обновлять данные в реальном времени. Я думаю, что я понял эту часть: чего у меня нет, так это того, как получить данные из firebase без использования asyn c pipe.

Когда я подписываюсь на поток данных, я не получаю объект данных (значения, которые я могу использовать сразу), но наблюдаемый (затем мне нужно использовать конвейер asyn c в HTML, чтобы просмотреть его). Есть ли способ подписаться на данные и заполнить какой-либо объект данными из firebase (в основном делать то, что конвейер asyn c делает в компоненте HTML, но без использования конвейера asyn c?).

Ниже приведен page.service.ts logi c, который получает данные из firebase:

  /**
   *
   * @param workspaceId
   * @param pageId
   * GET A PAGE AS AN OBSERVABLE
   * SNAPSHOT CHANGES ALLOWS THIS TO BE WRITTEN TO IN REAL TIME
   */
  getWorkspacePage(workspaceId: string, pageId: string) {
    return this.afAuth.authState.pipe(
      map((user) => {
        if (user) {
          return this.fs.doc$(
            `users/${user.uid}/workspaces/${workspaceId}/pages/${pageId}`
          );
        } else {
          return {};
        }
      })
    );
  }

Ниже приведена конкретная функция c, doc$:

  /**
   * GET THE DATA
   */
  doc$<T>(ref: DocumentPredicate<T>): Observable<T> {
    return this.doc(ref)
      .snapshotChanges()
      .pipe(
        map((doc) => {
          return doc.payload.data() as T;
        })
      );
  }

Вот компонент ts:

currentPage: Page;
  @Input("currentPageId") currentPageId; // currentPageId
  @Input() workspace; // workspaceId
  sub: Subscription;

  ngOnInit() {
    // current page
    this.sub = this.pageService
      .getWorkspacePage(this.workspace.id, this.currentPageId)
      .subscribe((pageData) => {
        this.currentPage = pageData;

         // now what must be done to get pageData as an object and not as an observable?

      });

Спасибо!

1 Ответ

2 голосов
/ 04 августа 2020
getWorkspacePage(workspaceId: string, pageId: string) {
    return this.afAuth.authState.pipe(
      map((user) => {
        if (user) {
          return this.fs.doc$(
            `users/${user.uid}/workspaces/${workspaceId}/pages/${pageId}`
          );
        } else {
          return {};
        }
      })
    );
  }

В этом методе используется map, следовательно, return this.fs.doc$ ..., который является возвращенным Observable, а не желаемым объектом.

Попробуйте использовать switchMap следующим образом:

getWorkspacePage(workspaceId: string, pageId: string) {
    return this.afAuth.authState.pipe(
      switchMap((user) => {
        if (user) {
          return this.fs.doc$(
            `users/${user.uid}/workspaces/${workspaceId}/pages/${pageId}`
          ); // return page data as Observable
        } else {
          return of({}); // return a blank object as the Observable
        }
      })
    );
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...