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