Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make "Convert for to forEach" handle for…of loops #92

Closed
bennidi opened this issue Mar 30, 2020 · 5 comments · Fixed by #263
Closed

Make "Convert for to forEach" handle for…of loops #92

bennidi opened this issue Mar 30, 2020 · 5 comments · Fixed by #263
Labels
💪 Improvement Refactoring doesn't run on a specific case or result could be optimized 👋 Good first issue Good for newcomers

Comments

@bennidi
Copy link

bennidi commented Mar 30, 2020

The for loop to foreach refactoring apparently does not work on for (const entry of entries) style loops. At least the plugin says it did not detect a valid for-loop.
Would be great to make it work for this style of loops.

Abracadabra version: 3.2.3

@bennidi bennidi added the 💪 Improvement Refactoring doesn't run on a specific case or result could be optimized label Mar 30, 2020
@nicoespeon nicoespeon added the 👋 Good first issue Good for newcomers label Apr 2, 2020
@nicoespeon nicoespeon changed the title for-loop to foreach Make "Convert for to forEach" handle for-of loops Apr 2, 2020
@nicoespeon nicoespeon changed the title Make "Convert for to forEach" handle for-of loops Make "Convert for to forEach" handle for…of loops Apr 2, 2020
@nicoespeon
Copy link
Owner

nicoespeon commented Apr 2, 2020

Indeed, that would be doable.

And I think that's something contributors could help with, it's not too complex.

Code example

So this code:

const array1 = ['a', 'b', 'c'];

for (const element of array1) {
  console.log(element);
}

Should be convertable to this code:

const object1 = { 'a': 1, 'b': 2, 'c': 3 };

array1.forEach((element) => {
  console.log(element);
})

Where to do the change

The refactoring already exist, everything is here: https://github.com/nicoespeon/abracadabra/tree/master/src/refactorings/convert-for-to-foreach

What you need to do:

  1. Create at least one new test case to illustrate that it doesn't work today:
    {
    description: "list is a member expression itself",
    code: `for (let i = 0; i < this.data[0].items.length; i++) {
    console.log(this.data[0].items[i]);
    }`,
    expected: `this.data[0].items.forEach(item => {
    console.log(item);
    });`
    }
  2. Make it work!

Warning, edge-cases

Actually, for…of is something that can be used on any Iterable, not just Arrays: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Instructions/for...of

Another example of natural iterables are Strings. If we don't pay attention, we can break the code:

const iterable = 'boo';

// This works!
for (const value of iterable) {
  console.log(value);
}

// This doesn't, `String.prototype.forEach()` doesn't exist
iterable.forEach((value) => {
  console.log(value);
});

Check MDN documentation for all existing iterables and make sure that we handle them properly. It's acceptable to not perform the refactoring for the non-supported iterables.

But we shouldn't make it possible to break the code 😉

@filiphoeven
Copy link

I was actually looking for an automatic refactoring of "forEach" into "for (... of ...)" because "forEach" can be dangerous (doing something else than expected) when used with promises (or async/await) while "for of" works fine.

@ajanian
Copy link

ajanian commented Nov 17, 2020

I'm thinking about fixing this one as a good first issue. @nicoespeon, I assume since it isn't assigned that it isn't being actively worked? Just want to make sure I don't do work someone else is already doing.

@nicoespeon
Copy link
Owner

nicoespeon commented Nov 17, 2020

@ajanian indeed, no-one in working on that (or I'm not aware). If you start working on that let me know and I'll "assign" it to you so it clarifies it's in progress.

Thanks for your help by the way, that's awesome 😃

@nicoespeon
Copy link
Owner

This will be available in the next release. I'll make it happen before the end of the week ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💪 Improvement Refactoring doesn't run on a specific case or result could be optimized 👋 Good first issue Good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants