EDIT: SEE THE ANSWER BELOW
I have a function:
dataFactory.getCurrentStepId(wf.identifier, ctx.identifier)
.then(function (data) {
console.log('then');
$timeout(function () {
$("#app-node-" + data.identifier)
.parent().parent().css("border", "5px solid green");
});
})
.catch(function () {
console.log('error');
alert('Error!')
});
The getCurrentStepId
has an exception, and I see the error printed on the console for the AJAX request it sends, but my alert and console.log don't fire in the catch.
Any ideas why? Here is the stuff it's calling:
app.factory('dataFactory', function ($http, $q) {
var _baseUrl = webServiceContext;
var _doGet = function (endpoint) {
var deferred = $q.defer();
$http.get(_baseUrl + '/' + endpoint).then(function (response) {
deferred.resolve(response.data);
});
return deferred.promise;
};
var getCurrentStepId = function (wid, cid) {
return _doGet('wf/step/' + wid + '/' + cid);
};
})
Here is the answer
@Blunderfest almost got it right:
$http.get(_baseUrl + '/' + endpoint).then(function (response) {
deferred.resolve(response.data);
}).catch(function(e){return deferred.reject(e);});
EDIT: SEE THE ANSWER BELOW
I have a function:
dataFactory.getCurrentStepId(wf.identifier, ctx.identifier)
.then(function (data) {
console.log('then');
$timeout(function () {
$("#app-node-" + data.identifier)
.parent().parent().css("border", "5px solid green");
});
})
.catch(function () {
console.log('error');
alert('Error!')
});
The getCurrentStepId
has an exception, and I see the error printed on the console for the AJAX request it sends, but my alert and console.log don't fire in the catch.
Any ideas why? Here is the stuff it's calling:
app.factory('dataFactory', function ($http, $q) {
var _baseUrl = webServiceContext;
var _doGet = function (endpoint) {
var deferred = $q.defer();
$http.get(_baseUrl + '/' + endpoint).then(function (response) {
deferred.resolve(response.data);
});
return deferred.promise;
};
var getCurrentStepId = function (wid, cid) {
return _doGet('wf/step/' + wid + '/' + cid);
};
})
Here is the answer
@Blunderfest almost got it right:
$http.get(_baseUrl + '/' + endpoint).then(function (response) {
deferred.resolve(response.data);
}).catch(function(e){return deferred.reject(e);});
Share
Improve this question
edited Jan 29, 2016 at 18:15
mikeb
asked Jan 29, 2016 at 18:00
mikebmikeb
11.4k8 gold badges69 silver badges132 bronze badges
8
-
1
If
catch
was called anywhere else in your promise chain, then your catch will not fire. – arjabbar Commented Jan 29, 2016 at 18:03 -
A quick CTRL-F for
catch
in the javascript files shows that as the only place I'm using it. It's a pretty simple bit of code. – mikeb Commented Jan 29, 2016 at 18:05 -
Does your
then
callback fire at all? – arjabbar Commented Jan 29, 2016 at 18:07 - For a valid query, yes it does – mikeb Commented Jan 29, 2016 at 18:07
-
So the exception isn't being thrown in the
$timeout
callback right? – arjabbar Commented Jan 29, 2016 at 18:09
3 Answers
Reset to default 2Make sure you return a rejected promise in your catch blocks. So this:
$http.get(_baseUrl + '/' + endpoint).then(function (response) {
deferred.resolve(response.data);
})
Should be this:
$http.get(_baseUrl + '/' + endpoint).then(function (response) {
deferred.resolve(response.data);
}).catch(function(e){
return $q.reject(e);
});
Actually, you can use $q.reject as a shorthand for rejecting a promise, so I think it's a correct answer :). You can also use return $q.when(response)
as a shorthand for deferred, resolve and all that.
I remend reading: $q.defer: You're doing it wrong
Really, I would re-organize your code to follow a few best practices on promises, especially in angular. It's better to return the $http request itself (which is a promise):
app.factory('dataFactory', function ($http, $q) {
var _baseUrl = webServiceContext;
var _doGet = function (endpoint) {
// Returns the promise wholesale.
return $http.get(_baseUrl + '/' + endpoint).then(function (response) {
return response.data;
}).catch(function(e){
// ensures the returned promise is rejected up the chain.
return $q.reject(e);
});
};
var getCurrentStepId = function (wid, cid) {
return _doGet('wf/step/' + wid + '/' + cid);
};
})
Angular Docs for $q methods:
reject(reason) – rejects the derived promise with the reason. This is equivalent to resolving it with a rejection constructed via $q.reject
The reason you need to do this is that if you do not catch errors and reject promises at lower levels, the promise chain up the line will not know the promise is rejected and treat it as a success.
I find this article has great explaination and example
Inside the promise, the catch() method will catch the error caused by the throw statement and reject().
If an error occurs and you don’t have the catch() method, the JavaScript engine issues a runtime error and stops the program.
try this instead
dataFactory.getCurrentStepId(wf.identifier, ctx.identifier)
.then(function (data) {
console.log('then');
$timeout(function () {
$("#app-node-" + data.identifier)
.parent().parent().css("border", "5px solid green");
}, function (err) {
console.log(err);
alert(err);
});
remember then
takes 2 parameters - a function if successful, a function if error occurred. You only provided success.