использование toPromise () и наблюдаемое не работает асинхронно - PullRequest
0 голосов
/ 10 июля 2020

Я новичок, использую angular и firebase, и я застрял на каком-то этапе обучения. Я не родной английский sh.

Я следил за учебником с использованием базы данных реального времени, но теперь я пытаюсь потренироваться с помощью firestore.

У меня есть коллекция под названием «категории» , который содержит такие категории, как «игрушки», «пицца» или что-то еще.

Моя цель - получить эти категории, используя подход, аналогичный подходу, который я видел ранее, поэтому, пожалуйста, не присылайте мне что-то совершенно другое , я пытаюсь научиться, а не для того, чтобы это работало (ну, в некотором роде, но .. вы понимаете ахах).

Так что это мой сервис

getCategories () {
    let categories = [];
    this.db.collection("categories").get().toPromise().then(function(querySnapshot) {
          querySnapshot.forEach(function(doc) {
            categories[doc.id] = doc.data();
          });
      console.log("getCategories() returned : ");
      console.log(categories);
      return categories;
        })
        .catch(function(error) {
          console.log("Error getting documents: ", error);
        });
  }

и это мой компонент

export class ProductFormComponent {

  categories$;

  constructor(categoryService: CategoryService) {
    this.categories$ = categoryService.getCategories();
  }
}

Я пытаюсь использовать «toPromise ()», чтобы создать обещание, которое получит все категории и отобразит его в наблюдаемом, называемом категориями $.

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

I Я использую асинхронный c " tag ", но это ничего не решает.

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

Если я найду свой ответ (какой бы глупый он ни был), я все равно опубликую его здесь, так что мой пост не будет бесполезным.

Всем спасибо, надеюсь, вы не слишком раздражены, получив вопрос начинающего.

1 Ответ

1 голос
/ 10 июля 2020

Ваш метод getCategories() ничего не возвращает, поэтому this.categories$ будет undefined навсегда.

Если вы конвертируете его в обещание, просто чтобы снова вернуть его как Observable, я не думаю, что вам нужно преобразовать его в первую очередь.

Обновленная служба, которая возвращает наблюдаемый

// you may want to type your observable better...
getCategories (): Observable<any[]> {
    return this.db.collection("categories").get().pipe(
        map(querySnapshot => {
          let categories = []; //I don't think you actually want an array here, but thats what your existing code had
          querySnapshot.forEach(function(doc) {
            // you were originally  trying to set the index of an array to be the doc ID, this is probably going to cause an issue
            // categories[doc.id] = doc.data();
            // this will add the data to the array, you probably lose the ID though
            categories.push(doc.data());
          });
          console.log("getCategories() returned : ");
          console.log(categories);
          return categories;
         
        }),
        catchError(error => { 
           console.log("Error getting documents: ", error);
           return []; // You need to determine what to do here, return an empty array, or possibly re-throw the error with throwError(error)
        });

    );

Обновленный компонент. Обратите внимание, что мы все еще не подписываемся, поэтому он по-прежнему ничего не сделает. Вы должны подписаться в шаблоне где-нибудь через async pipe.

export class ProductFormComponent {

  categories$: Observable<any[]>; // type this better...

  constructor(categoryService: CategoryService) {
    this.categories$ = categoryService.getCategories();
  }
}

Пример шаблона с asyn c pipe

<ul>
<li *ngFor="let category of categories$ | async">
{{category | json}} <!-- do something better here to show your data -->
</li>
</ul>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...