Shopify / javascript

The home for all things JavaScript at Shopify.
MIT License
253 stars 38 forks source link

esify assumes foo is defined with "for x, y of foo" #240

Closed WillsonSmith closed 7 years ago

WillsonSmith commented 7 years ago

Right now when translating a for of coffeescript loop, we use Object.entries(object) so:

for code, option of @selectedShipmentOptions[@rateCode]
  rows.push(Shopify.Templates.render(@shipmentOptionsTemplate, {
    optionName: option.name,
    optionPrice: @money(option.amount)
  }))

becomes

for (const [code, option] of Object.entries(this.selectedShipmentOptions[this.rateCode])) {
  rows.push(Templates.render(this.shipmentOptionsTemplate, {
    optionName: option.name,
    optionPrice: this.money(option.amount),
  }));
}

This assumes that this.selectedShipmentOptions[this.rateCode] is defined, but that is not always the case. Since this is how it is translated, Object.entries(undefined) throws. I can get around it by doing something like:

const selectedShipmentOption = this.selectedShipmentOptions[this.rateCode]) || {};
for (const [code, option] of Object.entries(selectedShipmentOption) {
...

but ideally this wouldn't be necessary.

@GoodForOneFare

GoodForOneFare commented 7 years ago

160+ instances of this when decaffing app/assets/javascripts/**/*.coffee 😬 At the very least, we should add an esify warning.

GoodForOneFare commented 7 years ago

@lemonmade this seems like an esify blocker. Should we:

lemonmade commented 7 years ago

Yes, I agreed, we need to fix. Are we even converting to something equivalent? Object.entries() is only over own properties, it looks like CS does it over all properties?

We might want to just match the simpler for in loop directly from CS, unless that violates some linting rule I don't remember. If so, I would just stick to || {}.