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

undefined is not a function(evaluating '_iterator[typeof Symbol === "function"?Symbol.iterator:"@@iterator"]()') #15902

Closed
hzuhyb opened this issue Sep 12, 2017 · 29 comments
Labels
Ran Commands One of our bots successfully processed a command. Resolution: Locked This issue was locked by the bot.

Comments

@hzuhyb
Copy link

hzuhyb commented Sep 12, 2017

I used "for(let...of...){}" to traverse a Map object at react-native,I got this error.
it's working perfectly for IOS and android debug mode, but not working for android normal mode.

wx20170912-162205 2x

@radko93
Copy link
Contributor

radko93 commented Sep 12, 2017

When using remote debugging you use chrome for running JS code. It's a bit different.

@hzuhyb
Copy link
Author

hzuhyb commented Sep 15, 2017

@radko93 thank you for your reply, I know this difference, but how I fix this, whether I need to do some compatibility handling or whether i can not use "for(let...of...){}" to traverse a Map object at react-native?

@TheNoim
Copy link

TheNoim commented Sep 30, 2017

I had the same problem a few days back and I think I solved it with an babel preset. I used
["react-native-stage-0", "react-native-stage-0/decorator-support"]
babel-preset-react-native-stage-0

@pull-bot
Copy link

@facebook-github-bot no-template

@facebook-github-bot
Copy link
Contributor

Hey, thanks for reporting this issue! It looks like your description is missing some necessary information, or the list of reproduction steps is not complete. Can you please add all the details specified in the Issue Template? This is necessary for people to be able to understand and reproduce the issue being reported. I am going to close this, but feel free to open a new issue with the additional information provided. Thanks! See "What to Expect from Maintainers" to learn more.

@facebook-github-bot facebook-github-bot added the Ran Commands One of our bots successfully processed a command. label Oct 10, 2017
@luoyushouchai
Copy link

@huangtubiao Have you solved this yet?

@hzuhyb
Copy link
Author

hzuhyb commented Oct 11, 2017

@luoyushouchai i solved it by using other traversal methods, you also solve it with an babel preset.

@luoyushouchai
Copy link

@huangtubiao @TheNoim
How should I do to change this?
I tried : npm install babel-preset-react-native-stage-0 --save
and then modify .babelrc in root project : { "presets": ["react-native-stage-0"] }
It still not work!

@lwansbrough
Copy link
Contributor

lwansbrough commented Jan 22, 2018

Ok.. so React Native internal code is now using for..of iterators -- and they don't work for me!

Edit: the following does work, though it doesn't explain why I have to apply this fix myself.

import 'core-js/es6/map'
import 'core-js/es6/symbol'
import 'core-js/fn/symbol/iterator'

Edit 2: Just kidding, that doesn't work either.

@ericketts
Copy link

ericketts commented Feb 8, 2018

@lwansbrough when you say that doesn't work either, are you getting a runtime error to the effect of Incompatible receiver, Map required!? If so, check out a possible solution here zloirock/core-js#368

@hzuhyb
Copy link
Author

hzuhyb commented Feb 9, 2018

@ericketts as you said, I got this mistake at different computer machine and I haven't found a good solution yet.
Incompatible receiver, Map required!
wechatimg4066

@ericketts
Copy link

ericketts commented Feb 9, 2018

Sorry that was meant to contain a link directly to the comment which specifies a (temporary) fix. Fixed the link now.

@vafada
Copy link

vafada commented Mar 18, 2018

the main issue here is that Symbol is not implemented in Android.

you have to manually polyfill Symbol and methods that accepts Symbol.iterator.

In my case, a third party library was causing a crash since it uses for-of loop.

Here's my solution:

if (Platform.OS === 'android') {
  if (typeof Symbol === 'undefined') {
    logger.info('Polyfilling Symbol on Android');
    require('es6-symbol/implement');
    logger.info('Polyfilling Array.prototype[Symbol.iterator] on Android');
    if (Array.prototype[Symbol.iterator] === undefined) {
      Array.prototype[Symbol.iterator] = function() {
        let i = 0;
        return {
          next: () => ({
            done: i >= this.length,
            value: this[i++],
          }),
        };
      };
    }
  }
}

In my case. I had to polyfill Array[Symbol.iterator] to return a Iterator protocol:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols

