title: Flatten Synchronous Angular Promises
body: <p>How can I run a series of promises synchronously such that the second promise is not executed until the first one is done?  Here I'm loading three chunks of data, each 10 clients long, then loading the rest.  The idea here is that go ahead and display the first N clients while the rest are loading.</p>
  
  <p>What I don't want is to have to explicitly say processChunk1().then(() => processChunk2()) etc. like I have below.  I want it to process the chunks in a loop until there are no more clients left.  Any help would be appreciated!</p>
  
  <pre><code>loadPerformanceDtos(): ng.IPromise&lt;{}&gt; {
      var deferred = this.$q.defer();
      var clientList: any = [];
  
      $.extend(clientList, this.$location.search().client);
  
      // If the user only searched for one client, we need to turn it into an array
      if (!angular.isArray(clientList)) {
          clientList = [clientList];
      }
  
      var that = this;
  
      // Sort so we can chunk it
      var sortedClients: string[] = (&lt;string[]&gt;clientList).sort();
      const chunkSize: number = 10;
  
      // Reset page's data
      this.performanceDtoModels = [];
  
      // Set up three chunks to load in order
      var chunk1: string[] = sortedClients.splice(0, chunkSize);
      var chunk2: string[] = sortedClients.splice(0, chunkSize);
      var chunk3: string[] = sortedClients.splice(0, chunkSize);
  
      // I don't want to have to explicitly define the groups below, I want this to be in a loop
      processChunk(chunk1).then(() =&gt; {
          // Resolve the inital page's progress bar
          deferred.resolve();
  
          processChunk(chunk2).then(() =&gt; {
              processChunk(chunk3).then(() =&gt; {
                  processChunk(sortedClients);
              });
          });
      });
  
      function processChunk(chunk: string[]) {
          var chunkDeferred = that.$q.defer();
          if (chunk.length === 0) {
              chunkDeferred.resolve();
          } else {
              that.performanceService.loadPerformanceData(chunk)
                  .success((data: IPerformanceDtoModel[]) =&gt; {
                      data.forEach((item: IPerformanceDtoModel) =&gt; {
                          // Add the final item to the page
                          that.performanceDtoModels.push(item);
                      });
  
                      chunkDeferred.resolve();
                  });
          }
          return chunkDeferred.promise;
      }
  
      return deferred.promise;
  }
  </code></pre>