Structure
I have two controllers and one model.
- an order controller that processes one step of the order process
- order navigator controller that only handles order navigation
- An order model that processes all order data.
All information is stored in the order object, depending on which package you have chosen, you get a tab to configure this package.
During navigation through the various stages of the order, the navigation controller always does its job, and the order controller can change in different controllers necessary for the specific configuration step that you are currently using.
Scenario
When loading the first state, initialization of the order controller and initialization of the nav controller. Both calls to the OrderModel.getOrder () method, which is a promise using an http call.
If both controllers are initialized and the promise has not yet been resolved, it raises a double request for api, which, I think, is a bit picky.
Decision
I created a wrapper around the $ q library, which adds a new method, unique.
A unique method is to keep a promise in the model if the promise does not exist, but it creates a new promise, otherwise it returns a promise that is not yet resolved. This prevents multiple http calls.
Question
Since this solution looks so simple and simple, I feel like I'm doing something wrong, what do you guys think about this structure / solution?
Code example:
Controllers getOrder method:
function getOrder (id, force) {
return $q(
function (resolve, reject) {
Orders.getOrder(id, force).then(
function (order) {
vm.order = order;
resolve(order);
},
reject
);
}
);
}
Model getOrder method:
function getOrder (id, force) {
var url = AppConfig.ApiUrl + '/order/' + id;
var promiseUrl = url + '-force-' + force;
return $qPromise.unique(promiseUrl, function (resolve, reject) {
if (!force && model.orders[id]) {
return resolve(model.orders[id]);
}
$http.get(url, { bearer: true }).then(
function (response) {
model.orders[id] = response.data.data;
resolve(model.orders[id]);
},
reject
);
});
}
$q (function() {
angular.module('app').factory('$qPromise', qWrapper);
qWrapper.$inject = ['$q'];
function qWrapper($q) {
var model = {
promises: {}
};
$q.unique = uniquePromise;
return $q;
function uniquePromise (id, cb) {
if (model.promises[id]) {
return model.promises[id];
}
var promise = model.promises[id] = $q(cb);
promise.catch(console.warn);
$q.when(
promise,
function () { delete model.promises[id]; },
function () { delete model.promises[id]; }
);
return promise;
}
}
})();