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))
);

Relaterte artikler