I am currently working on an Angular 9 application that heavily relies on observables. In a specific component, I have the following requirements:
- Retrieve all companies to access certain information.
- Fetch all responses and link additional company details (such as the company name) to each response.
- Return this compiled list as an observable and subscribe to it in the template using the async pipe.
To achieve this, I initially wrote the following code snippet (which seems to be functioning correctly):
getPopulatedResponses(): Observable<ResponseModel[]> {
return this.companyFilesStore
.select(companyFilesSelector)
.pipe(
switchMap(companies => {
return this.getAccessibleResponses(companies);
})
)
}
getAccessibleResponses(accessibleCompanies: CompanyFilesModel[]): Observable<ResponseModel[]> {
return this.responsesStore
.select(responsesSelector)
.pipe(
map((responses) => {
return responses?.map((response) => {
const company = accessibleCompanies?.find(c => c.companyGuid === response.companyId);
response.companyName = company?.companyName;
return response;
}).sort((a, b) => {
return a.completedDateTime < b.completedDateTime ? 1 : -1;
})
})
)
Initially, I was uncertain if switchMap was the correct operator since I was unsure if updating the companyFilesSelector would terminate the previous subscription when responsesSelector started executing.
Now, I also need to include a subscription to a filter service. I made some modifications to the getAccessibleResponses method which seem to be functioning, but I feel like it might be more of a coincidence than deliberate design:
getAccessibleResponses(
accessibleCompanies: CompanyFilesModel[],
): Observable<ResponseModel[]> {
return this.searchAndFilterService.getFilter()
.pipe(
switchMap(filter => {
return this.responsesStore
.select(responsesSelector)
.pipe(
map((responses) => {
return responses?.map((response) => {
const company = accessibleCompanies?.find(c => c.companyGuid === response.companyId);
response.companyName = company?.companyName;
return response;
})
?.filter(r => !r.isArchived)
?.filter(r => !filter?.selectedCompany || r.companyId === filter.selectedCompany.companyId)
?.filter(r => !filter.selectedAssessmentTemplate ||
r.assessmentTemplateId === filter.selectedAssessmentTemplate.assessmentTemplateId)
.sort((a, b) => {
return a.completedDateTime < b.completedDateTime ? 1 : -1;
})
})
)
})
)
}
I am aware that my current approach may not be optimal or accurate. I am finding it difficult to grasp how to accomplish the following objectives:
- Retrieve all companies initially.
- Combine data from the companies observable with the responses.
- Apply filters when the filter service observable is updated to refine the combined results of steps 1 and 2.
I would greatly appreciate any assistance or advice on how to improve this process.