30

I'm experiencing a weird bug on IE8 while trying to catch a promise reject (promise returned by a basic ngResource call) :

This code work with .then(success, fail) syntax :

promise.then(function(response) {
  // success
},
function(response) {
  // error
});

but this one fails with .then(success).catch(fail) syntax :

promise.then(function(response) {
  // success
})
.catch(function(response) {
  // error
});

and the IE error pointing to the .catch() line is :

Expected identifier

Am I doing something wrong ? someone reproduce it ? or is it a common IE8 due to restricted keyword ?

Thanks

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
Jscti
  • 14,096
  • 4
  • 62
  • 87

3 Answers3

50

You need to use bracket notation:

promise.then(function(response) {
  // success
})
["catch"](function(response) {
  // error
});

This is because IE8 implements ECMAScript 3 that does not allow bare keywords in dot notation. Modern browsers implement ECMAScript 5 that allows it.

A lot of libraries alias .catch with another keyword. However, the way Angular promises are built it is not simple to extend $q promises. So ["catch"] would have to do. Note this is also true for finally.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • 1
    Thanks for the explanation. I'll stick with the `then(null, error)` notation which looks better than this ugly `["catch"]` – Jscti Apr 16 '14 at 10:26
  • 1
    @Bixi alternatively, you can use a preprocessor like ESPRIMA with ESCODEGEN that will automatically replace `.catch` with `["catch"]` as part of your build process. – Benjamin Gruenbaum Apr 16 '14 at 11:56
  • Thanks for the info, but that's overkill and adding complexity for not much – Jscti Apr 16 '14 at 12:31
9

Yes, IE8 thinks it's a keyword. You can get around this a couple of ways:

  1. promise.then(function() { })['catch'](function() { });
  2. promise.then(function() { /* success handler */ })).then(null, function() { /* error handler */ });
  3. Or combine success and error into one then statement, if such a thing is appropriate: promise.then(function() { /* success handler here */ }, function() { /* error handler here */ });

catch is shorthand for #2.

moribvndvs
  • 42,191
  • 11
  • 135
  • 149
  • Your two alternatives do completely different things though. – Benjamin Gruenbaum Apr 16 '14 at 09:30
  • The first one will catch errors in the `.then`, the second will not. – Benjamin Gruenbaum Apr 16 '14 at 09:32
  • 4
    I'm not following you. Then can take 1, 2 or 3 function arguments. The first being success, the second being error, the third being notify. `catch` just calls and returns the result of `.then(null, fn)`. So ok, I meant that in my answer (so there are three options), but I instinctively optimized it into one call, with both success and error handlers. – moribvndvs Apr 16 '14 at 09:43
  • To clarify difference: http://stackoverflow.com/questions/24662289/thensuccess-fail-antipattern-for-promise ... third option isn't catching exceptions thrown in success handler as it would do in first and second option. – Thomas Urban Jun 18 '15 at 08:51
3

http://docs.angularjs.org/api/ng/service/$q#the-promise-api

Because finally is a reserved word in JavaScript and reserved keywords are not supported as property names by ES3, you'll need to invoke the method like promise'finally' to make your code IE8 and Android 2.x compatible.

Same for catch.

Miraage
  • 3,334
  • 3
  • 26
  • 43