title: Angular 5: Returning an Observable from a function
body: <p>In the old days, I would define a new <code>Promise</code>, defer it, then resolve it when my function completed.
  Now I find myself in a situation where I need to return an <code>Observable</code> from a function, and I want to be sure I'm setting it up properly in an <code>Angular 5</code> context.</p>
  
  <p>Test function, working fine:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>getTreeViewChildren(currNode: any, nodeType: string, nodeTypeEnum: number = 0, nested: boolean = true)
                    : Observable&lt;any&gt; 
  {
  
  let treeObs: Observable&lt;any&gt;;
  
  treeObs = new Observable(obs =&gt; {
  
   this.siteConfigService.getHostAccessPoints().subscribe(data =&gt; {
    let hostAccessPoints = JSON.parse(data);
    let accPointTree = this.findChildNodes(currNode, hostAccessPoints, nested);
    obs.next(accPointTree);
    obs.complete(); 
   });  
   
  }); 
  return treeObs;
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p>and from my NG component I successfully subscribe:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>this.configService.getTreeViewChildren(this.selectedTreeViewItem, type, nodetype, true).subscribe(tree =&gt;{
   let theTree = tree;
   }); </code></pre>
  </div>
  </div>
  </p>
  
  <p>However the real function has much more retrieval logic. What is the correct way to setup the <code>Observable</code> as per my test function above? Same exact pattern, just wrapping all the code within <code>treeObs = new Observable(..)</code> ?</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>getTreeViewChildNodes(currNode: any, nodeType: string, nodeTypeEnum: number = 0, nested: boolean = true): Observable&lt;any&gt; {
   let hosts;
   let locations;
   let hostAccessPoints;
   let treeResult: Observable&lt;any&gt;;
  
   if (nodeTypeEnum === NodeType.Location) {  
    // more code..
    let someTree = getStuff();
    return someTree;
   }
  
   if (nodeTypeEnum === NodeType.Host) {
    // more code..
    let someTree = getStuff();
    return someTree;
   }
  
   if (nodeTypeEnum === NodeType.HostAccessPoint) {
    let accPointTree;
    if (sessionStorage["hostAccessPoints"]) {
     // more code..
     let someTree = getStuff();
     return someTree;
    }
    else {
     this.siteConfigService.getHostAccessPoints().subscribe(data =&gt; {
      // more code..
      let someTree = getStuff();
      return someTree;
     });   
    }
   }
  
   if (nodeTypeEnum === NodeType.HostStorage) {
    // TO DO
   }  
    }</code></pre>
  </div>
  </div>
  </p>
  
  <p>**** UPDATED (Based <code>Observable.of()</code> suggested answer below):</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>// Builds hierarchical treeview data
    getTreeViewChildNodes(currNode: any, nodeType: string, nodeTypeEnum: number = 0, nested: boolean = true): Observable&lt;any&gt; {
   let hosts;
   let locations;
   let hostAccessPoints;
  
   
   if (nodeTypeEnum === NodeType.Location) {
    if (sessionStorage["locations"] != null &amp;&amp; sessionStorage["locations"] != "undefined") {   
     locations = JSON.parse(  sessionStorage.getItem('locations') );
    }
    // find child nodes
    let locationTree = this.findChildren(currNode, locations, nested);     
    return Observable.of(locationTree);
   }
  
   if (nodeTypeEnum === NodeType.Host) {
    if (sessionStorage["hosts"] != null &amp;&amp; sessionStorage["hosts"] != "undefined") {   
     hosts = JSON.parse(  sessionStorage.getItem('hosts') );
    }
    // find child hosts for current node
    let hostTree = this.findChildHosts(currNode, hosts, nested);  
    return Observable.of(hostTree);
   }
  
   if (nodeTypeEnum === NodeType.HostAccessPoint) {
    let accPointTree;
    if (sessionStorage["hostAccessPoints"]) {
     hostAccessPoints = sessionStorage.getItem("hostAccessPoints");
     accPointTree = this.findChildHostAccessPoints(currNode, hostAccessPoints, nested);   
     return Observable.of(accPointTree);
    }
    else { // **** THREW ERROR FROM CALLER 'Cannot read property 'subscribe' of undefined****`
     /*this.siteConfigService.getHostAccessPoints().subscribe(data =&gt; {
      hostAccessPoints = JSON.parse(data);
      accPointTree = this.findChildHostAccessPoints(currNode, hostAccessPoints, nested);    
      return Observable.of(accPointTree);
     });*/   
                  // ** CORRECTED CODE **
                  return this.siteConfigService.getHostAccessPoints().map(data =&gt; {
      hostAccessPoints = JSON.parse(data);
      accPointTree = this.findChildHostAccessPoints(currNode, hostAccessPoints, nested);    
      return accPointTree;
     });      
        
    }
   }
    }</code></pre>
  </div>
  </div>
  </p>
  
  <p>and from my component code, it throws an error <code>TypeError: Cannot read property 'subscribe' of undefined</code> only where I call my service which in turn calls http.get():</p>
  
  <pre><code> this.configService.getTreeViewChildNodes(this.selectedTreeViewItem, type, nodetype, true).subscribe(data =&gt; {
          this.rebuildNetworkTree(data);
      });
  </code></pre>