Skip to content

Instantly share code, notes, and snippets.

@toverux
Last active September 17, 2018 09:14
Show Gist options
  • Save toverux/c40f8ae053db01c65ae35de69ef54617 to your computer and use it in GitHub Desktop.
Save toverux/c40f8ae053db01c65ae35de69ef54617 to your computer and use it in GitHub Desktop.
/**
* Fetches and constructs the breadcrumb of modules, starting from the last opened on the stack (startModuleId),
* tracing back to the root module, thanks to each module's parentId.
*
* @param startModuleId The last module you want to be opened in the breadcrumb.
*/
private fetchModules(startModuleId: AuditModule['_id']): Observable<AuditModule[]> {
//=> Each time we need to fetch a new module, we emit the wanted module id on this subject
const fetchIdSubject = new BehaviorSubject(startModuleId);
return fetchIdSubject.pipe(
//=> Fetch each module corresponding to this id
mergeMap(id => this.auditModuleQuery(id).valueChanges.pipe(
//=> Wait for data and map on it..
filter(({ data }) => !!data),
map(({ data }) => data.auditModule),
//=> If that's not the root module yet, emit the parentId on the source subject, so it's loaded next
tap(module => module.parentId && fetchIdSubject.next(module.parentId)))),
//=> Update the breadcrumb state
scan(updateBreadcrumb, []),
//=> Begin by emitting an empty breadcrumb before the first module is loaded
startWith([]));
function updateBreadcrumb(breadcrumb: AuditModule[], module: AuditModule): AuditModule[] {
breadcrumb = [...breadcrumb];
const currentIndex = breadcrumb.findIndex(candidate => candidate._id == module._id);
const childIndex = breadcrumb.findIndex(candidate => candidate.parentId == candidate._id);
const replace = currentIndex >= 0;
breadcrumb.splice(replace ? currentIndex : childIndex, replace ? 1 : 0, module);
return breadcrumb;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment