У меня есть projectService для извлечения проектов. Каждый проект, в свою очередь, имеет методы для извлечения соответствующих тегов и модулей.
Что я пытаюсь сделать, это заполнить проекты свойств экземпляра: Project [] всеми соответствующими тегами и модулями и, когда все заполнено, вызвать другой метод, который зависит от данных.
Я знаю, что мой подход не работает, потому что моя операция с картой возвращает проекты до того, как наблюдаемые в для l oop завершены, но я понятия не имею, как это сделать правильно.
class ProjectService {
getAll(): Observable<Project[]> {...}
}
class Project {
tagCollection: Tag[];
moduleCollection: Module[];
getTags(): Observable<Tag[]> {...}
getModules(): Observable<Module[]> {...}
}
this.projectService
.getAll()
.pipe(
map(projects => {
for (const project of projects) {
project.getTags().subscribe(tags => {
project.tagCollection = tags;
});
project.getModules().subscribe(modules => {
project.modules = modules;
});
}
return projects;
})
)
.subscribe(projects => {
this.projects = projects;
this.someOtherMethod();
});
Обновление
Я испробовал оба решения и отредактировал их, чтобы сохранить тип проекта и использовать аналогичный стиль кодирования. Оба решения работают и, кажется, делают то же самое в контексте моего проекта. Но я не уверен, какое решение лучше, и если внесенные мной изменения нарушают какие-либо реактивные передовые методы. Кто-нибудь может уточнить это?
Решение 1 от Reqven
this.projectService
.getAll()
.pipe(
switchMap(projects =>
combineLatest(
projects.map(project =>
combineLatest([project.getTags(), project.getModules()]).pipe(
map(([tags, modules]) => {
project.tagCollection = tags;
project.modules = modules;
return project;
})
)
)
)
)
)
.subscribe(projects => {
console.log(projects);
this.projects = projects;
this.someOtherMethod();
});
Решение 2 от NateDev
this.projectService
.getAll()
.pipe(
mergeMap(projects => from(projects)),
mergeMap(project =>
combineLatest([project.getTags(), project.getModules()]).pipe(
map(([tags, modules]) => {
project.tagCollection = tags;
project.modules = modules;
return project;
})
)
),
toArray()
)
.subscribe(projects => {
console.log(projects);
this.projects = projects;
this.someOtherMethod();
});