How to perform operations on 2 separate data collections in 1 function in RxJS so that it returns observable -> as for now it returns Void ? This function is running inside Service of course, and finally I want to subscribe to it in my component.
I assume it requires refactoring, I’m still learning RxJS 🙂
My attempt (it does not work):
https://pastecode.io/s/m1g7a861
// use interface instead class for TS
export interface Task {
goal_id: string;
name: string;
description: string;
priority: string;
taskDate: string;
id: string; // key collection
}
// Base Goal Model
export interface Goal {
name: string;
isMainGoal: boolean;
details: string;
category: string;
lifeArea: string;
creationDate: string;
priority: string;
endDate: Date;
id: string;
}
class MyService {
getTasksByCategory(category:string):Observable<any> {
const daysFromThisWeek = this.getDaysFromThisWeek();
return forkJoin({
tasks: this.tasksS.tasksCollection(),
goals: this.goalsS.goalsCollection(),
})
// !!! OPERATIONS ON GOALS !!!
.pipe(
// filter goals with category from parameter
map(({ tasks, goals }) => {
return goals.filter((item:any) => item.category === category);
}),
// get ID's of found goals in the previous step
map((goals:any) => {
const goalsIDs = goals.map((item:any) => item.id);
return goalsIDs;
})
)
// !!! OPERATIONS ON TASKS !!!
.pipe(
// get IDs-matching-tasks
map(({ tasks, goalsIDs }) => {
let modArr = [] as any;
goalsIDs.forEach((goalId:any) => {
const forModArr = tasks.filter((task:any) => task.goal_id === goalId);
modArr = modArr.concat(forModArr);
})
return modArr;
}),
map(tasksArr => {
// get number of IDs-matching-tasks on each week day
let finalTasks = [] as any;
daysFromThisWeek.forEach((day:any) => {
const forFinalTasks = tasksArr.filter((task:any) => task.taskDate === day);
finalTasks = finalTasks.concat(forFinalTasks.length);
})
return finalTasks;
})
)
}
getDaysFromThisWeek() {
let daysArr = [];
for(let i=1; i<=7; i++) {
daysArr.push(dayjs().startOf('week').add(i, "day").format('YYYY-MM-DD'));
}
return daysArr;
}
}
2
Answers
You’re almost there. You are only returning the
goalsIDs
from the firstpipe
, so the input for the secondpipe
do not get thetasks
emissions. Also as mentioned in the comments, having multiplepipe
s to the same input observable isn’t different from having a singlepipe
containing all operators.Instead of performing the
map
opearations ofthis.goalsS
observable after theforkJoin
, perform it before. Then you could use thegoalIds
to filter the emission oftasksS
observable.Also I’m certain the filtering operations on tasks emissions could be done better, but I’ll leave that to you.
Try the following
Edit: Added brief info about error in OP’s code
Your first map is actually removing the
tasks
result. Instead, do something like this:You may even merge those