Pete Pete - 11 days ago 5
AngularJS Question

Returning a $promise from two resource calls in AngularJS to delay route change

Use Case



Using a route provider, returning a $promise in the resolve will avoid the data popping up after the UI has loaded. However, I'm having trouble processing two different resource calls and returning it as a single array.

Current Implementation



The current implementation works, but requires that the controller requires two resources.

var app = angular.module('app', []);

app.config(function($routeProvider) {
$routeProvider
.when('/resource/:id', {
templateUrl: 'partials/resource.html',
controller: ResourceController,
resolve: {
parentResource: function($route, SingleResource) {
return SingleResource.get({ id: $route.current.params.id }).$promise;
},
childResources: function($route, ChildResource) {
return ChildResource.get({ id: $route.current.params.id }).$promise;
}
}
});
});


However, what I'd like to do is provide
ResourceController
with a single array
Resource
that is an array composed of
parentResource
and
childResource
where item 0 in the array is the
parentResource
.

Idea



This is what I have in mind, but I don't know what to return in the resolve? If I return result, the route will change and pass an empty array.

var app = angular.module('app', []);

app.config(function($routeProvider) {
$routeProvider
.when('/resource/:id', {
templateUrl: 'partials/resource.html',
controller: ResourceController,
resolve: {
Resource: function($route, SingleResource) {
var resources = [];
SingleResource.get({ id: $route.current.params.id })
.$promise.then(function(parent)
{ resources.splice(0, 0, parent); })
.catch(function(error) { alert('error!'); })
ChildResource.get({ id: $route.current.params.id })
.$promise.then(function(children)
{ resources = resources .concat(children); })
.catch(function(error) { alert('error!'); })

return ???? // Can I return a $promise here?
}
}
});
});


Question



How can I get my ResourceController signature from
The idea is then to get the controller to have this signature:

var ResourceController = function($scope, parentResource, childResources) { ... }


to

var ResourceController = function($scope, resources) { ... }


through returning $promise?

Answer

You can use $q.all to return an array of promises

var resources = [];

resources.push(SingleResource.get({ id: $route.current.params.id }).$promise);
resources.push(ChildResource.get({ id: $route.current.params.id }).$promise);

return $q.all(resources) // You return an array of promises