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" from wonka.js on query operation in react-native #3129

Closed
3 tasks done
jtc3161 opened this issue Apr 5, 2023 · 25 comments
Closed
3 tasks done

Comments

@jtc3161
Copy link

jtc3161 commented Apr 5, 2023

Describe the bug

Using a minimal example mostly copied from the docs I'm getting the error "undefined is not a function" when a useQuery attempts to execute the operation. This is specifically happening on Android using expo@48 (react-native dev environment). There is some incompatibility with urql@4 and expo@48 that I haven't been able to get to the bottom of.

Debugger is pointing to this line as the entry to wonka.js:

fromAsyncIterable(fetchOperation(operation, url, fetchOptions)),

The provided reproduction doesn't work in the snack web ui, but if you download the zip, run:
npm install npx expo start and then use the Expo Go app to run it on an android phone and it runs fine. But then if you run npm uninstall expo and then npm install expo@48 (newest version), urql does not function properly. I'll continue to work on tracking down what package exactly is causing the incompatibility. upgrading expo also upgrades react-native and several other packages.

btw love this project, I have multiple web apps using urql and they have always worked flawlessly.

Reproduction

https://snack.expo.dev/@jtc3161/curious-chip?platform=web

Urql version

urql v4.0.0

Validations

  • I can confirm that this is a bug report, and not a feature request, RFC, question, or discussion, for which GitHub Discussions should be used
  • Read the docs.
  • Follow our Code of Conduct
@kitten
Copy link
Member

kitten commented Apr 5, 2023

I'm not sure what Expo's default transpilation for node modules comes down to, since I've actually seen that their preset includes this, but to summarise, the problem here is that you'll need to add a transformer for async generators, so it's not a bug per se, but React Native is basically the only supported platform that doesn't have support for async iterables/generators out of the box and will need that to be transpiled.

This on its own isn't that unusual — after all — Hermes has a bunch of unsupported ES features that are a little odd compared to other platforms, but generally speaking, I'm basically just not sure what Expo's default's on this are or what Expo Snack's defaults for this are.

@jtc3161
Copy link
Author

jtc3161 commented Apr 5, 2023

Awesome thank this is an amazing lead. I'll hit up the expo discord. If there's any react-native specific urql documentation I might be able to provide I will get back to you

@jtc3161 jtc3161 closed this as completed Apr 5, 2023
@jtc3161
Copy link
Author

jtc3161 commented Apr 5, 2023

@kitten thank you for your help, digging into the docs, expo 48 changed the default js engine from JS core to Hermes. Switching the engine back to jscore unblocks me, but it doesn't seem like this has ever worked on hermes. I have an issue open on expo to see if there's changes that can be made to their babel preset to support this.

@Vednus
Copy link

Vednus commented Apr 11, 2023

Is there a workaround for this that anyone knows of? Going back to JS core is a bad idea. Hermes has been the default for a while now. I'll look into it and post any options I come across.

@Vednus
Copy link

Vednus commented Apr 11, 2023

seems like this will work: aws-amplify/amplify-js#10764 (comment)

@Mafooch
Copy link

Mafooch commented Apr 19, 2023

So, is the official fix for this just to use the js core polyfill or should we be expecting an update from urql?

@kitten
Copy link
Member

kitten commented Apr 19, 2023

@Mafooch We're not currently planning a change from our end, no, as the switch to async generators on our fetch implementation was intentional given our browser support. That said, while Hermes is not supporting async generators/iterables — and you can work around this by ensuring the proper polyfills and transforms are applied — the React Native Babel preset should, as long as it's applied to node modules, polyfill support for this.

However, for one reason or another this doesn't seem to be the case. The only issue that was opened in reaction to this is: expo/expo#22006 (comment)

However, I currently have no bandwidth to look into this and am not sure why this polyfill may not be applied correctly automatically

@elisalimli
Copy link

@Vednus @jtc3161

seems like this will work: aws-amplify/amplify-js#10764 (comment)

Is just adding this to index.ts solved the issue for you?

import "core-js/full/symbol/async-iterator";
import allSettled from "promise.allsettled";
allSettled.shim();

import "expo-router/entry";

@Vednus
Copy link

Vednus commented May 1, 2023

@elisalimli I think that's what I did. I ended up not going with urql, but I'm pretty sure that worked

@elisalimli
Copy link

@Vednus In my case adding the lines to index.ts fixed the "undefined is not a function" error.

But while using useQuery network error occurs:

[Network] Cannot convert undefined value to object at construct (native) at apply (native) at _construct (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:7125:28) at Wrapper (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:7087:25) at construct (native) at _createSuperInternal (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:128706:294) at call (native) at CombinedError (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:128742:26) at makeErrorResult (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:129002:31) at ?anon_0_ (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:129326:30) at throw (native) at resume (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:129380:30) at anonymous (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:129391:17) at tryCallOne (/private/var/folders/yw/6bx918xn4671rggfcdxz7fph0000gn/T/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:53:16) at anonymous (/private/var/folders/yw/6bx918xn4671rggfcdxz7fph0000gn/T/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:139:27) at apply (native) at anonymous (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:33521:26) at _callTimer (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:33440:17) at _callReactNativeMicrotasksPass (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:33470:17) at callReactNativeMicrotasks (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:33633:44) at __callReactNativeMicrotasks (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6570:46) at anonymous (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6382:45) at __guard (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6554:15) at flushedQueue (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6381:21) at callFunctionReturnFlushedQueue (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6366:33)

