title: How to run functions sequentially in Angular 2/4 Typescript
body: <p>I am having trouble trying to run functions sequentially in my Angular 2/4 project.</p>
  
  <p>I have <code>retrieveData()</code> function that retrieves data from data service and assigns them into an array that I declared.</p>
  
  <p>Then I have <code>displayData()</code> function that uses the data stored in the array and display them in a chart.</p>
  
  <p>When I try to run them, for eg:</p>
  
  <pre><code>function(){
    this.retrieveData();
    this.displayData();
  }
  </code></pre>
  
  <p><code>displayData()</code> function runs first before <code>retrieveData()</code> mainly because of the data service in the <code>retrieveData()</code> function. Therefore the graph cannot be displayed properly.</p>
  
  <p>One of the ways that I found that I can run functions sequentially is <code>async.waterfall</code> from <code>async</code> library but I am having trouble importing the library into my project, with the console log saying: 
  <code>Uncaught Error: Unexpected value 'waterfall' imported by the module 'AppModule'. Please add a @NgModule annotation.</code></p>
  
  <p>I don't want to use Promises and Observables because they require the initial function to have some kind of return value to pass on to the next functions. I somewhat managed to achieve it using <code>setTimeOut()</code> function but I really doubt the reliability and robustness of the approach.</p>
  
  <p>So, any help with the use of <code>async</code> in Angular 2/4, or any kind of ways to make the functions wait without any kind of return promises?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Sorry for the confusion and inconvenience caused guys. I was posting and asking for an over-simplified version. Here is the more complete part of my code. I am an Angular and Typescript noob, and more noob when it comes to Async programming techniques.  </p>
  
  <p>Below is my implementation of promises in <code>retrieveAllData()</code> method. It doesn't give any error in either compile time or runtime. But when the functions are still running asynchronously, i.e. <code>refreshAllCharts()</code> still runs before <code>retrieveAllData()</code>. Is there any flaws in my implementation of promises?</p>
  
  <pre><code>import { Component, OnInit, AfterContentInit } from '@angular/core';
  import { DataService } from '../data.service';
  import {BaseChartDirective} from 'ng2-charts/ng2-charts';
  import {IMyDpOptions,IMyDateModel} from 'mydatepicker';
  
  //import {MomentTimezoneModule} from 'angular-moment-timezone';
  import * as moment from 'moment-timezone';
  
  // import async from 'async-waterfall';
  
  @Component({
    templateUrl: 'chartjs.component.html'
  })
  export class ChartJSComponent {
  
    tempArr = []; //array to store temperature values for the chart
    timeTempArr = []; //array to store timestamps for the chart label
  
    device = "1CB001"; //a parameter used for the data service method to query the database
  
    dateSelected; //variable to store the date chosen from the datepicker on the html side of the component
  
    constructor(private dataService: DataService){
    }
  
    ngOnInit(){
    }
  
  //function to retrieve temperature values and assign them into "tempArr" array
    retrieveTempDataAssign(){
      var _arr = new Array();
  
      this.dataService.getData(this.device, this.dateSelected).subscribe(response =&gt; {
  
        console.log("Response: " + JSON.stringify(response));
        for(var item of response){
          _arr.push(item.Temperature);
        }
  
        this.tempArr = _arr;
        console.log("Array assigned Temp: " + this.tempArr);
      });
  
      this.retrieveTempTimeDataAssign();
  
    }
  
  //function to retrieve time values and assign the date and time objects into "timeTempArr" array
    retrieveTempTimeDataAssign(){
  
      var _arr = new Array();
  
      this.dataService.getData(this.device, this.dateSelected).subscribe(response =&gt; {
  
        for(var item of response){
          // var value = "'" + item.Date + "'";
          // _arr.push(value);
  
          var value = item.Date;
          var time = moment.tz(value, "Asia/singapore");
          _arr.push(time);
        }
        this.timeTempArr = _arr;
        console.log("Array assigned Time: " + this.timeTempArr);
      });
    }
  
  //function to refresh the whole of Temperature chart
    refreshTempChart(){
      this.showTempData();
      setTimeout(() =&gt; this.showTempLabels(), 500);
    }
  
  //function to assign the "tempArr" array into the dataset for the temperature chart
    showTempData(){
      console.log("To display: " + this.tempArr);
      this.datasetsTemp = [{
        label: "Values",
        data: this.tempArr
      }];
    }
  
  //function to assign the "timeTempArr" array into the labels for the temperature chart
    showTempLabels(){
      console.log("To label: " + this.timeTempArr);
      this.labels = this.timeTempArr;
    }
  
  //date picker format
    private myDatePickerOptions: IMyDpOptions = {
          dateFormat: 'yyyy-mm-dd',    
    };
  
  //change event listener on the datepicker
    onDateChanged(event: IMyDateModel){
  
      this.dateSelected= event.formatted;
      console.log("Selected Date: " + this.dateSelected);
  
  //**The implementation part**
      this.retrieveAllData().then(()=&gt;{
        this.refreshAllCharts();
      })
  
    }
  
  //to run all functions to retrieve respective data
    retrieveAllData(){
      return new Promise((resolve, reject) =&gt; {
        this.retrieveTempDataAssign(); //assign the retrieved values into the array first
  
        return true;
      });
    }
  
  //to run all functions to update all the charts
    refreshAllCharts(){
      this.refreshTempChart();
    }
  
  //objects used by the chart to display data
    private datasetsTemp = [
      {
        label: "Values",
        data: []
      }
    ];
  
    private labels = [];
  
    private options = {
      scales: {
        xAxes: [{
            display: true,
            type: "time",
            time: {
                unit: "hour",
                tooltipFormat: 'YYYY-MM-DD hh:mm A'
            },
            scaleLabel: {
                display: true,
                labelString: 'Time'
            }
        },],
        yAxes: [{
          ticks: {
            beginAtZero: false
          }
        }]
      }
    };
  }
  </code></pre>