Search code examples
angularfirebaserecursionrxjsangularfire2

Angularfire2 Observable Recursion


I am attempting to create a "breadcrumbs" list by looping through documents and grabbing their parents. My data structure looks like so:

storage-unit:

  • parent: DocumentRef to another storage unit.

I am attempting to make an array of a single unit's tree of parents. I'm trying to use recursion, as I would assume that's the easiest way of doing it. I know without observables, it would be something like the following:

// Unit is an observable returned by valueChanges()
recurseParents(unit){
  if (unit === null) {
    return;
  }
  // Titles array defined onInit in Angular
  this.titles = [...unit, this.titles];
  recurseParents(this.unitService.getUnitById(unit.parent));
}

With Angularfire2's observables, I'm not sure how to accomplish this. I tried doing the same-ish steps within a subscribe, and it produced odd behavior at times, even doing .take(1) before calling subscribe.

The end goal is to look like this:

[{root parent}, {sub parent 1}, {sub parent 2}, {original document}]

Solution

  • You can use the .expand() operator, and it is just a one liner:

    expand(unit => unit === null ? empty() : this.unitService.getUnitById(unit.parent))
    

    Note: empty() returns an observable that is empty and terminate the stream immediately.

    So you can just do something along the lines:

    let rootDoc$ = of(this.titles) //assign to the observables of your DocumentRef
    
    rootDoc$
        .pipe(
            expand(unit => unit === null ? empty() : this.unitService.getUnitById(unit.parent))
        )
        .subscribe(unitValues => {
            this.titles = [...unitValues, this.titles];
        })