inexorabletash / polyfill

JavaScript Polyfills, Shims and More
Other
1.36k stars 354 forks source link

URL.searchParams.entries() is not iterable #116

Closed antoine-aubry closed 7 years ago

antoine-aubry commented 7 years ago

When using the URL polyfill in IE11, if I try to iterate the searchParams.entries(), the code generated by babel throws the following exception:

TypeError: [object Object] is not iterable!

The code that I am using is similar to this:

const url = new URL('http://example.com')
for (let [k, v] of url.searchParams.entries()) { // Throws TypeError: [object Object] is not iterable!
  // Do stuff
}

By looking at the generated code, I see that the iterator code attempts to read properties to get the iterator object. This returns undefined and causes the subsequent error. I am not sure why this is necessary since the object returned by entries() is already an iterator. The relevant code follows:

    var classof   = __webpack_require__(600)
      , ITERATOR  = __webpack_require__(592)('iterator')
      , Iterators = __webpack_require__(574);
    module.exports = __webpack_require__(559).getIteratorMethod = function(it){
      if(it != undefined)return it[ITERATOR]
        || it['@@iterator']
        || Iterators[classof(it)];
    };

I can work around the problem by monkeypatching the result of entries() and add the missing iterator property like this:

const url = new URL('http://example.com')

const entries = url.searchParams.entries()
if (!entries[Symbol.iterator]) {
  entries[Symbol.iterator] = () => entries
}

for (let [k, v] of entries) { // Now works as expected
  // Do stuff
}

Is this a bug in this polyfill? In babel? Or am I doing sonething wrong?

inexorabletash commented 7 years ago

for (x of y) calls y[@@iterator] even if y is iterable to be consistent.

The polyfill may have a bug where the iterator itself is not iterable, let me check...

On Dec 28, 2016, at 10:26 AM, Antoine Aubry notifications@github.com wrote:

When using the URL polyfill in IE11, if I try to iterate the searchParams.entries(), the code generated by babel throws the following exception:

TypeError: [object Object] is not iterable!

The code that I am using is similar to this:

const url = new URL('http://example.com') for (let [k, v] of url.searchParams.entries()) { // Throws TypeError: [object Object] is not iterable! // Do stuff } By looking at the generated code, I see that the iterator code attempts to read properties to get the iterator object. This returns undefined and causes the subsequent error. I am not sure why this is necessary since the object returned by entries() is already an iterator. The relevant code follows:

var classof = webpack_require(600) , ITERATOR = webpack_require(592)('iterator') , Iterators = webpack_require(574); module.exports = webpack_require(559).getIteratorMethod = function(it){ if(it != undefined)return it[ITERATOR] || it['@@iterator'] || Iterators[classof(it)]; }; I can work around the problem by monkeypatching the result of entries() and add the missing iterator property like this:

const url = new URL('http://example.com')

const entries = url.searchParams.entries() if (!entries[Symbol.iterator]) { entries[Symbol.iterator] = () => entries }

for (let [k, v] of entries) { // Now works as expected // Do stuff } Is this a bug in this polyfill? In babel? Or am I doing sonething wrong?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

inexorabletash commented 7 years ago

Yeah, the iterator a returned are too simple - just objects with next() methods; they need @@iterator as well. I'll fix - unless you want to submit a pull request? Note that I want the polyfill to work even without babel so it can't assume ES6 syntax.

Thanks for reporting this!

On Dec 28, 2016, at 10:26 AM, Antoine Aubry notifications@github.com wrote:

When using the URL polyfill in IE11, if I try to iterate the searchParams.entries(), the code generated by babel throws the following exception:

TypeError: [object Object] is not iterable!

The code that I am using is similar to this:

const url = new URL('http://example.com') for (let [k, v] of url.searchParams.entries()) { // Throws TypeError: [object Object] is not iterable! // Do stuff } By looking at the generated code, I see that the iterator code attempts to read properties to get the iterator object. This returns undefined and causes the subsequent error. I am not sure why this is necessary since the object returned by entries() is already an iterator. The relevant code follows:

var classof = webpack_require(600) , ITERATOR = webpack_require(592)('iterator') , Iterators = webpack_require(574); module.exports = webpack_require(559).getIteratorMethod = function(it){ if(it != undefined)return it[ITERATOR] || it['@@iterator'] || Iterators[classof(it)]; }; I can work around the problem by monkeypatching the result of entries() and add the missing iterator property like this:

const url = new URL('http://example.com')

const entries = url.searchParams.entries() if (!entries[Symbol.iterator]) { entries[Symbol.iterator] = () => entries }

for (let [k, v] of entries) { // Now works as expected // Do stuff } Is this a bug in this polyfill? In babel? Or am I doing sonething wrong?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

inexorabletash commented 7 years ago

I just added a fix and test. Can you give 0ed51c9 a try?

antoine-aubry commented 7 years ago

That was quick! I confirm that this fixes the error. Thanks.