title: Angular 4 loading tree structure in recursive observable calls
body: <p>Hi I'm pretty new to Observables and I'm looking for a way of loading my navigation tree with recursive observable calls. 
  The Navigation should be build up dynamically base on all the <code>index.json</code>files in the directory and sub directories.</p>
  
  <blockquote>
    <p>Only the url of the first call is static: <code>/public/index.json</code></p>
  </blockquote>
  
  <p>This is the directory structure. Each directory may contain a <code>index.json</code>,
  providing information about its content and may references to other index files via the <code>loadChildrenFromUrl</code> property.</p>
  
  <pre><code>|-public
     |- subdir1
         |- index.json
         |- test.html
     |- subdir2  
         |- index.json
         |- test.html
         |- subdir2.1  
             |- index.json
             |- . . .
     |- index.json
  </code></pre>
  
  <p>Navigation file <code>index.json</code></p>
  
  <pre class="lang-json prettyprint-override"><code>[
    // static entry with static children
    {
      "state": "module1",
      "name": "Modul 1",
      "type": "sub",
      "icon": "dashboard",
      "children": [
         {"state": "", "name": "Index", "icon": "https" },
         {"state": "test1", "name": "Test1", "icon": "live_help"}
      ]
   },
   {
     // dynamic entry children needs to be load from url
     "state": "test",
     "name": "Test loaded from url",
     "type": "sub",
     "icon": "info_outline",
     "loadChildrenFromUrl": "subdir2/index.json"
     "children": [] // should be loaded via url
    },
    . . .
  ]
  </code></pre>
  
  <p>The result should be one large object describing the whole navigation tree.
  So Children may contain children may contain children... .
  A Router-Guard (<code>CanActivate returning Observable</code>) will take care to wait until loading the tree has finished.</p>
  
  <p>My code is working but the function returns before the whole tree is loaded.
  I know the whole thing is async so this is by design but I've no idea how to solve it right. Looks like I've to use flatMap?</p>
  
  <p>NavigationService.ts</p>
  
  <pre class="lang-js prettyprint-override"><code>loadNavigation(): Observable&lt;Menu[]&gt; {
      if (this.navigationLoaded) {
        return Observable.of(this.navigationTree);
      } else {
        this.navigationTree = new Array();
        return this.loadNavigationByUrl('public', this.navigationTree);
  
      }
  }
  
  loadNavigationByUrl(url: string, navArray: Menu[]): Observable&lt;Menu[]&gt; {
  
      console.log(`Loading ${url}/index.json`);
  
      const result = this.http.get&lt;Menu[]&gt;(`${url}/index.json`, { responseType: 'json' });
      result.catch((err) =&gt; this.handleError(err));
      result.subscribe(data =&gt; {
  
        // console.log(data);
        if (data) {
  
          data.forEach((item: Menu, index: number, array: Menu[]) =&gt; {
  
            // add to navigationTree
            navArray.push(item);
  
            if (item.loadChildrenFromUrl &amp;&amp; item.loadChildrenFromUrl !== '') {
              item.children = new Array();
              this.loadNavigationByUrl(`${url}/${item.loadChildrenFromUrl}`, item.children);
            }
  
            // console.log(this.navigationTree);
          });
  
          // this.navigationTree = data;
          console.log('navigation loaded');
          this.navigationLoaded = true;
        }
      },
      err =&gt; {
  
      },
      () =&gt; {
        console.log(`Loading ${url}/index.json completed`);
      }
      );
  
      return result;
  
  }
  </code></pre>
  
  <p>So how to construct an observable "chain?" to do this?</p>
  
  <p><strong>new info 2017-12-01</strong></p>
  
  <p>At the end I need to use this function in a <code>Route Guard</code> so navigation structure gets loaded before route gets active.</p>
  
  <p>NavigationGuard.ts</p>
  
  <pre class="lang-js prettyprint-override"><code>@Injectable()
  export class NavigationGuard implements CanActivate, CanActivateChild  {
  
    constructor(private svc: NavigationService, private router: Router) { }
  
    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable&lt;boolean&gt; | Promise&lt;boolean&gt; | boolean {
      // console.log('canActivate');
      return this.svc.loadNavigation()
        .mapTo(true) // I'm not interested in the result
        .catch((error: any) =&gt; {
          console.log(error);
          return Observable.of(false);
        });
  
    }
  
    canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):  Observable&lt;boolean&gt; | Promise&lt;boolean&gt; | boolean {
      return this.canActivate(route, state);
    }
  }
  </code></pre>