I ended up not going with urql
What was the actual reason? these errors or something else ?

@Vednus
Copy link

Vednus commented May 1, 2023

@elisalimli No, it was working, but I was trying to migrate from apollo-client and I needed some features urql didn't have. I was also migrating because urql is faster, but it wasn't so much faster that it made a huge difference. Not sure why you're getting this error, but it seems unrelated to the async iterator stuff.

@elisalimli
Copy link

@Vednus can you share the link to the working code, please? I'm just trying to debug this error and can't solve it.

@Vednus
Copy link

Vednus commented May 1, 2023

@elisalimli I don't have any working code to show you. I have that work in a branch, but it's in a private repo and in a large project. I think the error you're getting probably means your useQuery code is wrong, like you didn't destructure correctly or something along those lines.

@elisalimli
Copy link

elisalimli commented May 1, 2023

Oh, It's ok.
For example:
hello query is supposed to be returned "hello world". But it returns the network error I told in my previous comment

import React from "react";
import { Text, View } from "../../components/Themed";
import { gel, useQuery } from "urql";

const meQueryDocument = gql`
  query {
    hello
  }
`;
export default function TabTwoScreen() {
  const [result] = useQuery({ query: meQueryDocument });
  console.log("result ", result);
  return (
    <View>
      <Text>Tab Two</Text>
    </View>
  );
}

@Vednus
Copy link

Vednus commented May 1, 2023

@elisalimli you're importing "gel", but "gel" isn't a thing. I think you're meaning to import "gql" and that's why you're erroring out.

@elisalimli
Copy link

elisalimli commented May 1, 2023

@Vednus I don't know why that happened. But in my code it's gql not gel

@Vednus
Copy link

Vednus commented May 1, 2023

@elisalimli then I don't know. Good luck

@elisalimli
Copy link

@Vednus btw why are you not using react-query instead of Apollo? It looks like it has got a bunch of features

@Vednus
Copy link

Vednus commented May 1, 2023

@elisalimli I need data normalization

@kamilafsar
Copy link

kamilafsar commented May 3, 2023

For me, adding import 'core-js/full/symbol/async-iterator'; at the top of my index.js worked. Thanks @elisalimli !
I didn't need to add Promise.allSettled, appears to be already available. I'm in a normal RN project, not expo.

Edit: after adding graphcache with @urql/storage-rn I ended up doing:

import "core-js/full/symbol/async-iterator"
import "core-js/full/promise/finally"

@elisalimli
Copy link

elisalimli commented May 13, 2023

@kamilafsar

You're welcome! In my case, today I re-tried adding the pollyfill stuff to index.ts.Although that fixes the 'undefined is not a function' error, but again the same network error occurs.

[Network] Cannot convert undefined value to object at construct (native) at apply (native) at _construct (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:7125:28) at Wrapper (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:7087:25) at construct (native) at _createSuperInternal (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:128706:294) at call (native) at CombinedError (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:128742:26) at makeErrorResult (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:129002:31) at ?anon_0_ (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:129326:30) at throw (native) at resume (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:129380:30) at anonymous (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:129391:17) at tryCallOne (/private/var/folders/yw/6bx918xn4671rggfcdxz7fph0000gn/T/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:53:16) at anonymous (/private/var/folders/yw/6bx918xn4671rggfcdxz7fph0000gn/T/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:139:27) at apply (native) at anonymous (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:33521:26) at _callTimer (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:33440:17) at _callReactNativeMicrotasksPass (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:33470:17) at callReactNativeMicrotasks (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:33633:44) at __callReactNativeMicrotasks (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6570:46) at anonymous (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6382:45) at __guard (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6554:15) at flushedQueue (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6381:21) at callFunctionReturnFlushedQueue (http://192.168.100.7:19000/index.ts.bundle?platform=ios&dev=true&hot=false:6366:33)

@hbriese
Copy link

hbriese commented Jul 14, 2023

For me, adding import 'core-js/full/symbol/async-iterator'; at the top of my index.js worked. Thanks @elisalimli ! I didn't need to add Promise.allSettled, appears to be already available. I'm in a normal RN project, not expo.

Edit: after adding graphcache with @urql/storage-rn I ended up doing:

import "core-js/full/symbol/async-iterator"
import "core-js/full/promise/finally"

What version of expo? Was it with hermes or jsc?
I can't get it working with pollyfills using expo 48 hemes

@kitten
Copy link
Member

kitten commented Jul 20, 2023

If anyone would like to try this wonka@6.3.3 contains a workaround that should allow React Native + Hermes's default Babel transpilations to still work with fromAsyncIterable & toAsyncIterable.

In other words, I believe, with the patch in wonka, this should now work without having to include the symbol/async-iterator polyfill from core-js manually.

https://github.com/0no-co/wonka/releases/tag/v6.3.3

@hbriese
Copy link

hbriese commented Jul 24, 2023

If anyone would like to try this wonka@6.3.3 contains a workaround that should allow React Native + Hermes's default Babel transpilations to still work with fromAsyncIterable & toAsyncIterable.

In other words, I believe, with the patch in wonka, this should now work without having to include the symbol/async-iterator polyfill from core-js manually.

https://github.com/0no-co/wonka/releases/tag/v6.3.3

Confirming that this indeed fixes the issue! 🙏
Tested on react native 0.72 (expo 49)

@solominh
Copy link

just add wonka >=6.3.3 (yarn add wonka) => work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants