2

I'm getting crazy with this, so I submit to the audience.

I need to return an Observable. I first call Firestore to retrieve a field that contains an array and then based on each value of the array, I want to retrieve the matching key. Fairly easy usually.

I see exactly what I cant on the console, so data are here, but why the hell they never show up in the view. Before I gave up, I made countless variations of the below.

My Service – Edited to reflect suggestions. Still not working

    getUserActivites() {

    console.log(this.userId)
    let array = []

    const agenda = this.afs.doc(`users/${this.userId}`).snapshotChanges()

     agenda.subscribe(list => {
      const data = list.payload.data().activities
       data.map(event => {
        const id = event
        const dataRef = this.afs.doc(`activities/${event}`).valueChanges()
         dataRef.subscribe(date => {
           array.push(date)
           console.log(array) //array log the expected data in an array of Object
          return data 
        })
      })
    })
    return agenda
  }

My Component public agendaData: Observable<any>

then in constructor

this.agendaData = this.agenda.getUserActivites()

My View

<div *ngFor="let item of agendaData | async ">
{{ item.name }}
</div>
Makah
  • 4,435
  • 3
  • 47
  • 68
Benoit
  • 374
  • 4
  • 20
  • Hi @Benoit. I'm not sure if I understood. Your issue is that you can't display an item's `key`? Or all data (e.g. `item.name`)? If it's the `key` only, it's because Firestore doesn't have one. You need to use the [snapshotChanges() method](https://github.com/angular/angularfire2/blob/master/docs/firestore/collections.md#snapshotchanges) to map it and include it in your array. – Will Dec 28 '17 at 22:41
  • My issue is I can't display any data at all. In this scenario I don't even need the key. I just want to retrieve a list of selected document. The selection happen based on an key which is hosted into `list.payload.data().activities` – Benoit Dec 28 '17 at 22:45
  • Your problem is that you are trying to return data from subscribe, which doesn't work :) https://stackoverflow.com/questions/39295854/angular-2-how-to-return-data-from-subscribe – AT82 Dec 29 '17 at 08:43

2 Answers2

1

1) I think you forgot to subscribe() in this.afs.....snapshotChanges(). One of the differences between Promise and Observables is that Observables is lazy - you need to subscribe it to start working.

2) If you do not need key/id you should use valueChanges() that is easier to use. Example (not tested):

getUserActivites() {
    let agenda = [] //Created for logging only

    let usersTask = this.afs.object(`users/${this.userId}`).valueChanges();     
    let myReturnTask = usersTask.subscribe(users => {           
        console.log('received users');
        users.map(user => {             
            const dataRef = this.afs.doc(`activities/${user.id}`).valueChanges()

            dataRef.subscribe(date => {
              agenda.push(date) //For logging purpose I created this array
              console.log(agenda) //Here I see exactly what I want!

              return date  // Why date is not returned?
            }) 
        })
    })

    return myReturnTask;
}
Makah
  • 4,435
  • 3
  • 47
  • 68
  • Thanks @Makah, I need to use `snapshotChanges()`as I need to read the `payload` before requesting the next `dataRef`. I update my code above with your proposal but it not working yet. How can I chekc the value received by `this.agendaData = this.agenda.getUserActivites()`in my component? – Benoit Dec 29 '17 at 09:43
  • @Benoit try to debug it with console.log() and see what you get. You can't verify synchronously beucause you are returning an Observable. I changed the code a bit to help you. – Makah Dec 29 '17 at 12:26
  • Freshly read in firestore documentation `Although Cloud Firestore can store arrays, it does not support querying array members or updating single array elements.` So maybe what I try to do is not possible with Firestore. I'll reconsider my view by creating single component that will host single `activities` and then create these single component based on array of `list.payload.data().activities` – Benoit Dec 29 '17 at 17:27
0

Does getUserActivities = () => { work?

Is date an observable?

this.observableBooks = this.bookService.getBooksWithObservable();

getBooksWithObservable(): Observable { return this.http.get(this.url).map((res: Response) => res.json());

Sorry if it doesn’t answer your question I like to know myself what the issue is here!

oudekaas
  • 325
  • 1
  • 6
  • 21