Mi objetivo es implementar la capacidad de eliminar un documento específico en una colección de firebase, como un botón en un componente. Para hacer esto, estoy usando un servicio Angular para obtener todas las ID de documentos en una colección, como se muestra a continuación (porque las ID también tienen utilidad en otros componentes):
getCurrUserDocID(){ this.getUsers().subscribe(arr =>{ this.listUsers = arr.map(item => { return{ userDocID : item.payload.doc.id, ...item.payload.doc.data() as User } }) }) return{ userIDs : this.listUsers };Inyectar este servicio en los componentes me permite obtener los docID. Sin embargo, es quisquilloso. Cuando lo llamé en ngOnInit en un componente que se carga en una pestaña de la barra de navegación, no funciona a menos que haga clic en esa pestaña un par de veces:
ngOnInit(): void { console.log(this.service.getCurrUserDocID().userIDs) }El primer y segundo clic devuelven una matriz vacía en la consola, mientras que el tercero finalmente devuelve la matriz de datos real. Sospecho que esto tiene algo que ver con los observables y la asincronía.
Está utilizando una suscripción para obtener los datos del observador this.getUsers() . Al obtener nuevos datos, establece el valor de this.listUsers . Ahora todo lo que necesita en su componente es acceder a this.listUsers.
Solo recuerde que cada vez que haya datos provenientes del observador this.getUsers() , el valor de this.listUsers se sobrescribirá, lo que hará que su componente se vuelva a procesar.
El hecho de que obtenga los datos solo en la tercera invocación puede estar relacionado con el tiempo que tarda this.getUsers() en devolver la fecha o con la forma en que la usa. Debe notar que la suscripción al observable devolverá múltiples resultados.
No se suscriba fuera del componente porque deberá cancelar la suscripción. Si desea ordenar los datos, use el operador map() en pipe() .
getCurrUserDocID(){ this.listUsers = this.getUsers().pipe( map(item => { return { userDocID: item.payload.doc.id, ...item.payload.doc.data() as User } }) ) };en componente
constructor(public: service: Service) {} // Make it public so you can use it in html file ngOnInit(): void { this.service.getCurrUserDocID() // here just triger `getUsers()` function. }En plantilla html con tubería asíncrona
<ul> <li *ngFor="let item of service.listUsers | async"> {{item.id}} </li> </ul>La tubería asíncrona en la plantilla se suscribe y cancela la suscripción por usted, por lo que no debe preocuparse por las fugas de datos.