NCEAS / metacatui

MetacatUI: A client-side web interface for DataONE data repositories
https://nceas.github.io/metacatui
Apache License 2.0
42 stars 26 forks source link

'Promise' used for quality metrics not supported in IE 11 #1200

Closed gothub closed 4 years ago

gothub commented 4 years ago

In order to display aggregated quality metrics in the portal metrics tab, an image needs to be retrieved from the quality service (k8s). As I didn't find a way to make this work with the commonly used $.ajax() call, Promise() was used. It turns out that IE 11 does not support Promise(). This work is currently in a feature branch. Note - i have not testing this in IE 11, just googled to see if there were any problems.

Potential solutions:

amoeba commented 4 years ago

Bluebird (minified) is 77 KiB which is a pretty heavy dependency for adding a single Promise to MetacatUI. IIUC, any Promise-based code can be rewritten to use callbacks, albeit not as slick, so I'd go for your first option. If it's really not going to pan out, promise-polyfill or RSVP are lighter ways use Promises when targeting older browsers w/o transpiling.

gothub commented 4 years ago

One solution would be a way to use $.ajax() so that it could retrieve an 'image/png'. I was getting parsing errors when trying to do this. @amoeba @laurenwalker @csjx @robyngit - does anyone know how to configure $.ajax() to be able to retrieve an image?

amoeba commented 4 years ago

Can you just let the browser load the image? Something like https://codepen.io/petridish/pen/gObpbZa. I think you'll need to take care of cross-origin issues. Another way would be to insert the image as a base64-encoded string but that feels a bit clunky.

laurenwalker commented 4 years ago

I found a Promise polyfill: https://www.npmjs.com/package/promise-polyfill that would be worth a shot trying. We could dynamically require it only if Promise is undefined. It's <1KB.

gothub commented 4 years ago

Nice! I'll try this out

gothub commented 4 years ago

@laurenwalker How can a module be dynamically required? Doesn't the module name for the 'Promise' always need to be in the define statement in Stats.js? For IE, that would be the library name of the polyfill, but what would it be when Promise is native JS?

Is there another way to conditionally require the polyfill for IE? Easy enough to test if the function is defined:

if (typeof Promise === "function") {... something ...}
laurenwalker commented 4 years ago

Either way would work, I was just thinking that requiring dynamically would save non-IE 11 users (most users) from having to load that polyfill code. It would be a minor performance improvement, so not a huge deal, but it would be nice.

You can require a component anywhere in the code, not just in the define() statement for a module. The define() function just defines a RequireJS module. Inside of a RequireJS module, you can require() components whereever needed. We do this in the router so that the views are only loaded as the user navigates to that view. Example: https://github.com/NCEAS/metacatui/blob/master/src/js/routers/router.js#L172-L184

If this is becoming a huge blocker, then we can just go ahead and include the polyfill in the Stats model.

gothub commented 4 years ago

The es6-promise component has been tested on Chrome, Edge, but not IE 11, as issue #1236 is a blocker - the metrics tab doesn't load.

The Promise polyfill was implemented and checked into the feature-portals-agu-demo branch (parent: dev-2.8) in commits:

gothub commented 4 years ago

The 'Promise' polyfill has been verified on WIn10/IE (and Edge):

Screen Shot 2020-01-15 at 3 14 49 PM