Reputation: 1130
I'm trying to instantiate a controller, passing arguments using a "resolve" object. Here is the syntax :
{
controller: 'HtmlModalController',
resolve: {
myarg: function() {
return "FOO";
}
}
}
This will cause my controller to have " myarg" variable injected as argument with value "FOO".
Now, this syntax also supports promises, which will be automatically resolved when instantiating the controller.
resolve: {
myarg: function() {
// Does the same as above (auto-resolved promise)
return $q.when("FOO");
}
}
Now, the question is : How can I inject a promise into the controller ? I don't want the promise to be resolved as I will resolve it once the controller is loaded. I tried to nest multiple promises, but they are all resolved back to the "FOO" value once in the controller.
resolve: {
myarg: function() {
// All promises are resolved for me :'(
return $q.when($q.when("FOO"));
}
}
My only solution for now is to wrap the promise into a function/object :
resolve: {
myarg: function() {
// So in my controller I can do "myarg.promise.then(...)"
return {promise: $q.when("FOO")};
}
}
I know this is a non-blocking detail, but I wonder if there is a way to properly resolve a promise "as a promise".
Thanks =)
Upvotes: 3
Views: 1473
Reputation: 12193
One pattern you can use is a service that provides the promise and caches it internally.
function MyService() {
var promise;
this.getSomePromise = function() {
if(!promise) {
promise = $q.when(...); // whatever produces your promise
}
return promise;
}
}
myModule.service('myService', MyService);
You can then depend on this service in your controller:
myModule.controller('MyController', function(myService) {
myService.getSomePromise().then(result => ...);
});
As well as using it to block your resolve:
resolve: {
/**
* Note: we are not actually injecting this.
* Only using it to block the route. The name blocker is arbitrary and could be anything.
*/
blocker: function(myService) {
return myService.getSomePromise();
}
}
This allows you to hook up as many then handlers as you want to the service method while ensuring only 1 call to the underlying asynchronous operation and 1 promise instance.
Upvotes: 0
Reputation: 276286
There is no way to resolve with a promise without it being implicitly recursively unwrapped to the final value. Resolving with a promise will always resolve with the promise's result and not with the promise itself.
The only option would be to pass a wrapper like you have done with {p: promise }
and no then
method.
Upvotes: 2