I'm finding it hard to understand the "deferred antipattern". I think I understand it in principal but I haven't seen a super simple example of what a service, with a differed promise and one with antipattern, so I figured I'd try and make my own but seeing as how I'm not super in the know about it I'd get some clarification first.
I have the below in a factory (SomeFactory):
//url = 'data.json';
return {
getData: function(){
var deferred = $q.defer();
$http.get(destinationFactory.url)
.then(function (response) {
if (typeof response.data === 'object') {
deferred.resolve(response.data);
} else {
return deferred.reject(response.data);
}
})
.catch(function (error) {
deferred.reject(error);
});
return deferred.promise;
}
The reason I am checking its an object is just to add a simple layer of validation onto the $http.get()
And below, in my directive:
this.var = SomeFactory.getData()
.then(function(response) {
//some variable = response;
})
.catch(function(response) {
//Do error handling here
});
Now to my uderstanding, this is an antipattern. Because the original deferred promise catches the error and simply swallows it. It doesn't return the error so when this "getData" method is called I have do another catch to grab the error.
If this is NOT an antipattern, then can someone explain why both require a "callback" of sorts? When I first started writing this factory/directive I anticipated having to do a deffered promise somewhere, but I didn't anticipate having to .catch()
on both sides (aka I was sort of thinking I could get the factory to return the response or the error if I did a SomeFactory.getData()
Yes, it is. 'Deferred anti-pattern' happens when a new redundant deferred object is created to be resolved from inside a promise chain. In your case you are using $q to return a promise for something that implicitly returns a promise. You already have a Promise object(
$http service
itself returns apromise
), so you just need to return it!Here's the super simple example of what a service, with a deferred promise and one with antipattern look like,
This is what you should do
while both of them are consumed in the same way.
There's nothing wrong with either examples(atleast syntactically)..but first one is redundant..and not needed!
Hope it helps :)