Home > Enterprise >  Mapping incorrect values
Mapping incorrect values

Time:07-07

I'm trying to map multiple observables into one single observable use RXJS CombineLatest. This was previously working when I was trying to map 6 observables but when adding an additional 5, the compiler seems to get confused about the mapping. This is the logic in question:

interface ReferenceData {
    observableOne: ArrOne[];
    observableTwo: ArrTwo[];
    observableThree: ArrThree[];
    observableFour: ArrFour[];
    observableFive: ArrFive[];
    observableSix: ArrSix[];
    observableSeven: ArrSeven[];
    observableEight: ArrEight[];
    observableNine: ArrNine[];
    observableTen: ArrTen[];
    observableEleven: ArrEleven[];
}

export class ReviewComponent extends BaseComponent implements OnInit, AfterViewInit {

 observableOne$: Observable<ArrOne[]>;
 observableTwo$: Observable<ArrTwo[]>;
 observableThree$: Observable<ArrThree[]>;
 observableFour$: Observable<ArrFour[]>;
 observableFive$: Observable<ArrFive[]>;
 observableSix$: Observable<ArrSix[]>;
 observableSeven$: Observable<ArrSeven[]>;
 observableEight$: Observable<ArrEight[]>;
 observableNine$: Observable<ArrNine[]>;
 observableTen$: Observable<ArrTen[]>;
 observableEleven$: Observable<ArrEleven[]>;

 referenceData$: Observable<ReferenceData>;

  ngOnInit(): void {
        this.getReferenceData();
        this.createSingleReferenceDataObservable();
    }

  getReferenceData() {
        this.observableOne$ = this.entityService.get('TestDataOne');
        this.observableTwo$ = this.entityService.get('TestDataTwo');
        this.observableThree$ = this.entityService.get('TestDataThree');
        this.observableFour$ = this.entityService.get('TestDataFour');
        this.observableFive$ = this.entityService.get('TestDataFive');
        this.observableSix$ = this.entityService.get('TestDataSix');
        this.observableSeven$ = this.entityService.get('TestDataSeven');
        this.observableEight$ = this.entityService.get('TestDataEight');
        this.observableNine$ = this.entityService.get('TestDataNine');
        this.observableTen$ = this.entityService.get('TestDataTen');
        this.observableEleven$ = this.entityService.get('TestDataEleven');
   }

    createSingleReferenceDataObservable() {
            this.referenceData$ = combineLatest([
                this.observableOne$, 
                this.observableTwo$, 
                this.observableThree$, 
                this.observableFour$, 
                this.observableFive$, 
                this.observableSix$, 
                this.observableSeven$, 
                this.observableEight$, 
                this.observableNine$, 
                this.observableTen$, 
                this.observableEleven$
            ])
            .pipe(
                map(([
                    ArrOne, 
                    ArrTwo, 
                    ArrThree, 
                    ArrFour, 
                    ArrFive, 
                    ArrSix, 
                    ArrSeven, 
                    ArrEight, 
                    ArrNine, 
                    ArrTen, 
                    ArrEleven
                ]) => {
                    return {
                        ArrOne, 
                        ArrTwo, 
                        ArrThree, 
                        ArrFour, 
                        ArrFive, 
                        ArrSix, 
                        ArrSeven, 
                        ArrEight, 
                        ArrNine, 
                        ArrTen, 
                        ArrEleven
                    }
                })
            );
        }
    
    }

The compiler is giving the following error:

Type 'Observable<{ ArrOne: ArrOne[]; ArrTwo: ArrOne[]; ArrThree: ArrOne[]; ArrFour: ArrOne[]; ArrFive: ArrOne[]; ArrSix: ArrOne[]; ArrSeven: ArrOne[]; ArrEight: ArrOne[]; ArrNine: ArrOne[]; ArrTen: ArrOne[]; ArrEleven: ArrOne[]; }>' is not assignable to type 'Observable'. Type '{ ArrOne: ArrOne[]; ArrTwo: ArrOne[]; ArrThree: ArrOne[]; ArrFour: ArrOne[]; ArrFive: ArrOne[]; ArrSix: ArrOne[]; ArrSeven: ArrOne[]; ArrEight: ArrOne[]; ArrNine: ArrOne[]; ArrTen: ArrOne[]; ArrEleven: ArrOne[]; }' is missing the following properties from type 'ReferenceData': observableOne, observableTwo, observableThree, observableFour, and 7 more.

It's strange because if I reduce the number of observables to six and delete the corresponding values from the ReferenceData interface, the compiler doesn't throw this error.

Any ideas?

CodePudding user response:

[
                    ArrOne, 
                    ArrTwo, 
                    ArrThree, 
                    ArrFour, 
                    ArrFive, 
                    ArrSix, 
                    ArrSeven, 
                    ArrEight, 
                    ArrNine, 
                    ArrTen, 
                    ArrEleven
                ]
this is an array of type `ArrOne[] | ArrTwo[] | ArrThree[] | ArrFour[] | ArrFive[] | ArrSix[] | ArrSeven[] | ArrEight[] | ArrNine[]` and you cannot just say that `Apple | Pear` is `Apple` only the other way round.

So you need to:
    return {
                        ArrOne as ArrOne[], 
                        ArrTwo as ArrTwo[],  
                        ...
                    }

CodePudding user response:

RxJS combineLatest also has another overload where you can pass in an object, which would let you skip the map too:

        this.referenceData$ = combineLatest({
            ArrOne: this.observableOne$, 
            ArrTwo: this.observableTwo$, 
            ArrThree: this.observableThree$, 
            ArrFour: this.observableFour$, 
            ArrFive: this.observableFive$, 
            ArrSix: this.observableSix$, 
            ArrSeven: this.observableSeven$, 
            ArrEight: this.observableEight$, 
            ArrNine: this.observableNine$, 
            ArrTen: this.observableTen$, 
            ArrEleven: this.observableEleven$
        });

Maybe this one works better. It could be the array one doesn't work because TS might have a limit on how many values it can infer from a tuple.

CodePudding user response:

You can find the solution an the end of the error msg

is missing the following properties from type 'ReferenceData': observableOne, observableTwo, observableThree, observableFour, and 7 more.

The problem is that in ReferenceData you have defined the properies names as observableOne, observableTwo,...

interface ReferenceData {
    observableOne: ArrOne[];
    observableTwo: ArrTwo[];
    ...
}

But in the map you are returning an object with properties named as ArrOne, ArrTwo,...

So you either change the mapping function so the returned properties names match the interface.

.pipe( 
  map(([observableOne, observableTwo,...]) => 
    ({observableOne, observableTwo,...})
  )
)

Or you use directly the object parameter signature of combineLatest

this.referenceData$ = combineLatest({
  observableOne: this.observableOne$, 
  observableTwo: this.observableTwo$,
  ...
});
                    

Cheers

  • Related