dayhaysoos / use-shopping-cart

Shopping cart state and logic for Stripe

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Intl.DateTimeFormat#formatToParts() is not defined in older browsers — please manually polyfill it, example below

TracerBuilt opened this issue · comments

commented

In older browsers (I've tried IE 9.0, 10, and 11 as well as Firefox 52 and 56), attempting to load the cart produces:

TypeError: a.formatToParts is not a function

Thoughts on a potential polyfill?

commented

I'm given to understand that this is also the case for iOS devices running Safari 12 or earlier.

Yeah you should be able to find a polyfill for Intl.DateTimeFormat. We probably won't be polyfilling that in this library because not everyone will want the polyfill. However, I can look up a polyfill real quick for you to use in your project.

This seems to be the most recent DateTimeFormat polyfill: https://formatjs.io/docs/polyfills/intl-datetimeformat/

commented

Just in case anyone winds up here looking for a solution to the same problem I had, I created a fork using this polyfill which enables this package to work in older browsers. It can be found hereand installed with: npm install @tracerbuilt/use-shopping-cart

@TracerBuilt you shouldn't need to fork the package to use a polyfill. May I ask why you did?

In order to keep your installation of use-shopping-cart up-to-date, I would suggest just installing the polyfill and then importing it before using use-shopping-cart. If you only want it to polyfill when necessary, you can use dynamic imports, and once your polyfills are loaded you can then render your application.

commented

Ah! I'm a bit new to all this and it was the only way I could think of to inject code into a pre-existing project.

Do you have any recommendations on where I could read up and learn how to do what you're talking about?

I'll send you an example of how I've done it in the past in my projects.

Here is a link to my project that utilizes an optional polyfill loading pattern:

https://github.com/ChrisBrownie55/notably/blob/dabe00a22c8db1d18cc7f49fd7ef866138b4ecdc/src/index.tsx#L50-L59

The idea is that you can create some asynchronous functions that see if a polyfill is needed for a feature and then will load each polyfill and assign them to their respective names on the window. Once you have these, you can run them all and use Promise.all() to wait for all of them.

Once all of the asynchronous functions have ended, you can then import your App.js file dynamically and render it. The reason why we wait to import App.js is that if we try to use one of those features — used in the module's global scope, not in a component/function — that need to be polyfilled within our app before it is polyfilled, then our app will crash.

async function loadXyz() {
	if (!window.xyz) {
		window.xyz = (await import('xyz-polyfill')).default
	}
}

async function loadAbc() { /* ... */ }

Promise.all([loadXyz(), loadAbc()])
	.then(() => import('./App.js'))
	.then(({ default: App }) => {
		// render
		ReactDOM.render(<App />, document.getElementById('root'));
	})
commented

Thank you so much. This is extremely helpful.