Promise.catch does not work in IE11 with polyfills

I use ES6, Promises and select Polymer 2 in my project. Since I need to support at least IE11, I translate from Babel (through the assembly in polymer) and use polyfills.io to polyfill fetch and support Promise. My import of polyfills.io happens before any other import and looks like this:

<script src="https://cdn.polyfill.io/v2/polyfill.js?features=default,fetch&flags=gated"></script>

When the page loads, this error appears in the IE11 console:

SCRIPT438: Object doesn't support property or method 'catch'

Looking through my code, the only time I use catch is in Promises. For instance:

 loadSchemas() { return APP.client .search("+type:Schema") .then(result => { // Do things with results. }) .catch(error => { // Deal with errors. }); } 

If I delete catch, the page loads without errors, but then my error handling code obviously does not work.

Why does this not work as expected? It works great in Firefox, Chrome, and Safari. I tried several different polynomial promises and still got the same error, so I don't think this is a polyfill error.

+5
source share
2 answers

Actually, if you import / webcomponentsjs / webcomponents -lite.js polyfill (with Polymer 2.x), it most likely rewrote Promise polyfill. And this polyfill currently has an open catch problem:

https://github.com/webcomponents/webcomponentsjs/issues/837

Where a workaround is offered:

Run the version of WebComponents polyfill to version 1.0.7 or lower.

I looked at webcomponents-lite polyfill for Promise and they replace the definition of Promise if the following is false (I simplified the entry):

 Object.prototype.toString.call(window.Promise.resolve()) == "[object Promise]" 

However, even if you import Promise polyfill from other sources, they display "[object Object]" , so they are replaced.

Note: webcomponents-lite polyfill for Promise also does not currently provide the Promise.all() method, also probably due to the above problem with the Closure compiler.

Suggested workaround while this problem is not fixed:

Download the polyfill after the polyfill web components.

 // load webcomponents polyfills (function() { if ('registerElement' in document && 'import' in document.createElement('link') && 'content' in document.createElement('template')) { // browser has web components } else { // polyfill web components let e = document.createElement('script'); e.src = '/bower_components/webcomponentsjs/webcomponents-lite.js'; document.head.appendChild(e); } // Promise polyfill for IE11, as of 2017/09/07 webcomponents Promise polyfill is broken // (https://github.com/webcomponents/webcomponentsjs/issues/837) if (!window['Promise'] || !window['Promise']['reject']){ // Remove the webcomponents polyfilled Promise object delete window.Promise; // Add own polyfill for Promise let e = document.createElement('script'); e.src = '/lib/promisePolyfill/promise.js'; // or polyfill.io document.head.appendChild(e); } })(); 
+1
source

So it looks like catch is a reserved word in IE 9+. I found this nugget of information at https://github.com/lahmatiy/es6-promise-polyfill :

catch is a reserved word in IE <9, which means promise.catch(func) throws a syntax error. To get around this, use the line to access the Property:

promise['catch'](function(err) { // ... });

Or use .then instead:

promise.then(undefined, function(err) { // ... });

My code works in IE11 if I modify it to avoid catch, for example:

 loadSchemas() { return APP.client .search("+type:Schema") .then(result => { // Do things with results. }, error => { // Deal with errors. }); } 
+3
source

Source: https://habr.com/ru/post/1271347/


All Articles