/ / Присъединяване към Firebase Query в Angularfire2 - ъглов, машинопис, firebase, firebase-база данни, angularfire2

"Присъединяване" към Firebase заявки в Angularfire2 - ъглови, машинопис, firebase, firebase-database, angularfire2

Проблемите, с които се сблъсквах с празнотостойностните полета се отнасят до несъществуващи ключове в моята база данни, така че по-голямата част от дискурса тук няма да се отнася за вашия въпрос. Ако търсите начин за „присъединяване“ към заявки в AngularFire2, приетият отговор по-долу прави прекрасна работа на това. В момента използвам combineLatest вместо forkJoin, За да направите това, трябва import "rxjs/add/observable/combineLatest";.

Имам следната денормализирана структура на Firebase:

members
-memberid1
-threads
-threadid1: true,
-threadid3: true
-username: "Adam"
...

threads
-threadid1
-author: memberid3
-quality: 67
-participants
-memberid2: true,
-memberid3: true
...

Искам да изобразя username в моето threads изглед, който е сортиран по quality.

Моята услуга:

getUsername(memberKey: string) {
return this.af.database.object("/members/" + memberKey + "/username")
}

getFeaturedThreads(): FirebaseListObservable<any[]> {
return this.af.database.list("/threads", {
query: {
orderByChild: "quality",
endAt: 10
}
});
}

Моят компонент:

ngOnInit() {
this.threads = this.featuredThreadsService.getFeaturedThreads()
this.threads.subscribe(
allThreads =>
allThreads.forEach(thisThread => {
thisThread.username = this.featuredThreadsService.getUsername(thisThread.author)
console.log(thisThread.username)
})
)
}

По някаква причина това записва нещо, което изглежда като неизпълнени наблюдения на конзолата.

въведете описанието на изображението тук

Бих искал да получа тези стойности в свойство на threads така че мога да го представя според мен така:

<div *ngFor="let thread of threads | async" class="thread-tile">
...
{{threads.username}}
...
</div>

Обновено: console.log за allThreads и thisThread

въведете описанието на изображението тук

въведете описанието на изображението тук

Актуализирано: абонирано е за getUsername ()

this.featuredThreadsService.getUsername(thisThread.author)
.subscribe( username => console.log(username))

Резултатът от това са обекти без стойности:

въведете описанието на изображението тук

Отговори:

4 за отговор № 1

Можете да съставите наблюдаемо въз основа на getFeaturedThreads който пита членове и замества стойностите във всяка нишка participants собственост с потребителски имена:

import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/forkJoin";
import "rxjs/add/operator/do";
import "rxjs/add/operator/first";
import "rxjs/add/operator/switchMap";

let featuredThreadsWithUserNames = this.getFeaturedThreads()

// Each time the getFeaturedThreads emits, switch to unsubscribe/ignore
// any pending member queries:

.switchMap(threads => {

// Map the threads to the array of observables that are to be
// joined. When the observables emit a value, update the thread.

let memberObservables = [];
threads.forEach(thread => {

// Add the author:

memberObservables.push(this.af.database
.object(`members/${thread.author}`)
.first()
.do(value => { thread.author = value.username; })
);

// Add the participants:

Object.keys(thread.participants).forEach(key => {
memberObservables.push(this.af.database
.object(`members/${key}`)
.first()
.do(value => { thread.participants[key] = value.username; })
);
});
});

// Join the member observables and use the result selector to
// return the threads - which will have been updated.

return Observable.forkJoin(...memberObservables, () => threads);
});

Това ще ви даде наблюдение, което се излъчва всеки път getFeaturedThreads излъчва. Ако обаче потребителските имена се променят, то няма да бъде повторно излъчено. Ако това е важно, заменете forkJoin с combineLatest и премахнете first оператор от съставения член наблюдава.


0 за отговор № 2

За да разреша присъединяването на потребителите, написах услуга, която кешира вече изтеглените потребители и ги прехвърля в референтните данни с минимален код. Използва вложена структура на картата, за да направи присъединяването:

constructor(public db: AngularFireDatabase, public users:UserProvider) {
this.threads = db.list("threads").valueChanges().map(messages => {
return threads.map((t:Message) => {
t.user = users.load(t.userid);
return m;
});
});
}

И услугата UserProvider изглежда така:

@Injectable()
export class UserProvider {
db: AngularFireDatabase;
users: Map<String, Observable<User>>;

constructor(db: AngularFireDatabase) {
this.db = db;
this.users = new Map();
}

load(userid:string) : Observable<User> {
if( !this.users.has(userid) ) {
this.users.set(userid, this.db.object(`members/${userid}`).valueChanges());
}
return this.users.get(userid);
}
}

Има пълен работен пример за съединенията и всички котелни плочи тук