Не может получить доступ к переменным данным и не может вернуть их в Angular Firestore - PullRequest
0 голосов
/ 22 марта 2019

Мой код для доступа к документу из firestore приведен ниже.

let data;
this.firestore.collection('groups').doc(tempId).ref.get().then(function(doc) {
  if (doc.exists) {
      data = doc.data();
      console.log("Document data:", doc.data());   // Gives correct data here
  } else {
      console.log("No such document!");
  }
}).catch(function(error) {
    console.log("Error getting document:", error);
});
console.log("Service Data :: " + data); //It says undefined here.

Здесь я хочу вернуть данные doc.data () другому компоненту.Но в console.log ("Service Data ::" + data); там указано undefined.

Итак, я запутался, как то, почему переменная данных не имеет значения doc.data () в нем.

Ответы [ 2 ]

1 голос
/ 22 марта 2019

метод .get() возвращает обещание, которое выполняется асинхронно после вызова .then().Из-за этого следующая выполняемая строка - console.log("Service Data :: " + data);.Javascript не ждет разрешения обещания и вместо этого просто продолжает следующую синхронную строку, которая является второй консолью.

Обычно я делаю это, передавая все обещание другому компоненту или лучшетем не менее, я использую .valueChanges() из .doc(), который возвращает наблюдаемое, и использую асинхронный канал в компоненте, которому я передаю:

// Get Observable on document. Returns Observable<any>
const group$ = this.firestore.doc('/groups' + tempId).valueChanges();

У вас тогда есть два варианта:

  1. Используйте group$.subscribe();
  2. Передайте group$ нужному компоненту и используйте там асинхронный канал

Первый вариант:

// In your component:
let data;
group$.subscribe(doc => {
  if (doc.exists) {
    data = doc
    console.log("Document data:", doc);   // No need to call data().
  } else {
    console.log("No such document!");
  },
  error => console.log("Error getting document:", error);
)

Второй вариант, переход к компоненту, где вы хотите, чтобы наблюдаемая была оценена и отображались данные:

<div *ngIf="group$ | async as doc">
  Your html here {{ doc.someProperty }} further html here...
</div>

Лично я предпочитаю второй вариант, потому что он хорошо сочетается с фреймворком и держит меняот совершения асинхронных ошибок.

Посмотрите репозиторий Angularfire2 Github для документов здесь .Если нет необходимости оценивать наблюдаемое вручную в коде, я бы не стал делать это и позволил бы инфраструктуре обработать его.

И последнее: если вы используете наблюдаемое и хотите при обработке использовать некоторую обработку ошибокасинхронный канал, вы, вероятно, захотите сделать это при создании наблюдаемой:

// Get Observable on document. Returns Observable<any>
// In error case, returns Observable of the error string
const group$ = this.firestore.doc('/groups' + tempId).valueChanges()
  .pipe(
    catchError(error => of(`Error getting document: ${error}`))
  );
1 голос
/ 22 марта 2019

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

let data;
this.firestore.collection('groups').doc(tempId).ref.get().then(function(doc) {
  if (doc.exists) {
      data = doc.data();
      console.log("Document data:", doc.data());   // first console
  } else {
      console.log("No such document!");
  }
}).catch(function(error) {
    console.log("Error getting document:", error);
});
console.log("Service Data :: " + data); //second console

если вы хотите изменить это поведение, обратитесь ко второй консоли рядом с первой.

Если вы хотите передать данные другому компоненту, используйте BehaviourSubject

  public  dataSource = new BehaviorSubject<any>([]);

  this.dataSource.next(doc.data()); 
  console.log("Document data:", doc.data());   // first console

передайте этот dataSource объект другому компоненту с помощью класса обслуживания и подпишите его как обычный Observable. перейдите по этой ссылке для получения дополнительной информации о angular-поведенческих субъектах-услугах

второй Component.ts

constructor(private service: Commonservice) { }

someMethod() {
  this.service.dataSource.subscribe((response: any) =>{
    // do something with data
  })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...