angular - Hvordan kan jeg korrekt bruke RxJS for å legge til et nytt felt til hvert objekt i et array som returneres i en Observable?
Jeg er ikke så interessert i RxJS, og jeg har følgende tvil.
Inn i denne Angular-tjenesteklassen har jeg denne metoden som henter data fra Firebase FireStore-databasen:
async getAllEmployees() {
return <Observable<User[]>> this.firestore.collection('users',ref => ref.where('profileType', '!=', 'admin')).valueChanges();
}
Som du kan se, returnerer den en Observable av User-objektet.
hvor Bruker er dette grensesnittet:
export interface User {
firstName: string;
surname: string;
completeName: string;
email: string;
photoUrl: string;
phoneNumber: string;
companyName: string;
vatID: string;
profileType: 'admin' | 'user' | 'unknown';
UID: string;
approved:boolean;
}
Nå trenger jeg å legge til completeName-feltet (ikke presentert på Firestore, så dette feltet hentes ikke) som er sammenslåingen av firstName- og surname-feltet til hvert objekt i det hentede arrayet fra den returnerte Observable. Jeg tenker at kanskje jeg kan bruke RxJS map-operatoren for å utføre denne oppgaven. Jeg prøvde å gjøre noe som dette:
return <Observable<Employee[]>> this.firestore.collection('users',ref => ref.where('isEmployee', '==', true)).valueChanges()
.pipe(map(userObj => {
const completeObj = {
completeName = userObj["firstName"] + " " + userObj["surname"],
...userObj
}
console.log("completeObj: ", completeObj);
return userObj;
}));
Men ved å gjøre det på denne måten oppnår jeg at følgende objekt blir opprettet (jeg kan se det i console.log i min Chrome-konsoll):
completeObj:
{0: {…}, completeName: "undefined undefined"}
0: {firstName: "Andrea", isEmployee: true, socialSecurityCode: "NBLNDRH501O", password: "XXXXXX", isAdmin: false, …}
completeName: "undefined undefined"
__proto__: Object
Så i utgangspunktet virker det som om det ikke legger til dette nye beregnede feltet til hvert objekt i arrayet som returneres som Observable, men det legger det til selve Observable.
Hvorfor? Hva er galt? Hva går jeg glipp av? Hvordan kan jeg fikse det?
Svar #1
Din userObj er et array av ansatte. Rxjs-operatøren map mapper dette arrayet, ikke arrayelementene. Det du trenger er en "nested" map.
return <Observable<Employee[]>> this.firestore.collection('users',ref => ref.where('isEmployee', '==', true))
.valueChanges().pipe(
map(usersArr => usersArr.map(user => ({ ...user, completeName: user.firstName + " " user.surname}))),
);
Svar #2
Du kan ikke initialisere en egenskap via tildeling.
Dette er et objekt:
{
firstName: "Hillary",
lastName: "Brown"
}
og dette er ikke gyldig syntaks:
{
firstName = "Hillary",
lastName = "Brown"
}
Jeg er overrasket over hva du fikk til å kompilere. Kanskje det gjør noe merkelig med den nåværende konteksten (this)? Jeg prøvde nettopp å gjøre noe lignende, og det ville ikke kompilere for meg.
Også, kartet ditt returnerer den samme verdien det får inn, du vil sannsynligvis returnere det nye objektet.
return <Observable<Employee[]>> this.firestore.collection(
'users',
ref => ref.where('isEmployee', '==', true)
).valueChanges().pipe(
map(userObj => ({
...userObj,
completeName: userObj["firstName"] + " " + userObj["surname"]
})),
tap(completeObj => console.log("completeObj: ", completeObj))
);
