For...of statements are not supported

Good day. I need to use a loop for…of to iterate through values iterator, which is returned by the method keys() URLSearchParams object.
But when I try to declare a loop I get this error:

for…of statements are not supported. Use transforms: { forOf: false } to skip transformation and disable this error, or transforms: { dangerousForOf: true } if you know what you’re doing (155:8)

As I understand it, this setting is Buble? I was trying to find to solve this problem, but to no avail.

I have decided in this way:

But I would like to use that statements for…of

Hi @Gertrido - yes, that message describes Buble settings. Take a look here for an explanation about for...of transforms: https://buble.surge.sh/guide/#dangerous-transforms

If you want to enable that transform (which is probably fine), here’s how you should edit the Buble options in your webpack.config.js:

{
  loader: "buble",
  options: {
    objectAssign: "Object.assign",
    transforms: {
      modules: false,
      dangerousForOf: true,
    },
  },
},

dangerousForOf: true fixes the issue you’re currently running into, and modules: false tells Buble it’s okay to ignore the export and import statements in your code (I started getting errors about those as soon as I added the first transforms option). https://buble.surge.sh/guide/#using-es-modules

Thanks to @knowler for helping me get that config right!

4 Likes

Thanks for the answer. The error disappeared and the cycle for…of works fine on simple examples, such as

let arr = [ 3, 5, 7 ];
for (let i of arr) {
   console.log(i); // displays "3", "5", "7"
}

But such an example does not work (iteration cycle is none). Example:

let searchParams = new URLSearchParams("key1=value1&key2=value2"); 

// Display the key/value pairs 
for(let key of searchParams.keys()) { 
  console.log(key); // displays "key1", "key2"
}

I don’t understand the reason. You are faced with this problem?

Hey @Gertrido,

Sorry, I missed it in their docs before, but the way Buble compiles for...of statements doesn’t work with objects that implement iterators (like URLSearchParams), only with simpler array-like objects that have a length property.

The result is that Buble compiles your for...of statement into an old-school for structure that doesn’t work with URLSearchParams or UrlSearchParams.keys(). You can try playing with this in your dev console to see what happens in each step:

var searchParams = new URLSearchParams("key1=value1&key2=value2");
for (var i = 0, list = searchParams.keys(); i < list.length; i += 1) {
  var key = list[i];

  console.log(key); // displays "key1", "key2"
}

There’s no such thing as list.length or list[i]. The Buble output would need to call .next() or use a different approach that works with iterators.

You’ve got at least a couple options:

  1. If you’re happy with the browser support for for...of you can just tell Buble not to process it at all:
    {
      loader: "buble",
      options: {
        objectAssign: "Object.assign",
        transforms: {
          modules: false,
          forOf: false,
        },
      },
    }
    
  2. Use a different loop method, e.g.:
    let searchParams = new URLSearchParams("key1=value1&key2=value2");
    Array.from(searchParams).forEach(param => console.log(param));
    
2 Likes

@mmirus thank you for such a detailed response. I’ll be experimenting.

1 Like