2017-08-17 2 views
1

Ich verwende Ionic 3, Firebase und FirebaseAuth. Ich versuche den aktuell authentifizierten Benutzer zu verwenden, um eine Liste von Objekten für diesen Benutzer abzurufen. Unten ist mein Versuch, und ich erhalte eine FehlermeldungWie gebe ich eine Liste der Ergebnisse mit rxjs zurück

getContacts Error: TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

Mir fehlt hier etwas, da dies scheint, wie es die onNext mit jedem neuen Stück von Daten aktualisieren soll.

Mein Versuch:

getContacts() { 
    this.contactList.length = 0; 
    this.data.getAuthenticatedUserContactList().subscribe(
     (contact => { 
     this.contactList.push(contact); 
     }), 
     (error => console.error(`getContacts Error: ${error}`)) 
    ); 
    } 

getAuthenticatedUserContactList() { 
    return this.afAuth.getAuthUser() 
     .flatMap(user => this.database.list(`contact-lists/${user.uid}`).take(1)) 
     .flatMap((contactList) => { 
     if (contactList && contactList.length > 0) {     
      contactList.forEach(element => { 
      console.log(`ForEach: ${element.userId}`); // THIS LOGS THE IDS AS EXPECTED 
      return this.database.object(`/profiles/${uid}`, { preserveSnapshot: true }).take(1); 
      }); 
     } else { 
      return Observable.throw(new Error("No bros here")); 
     } 
     }); 
    } 

Jede Hilfe wäre sehr dankbar.

Lösung gemäß forkJoin Empfehlung:

getContacts() { 
    this.contactList.length = 0; 
    this.data.getAuthenticatedUserContactList().subscribe(
     (contact => { 
     contact.map(userContact => { 
      this.contactList.push(<UserProfile>(userContact)); 
     }); 
     }), 
     (error => console.error(`getContacts Error: ${error}`)) 
    ); 
    } 

    getAuthenticatedUserContactList() { 
    return this.afAuth.getAuthUser() 
     .mergeMap(user => this.database.list(`contact-lists/${user.uid}`).take(1)) 
     .mergeMap((contactList) => { 
     return Observable.forkJoin(contactList.map(element => this.getProfileWithUid(element.userId).map(userProfile => userProfile.val()))) 
     }); 
    } 

    getProfileWithUid(uid: string) { 
    this.profileObject = this.database.object(`/profiles/${uid}`, { preserveSnapshot: true }); 
    return this.profileObject.take(1); 
    } 

Antwort

1

Im zweiten flatMap() Operator bist du nichts zurückkehrt, wenn diese Bedingung erfüllt ist:

contactList && contactList.length > 0 

Die return Anweisung ist innerhalb forEach Rückruf.

Ich weiß nicht, was die Logik Ihrer App ist aber der Rückruf flatMap muss immer ein beobachtbares zurückzukehren (oder etwas hier aufgelistet: http://reactivex.io/rxjs/class/es6/MiscJSDoc.js~ObservableInputDoc.html)

+0

Nun, dachte ich, die ‚nehmen (1)‘ liefert ein beobachtbar: Export deklarieren Funktion nehmen (dies: Observable , Anzahl: Nummer): Observable ; – AnxGotta

+0

@AnxGotta Es gibt eine Observable zurück, aber das ist nicht das Problem. Ich spreche von der zweiten 'flatMap' – martin

+0

, die ich nicht verstehe. Wenn die zurückgegebene Liste keine Elemente enthält oder null ist, gebe ich ein "ErrorObservable" von "Observable.throw (" ")" zurück. Wenn es Elemente in der Liste gibt, gebe ich für jedes Element ein Observable zurück. – AnxGotta

Verwandte Themen