In my angular form I have some collection type properties. The properties are given below:
countries: CountryInfo[] = [];
floorLists: VariableInfo[] = [];
memberTypes: VariableInfo[] = [];
memberCategories: VariableInfo[] = [];
businessTypes: VariableInfo[] = [];
voterRelations: VariableInfo[] = [];
bloodGroups: VariableInfo[] = [];
designations: VariableInfo[] = [];
Now I have used forkJoin operator to call service to populate the above properties with data. But it seems that whenever I put more than 6 parameters in forkJoin operator with different types, the operator shows an error. Below is the code
let countries$ = this.countryService.getCountryLists();
let floors$ = this.variableService.getFloorLists();
let memberTypes$ = this.variableService.getMemberTypeLists();
let categories$ = this.variableService.getMemberCategoryLists();
let businessTypes$ = this.variableService.getBusinessTypeLists();
let voterRelations$ = this.variableService.getVoterRelationLists();
let bloodGroups$ = this.variableService.getBloodGroupLists();
let designations$ = this.variableService.getDesignations();
forkJoin([countries$, floors$, memberTypes$, categories$, businessTypes$, voterRelations$, bloodGroups$, designations$]).subscribe(data => {
this.countries = data[0];
this.floorLists = data[1];
this.memberTypes = data[2];
this.memberCategories = data[3];
this.businessTypes = data[4];
this.voterRelations = data[5];
this.bloodGroups = data[6];
this.designations = data[7];
});
It shows the below errors.
TS2322: Type 'CountryInfo[] | VariableInfo[]' is not assignable to type 'CountryInfo[]'. Type 'VariableInfo[]' is not assignable to type 'CountryInfo[]'. Type 'VariableInfo' is missing the following properties from type 'CountryInfo': Name, Flag, Code
217 this.countries = data[0]; ~~~~~~~~~~~~~~
This is because data inside subscribe() is of type Array<CountryInfo[] | VariableInfo[]>. So referring to the array with the index data[i] infers the type CountryInfo[] | VariableInfo[], hence the error.
You can use array destructuring to have more specific types, which should fix the error.
forkJoin([countries$, floors$, memberTypes$, categories$, businessTypes$, voterRelations$, bloodGroups$, designations$])
.subscribe(([countries, floors, memberTypes, categories, businessTypes, voterRelations, bloodGroups, designations]) => {
this.countries = countries;
this.floorLists = floors;
this.memberTypes = memberTypes;
this.memberCategories = categories;
this.businessTypes = businessTypes;
this.voterRelations = voterRelations;
this.bloodGroups = bloodGroups;
this.designations = designations;
});
I think you can achieve that using another overload of the forkJoin, because the one you're using requires the observable array items to be from the same type.
The following overload should works:
forkJoin({
countries: countries$,
floors: floors$,
memberTypes: memberTypes$,
categories: categories$,
businessTypes: businessTypes$,
voterRelations: voterRelations$,
bloodGroups: bloodGroups$,
designations: designations$,
}).subscribe((data) => {
this.countries = data.countries;
this.floorLists = data.floors;
this.memberTypes = data.memberTypes;
this.memberCategories = data.categories;
this.businessTypes = data.businessTypes;
this.voterRelations = data.voterRelations;
this.bloodGroups = data.bloodGroups;
this.designations = data.designations;
});
ForkJoin with a Dictionary instead of an ArrayPositional arguement in an array are fairly error-prone. ForkJoin lets you solve this problem and the problem with types in one fell swoop. As long as the keys match, you can re-order the inputs without fear. It also stops you from re-typing the names over and over and over again.
forkJoin({
countries: this.countryService.getCountryLists(),
floorLists: this.variableService.getFloorLists(),
memberTypes: this.variableService.getMemberTypeLists(),
memberCategories: this.variableService.getMemberCategoryLists(),
businessTypes: this.variableService.getBusinessTypeLists(),
voterRelations: this.variableService.getVoterRelationLists(),
bloodGroups: this.variableService.getBloodGroupLists(),
designations: this.variableService.getDesignations()
}).subscribe(data => {
for (const [key, value] of Object.entries(data)) {
this[key] = value;
}
});
Of course, the obj here can be pulled out of the forkjoin and built (incrementally or otherwise) elsewhere. In this case make sure you type "callListType" properly somewhere so your code knows what to expect (Is voterRelations an optional field are there numerous types at play?)
let callList: callListType = {
countries: this.countryService.getCountryLists(),
floorLists: this.variableService.getFloorLists(),
memberTypes: this.variableService.getMemberTypeLists(),
memberCategories: this.variableService.getMemberCategoryLists(),
businessTypes: this.variableService.getBusinessTypeLists()
}
callList = {...callList, voterRelations: this.variableService.getVoterRelationLists()};
callList.bloodGroups = this.variableService.getBloodGroupLists();
callList["designations"] = this.variableService.getDesignations();
forkJoin(callList).subscribe(data => {
for (const [key, value] of Object.entries(data)) {
this[key] = value;
}
});