@Seddy24
Copy link

Seddy24 commented Mar 22, 2018

@vafada I tried your approach but now i'm getting:
image

Any ideas? Did you have to add any additional packages?

@vafada
Copy link

vafada commented Mar 22, 2018

@Seddy24 I've seen that error when I imported

import 'core-js/es6/symbol'
import 'core-js/fn/symbol/iterator'

Make sure you dont import those libraries.

The fix above requires you to add es6-symbol in your package.json

The simplest way to fix the

undefined is not a function(evaluating '_iterator[typeof Symbol === "function"?Symbol.iterator:"@@iterator"]()')

error without any libraries is to do:

if (Platform.OS === 'android') {
  if (typeof Symbol === 'undefined') {
    if (Array.prototype['@@iterator'] === undefined) {
      Array.prototype['@@iterator'] = function() {
        let i = 0;
        return {
          next: () => ({
            done: i >= this.length,
            value: this[i++],
          }),
        };
      };
    }
  }
}

Add the poly fill in your index.js or whatever is your App's entry point

@Seddy24
Copy link

Seddy24 commented Mar 22, 2018

@vafada Thanks that worked. I had to create a brand new app as I couldn't get it to work with what I had but I'm working on a POC anyway so thanks!!

@ericketts
Copy link

ericketts commented Mar 23, 2018

@Seddy24 no reason to reinvent the wheel, corejs is great (and already included as a dependency of react-native). try this:

// symbol polyfills
global.Symbol = require('core-js/es6/symbol');
require('core-js/fn/symbol/iterator');

// collection fn polyfills
require('core-js/fn/map');
require('core-js/fn/set');
require('core-js/fn/array/find');

for whatever reason react-native on android is shipping an old as shit version of JSC, one that doesn't have support for language features that current react version needs to work 🙄

@Seddy24
Copy link

Seddy24 commented Mar 23, 2018

@ericketts Thanks for the additional information. I'm new to react / react native, trying to rewrite my Xamarin app and loving react native so far!! Any additional tips are welcome!!

@ivanpagac
Copy link

I dont know but probably doing something wrong, copy/paste from @ericketts is not working in my app :( had to rewrite to for of to for

@ericketts
Copy link

ericketts commented Jun 13, 2018

@ivanpagac try pinning corejs to version 2.5.2 (this can be easily accomplished using yarn, if you're using npm still I'd say switch to yarn)

@ericketts
Copy link

as a more permanent solution to this issue, I'd advise updating the JSC version that ships with android so that the functionality presently being pollyfilled is implemented natively.

@ivanpagac
Copy link

@ericketts Thanks for that! The solution with updating the JSC version works.

@ericketts
Copy link

@ivanpagac glad to hear it! Really extremely puzzling to me why RN continues to ship a super outdated JSC.

@Calsowah
Copy link

Calsowah commented Jun 28, 2018

@ericketts into which file exactly does the code you mentioned above go?

`// symbol polyfills
global.Symbol = require('core-js/es6/symbol');
require('core-js/fn/symbol/iterator');

// collection fn polyfills
require('core-js/fn/map');
require('core-js/fn/set');
require('core-js/fn/array/find');`

Thank you`

@ericketts
Copy link

ericketts commented Jun 28, 2018

@Calsowah I created a file polyfill.js, and require it in the index.js or app.js file before requireing any other dependencies (note I said requireing, not importing, as the semantics of require are easier to reason about, and to guarantee ordering of imports).

Edit: also for blocks of code, you need 3 backticks on their own line to start and end the block, like so:

```javascript
const x = 4;
```

which becomes

const x = 4;

@Calsowah
Copy link

@ericketts I did as you suggested but I'm getting the following error
screenshot_2018-06-28-12-56-46

@andriichernenko
Copy link

If polyfilling Array.prototype['@@iterator'] does not fix the issue, you might need to polyfill String.prototype['@@iterator'] as well.

@mehulmpt
Copy link

@ericketts Thanks for the upgrading JSC tip. Works flawlessly!

@hramos
Copy link
Contributor

hramos commented Feb 11, 2019

The JSC in Android was updated in December, and it will be part of the 0.59 release.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Ran Commands One of our bots successfully processed a command. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests