angular-restmod icon indicating copy to clipboard operation
angular-restmod copied to clipboard

Queueing up multiple promises without waiting on last promise result

Open jasonayre opened this issue 9 years ago • 0 comments

Hi,

I have some code that I thought was working, but realized it was not when I ran multiple server processes, and saw that the requests I was making were dependent on the previous requests to complete. - I can see that the promises are being generated since they are visible in the scope.$pending count, but for some reason, it's not queueing up the actual network request. For example (just going to post the before and after in its entirety):

import _ from 'lodash';

export default /* @ngInject */ function(restmod, $http, RMPackerCache, $q, ProgressBar) {
  return restmod.mixin({
    $extend: {
      Collection: {
        $withBatchesOf(batch_size=25) {
          let batch_collection = this.$type.$collection();
          batch_collection.original_collection = this;
          batch_collection.batches = _.chunk(batch_collection.original_collection, batch_size);
          batch_collection.progress = new ProgressBar(0, batch_collection.batches.length);
          return batch_collection;
        },
        $createAllBatches() {
          let self = this,
              model = this.$type,
              collection_key = model.getProperty('plural'),
              request_url = model.$collectionPath('create_all'),
              batch_promises,
              batch_records,
              request_data,
              request;

          batch_promises = _.map(self.batches, function(batch){
            return self.$action(function(){
              batch_records = _.map(batch, function(record){
                return record.$encode();
              });

              request_data = {};
              request_data[collection_key] = batch_records;

              request = {
                url: request_url,
                method: 'POST',
                data: request_data
              };

              self.$dispatch('before-create-batch', [request]);

              return self.$send(request, function(_response){
                RMPackerCache.prepare();

                var raw = model.unpack(this, _response.data), pk, records;

                self.$decode(raw);
                self.progress.tick();
                self.$dispatch('after-create-batch', []);

                RMPackerCache.clear();
              }).$asPromise();
            });
          });

          return batch_promises;
        }
      }
    }
  })
}

The self.$action and self.$send are where I'm confused. I've tried a combination of doing it with/without one or the other, and with/without explicitly calling $asPromise at the end, but haven't gotten it to work. But from digging around the docs it seems like this is the way I am supposed to do this? The code I have now for comparison (which works but breaks the hook apis/I then don't have access to the collection $pending and $hasPendingActions which other code relies upon), is:

import _ from 'lodash';

export default /* @ngInject */ function(restmod, $http, RMPackerCache, $q, ProgressBar) {
  return restmod.mixin({
    $extend: {
      Collection: {
        $withBatchesOf(batch_size=25) {
          let batch_collection = this.$type.$collection();
          batch_collection.original_collection = this;
          batch_collection.batches = _.chunk(batch_collection.original_collection, batch_size);
          batch_collection.progress = new ProgressBar(0, batch_collection.batches.length);
          return batch_collection;
        },
        $createAllBatches() {
          let self = this,
              model = this.$type,
              collection_key = model.getProperty('plural'),
              request_url = model.$collectionPath('create_all'),
              batch_promises,
              batch_records,
              request_data,
              request;

          batch_promises = _.map(self.batches, function(batch){
            batch_records = _.map(batch, function(record){
              return record.$encode();
            });

            request_data = {};
            request_data[collection_key] = batch_records;

            request = {
              url: request_url,
              method: 'POST',
              data: request_data
            };

            self.$dispatch('before-create-batch', [request]);

            return $http(request).then(function(response){
              RMPackerCache.prepare();

              var raw = model.unpack(self, response.data);

              self.$decode(raw);
              self.progress.tick();
              self.$dispatch('after-create-batch', []);

              RMPackerCache.clear();
            });
          });

          return batch_promises;
        }
      }
    }
  })
}

Which works, but now api's are broken. Can you tell me if I'm doing something obviously stupid and or where I'm going wrong, or if angular-restmod is working as expected in this instance? (Like are collections only supposed to have one active promise going on at the same time?)

jasonayre avatar Jan 14 '16 20:01 jasonayre