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 responses when used with React Native #324

Closed
qnp opened this issue Nov 17, 2023 · 5 comments · Fixed by #398
Closed

undefined responses when used with React Native #324

qnp opened this issue Nov 17, 2023 · 5 comments · Fixed by #398

Comments

@qnp
Copy link

qnp commented Nov 17, 2023

Environment

React Native (all versions)

Reproduction

It is difficult to provide a react-native starter as I'm not a specialist, and it will require that you install and setup everything to start a react-native project. Instead, you could rely on my detailed investigation

Describe the bug

Hi,

in the light of this issue,

Looking deeper into the commit linked by @pi0 to close the issue, and having the same issue as @gtjamesa (responses are all undefined), it seems that this commit will not fix the undefined responses issue.

I dug into ofetch source code and did my own investigation. It appears that there is a boolean hasBody which checks if response.body exists, as expected in fetch Response spec, see:

ofetch/src/fetch.ts

Lines 172 to 173 in bb2d72b

const hasBody =
context.response.body &&

Yet, only these fields are available in the response object returned by fetch in React Native:
_bodyBlob, _bodyInit, bodyUsed, headers, status, statusText, type.

Indeed, react-native uses whatwg-fetch polyfill.

We can easily see in whatwg-fetch source code that all these keys are defined by the polyfill on this, but not body.

The correct answer would be to create an issue on whatwg-fetch so that they update their code and comply with Fetch API, and then create an issue on React Native to use this updated library, and then update React Native. Nevertheless, this process can take a while, and (as it is the case for our projects) many React Native projects are stuck to older versions because they depend on other libs that breaks and haven't updated yet and an update to the latest is very difficult.

The shorter answer would be to adapt ofetch so that it also checks specific whatwg-fetch fields in the response to know if a body is available.

What do you think ?

Additional context

No response

Logs

No response

@wzulfikar
Copy link

wzulfikar commented Mar 30, 2024

I can confirm that the issue still exist today. Can replicate from default expo template and adding ofetch somewhere in the code. Example:

npx create-expo-app myapp -t expo-template-blank-typescript
import { StatusBar } from "expo-status-bar";
import { Text, View } from "react-native";
import useAsync from "@/hooks/useAsync";
import { ofetch } from "ofetch";

export default function App() {
  const result = useAsync(() => ofetch("http://example.com"), []);
  console.log('result:', result);
  return (
    <View>
      <Text>Hello RN!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

The bug:
image

@joshmossas
Copy link
Contributor

It seems this has long been an issue with react native
facebook/react-native#27741

According to the author of whatwg-fetch. The react native team would need to make their own implementation of fetch since whatwg-fetch was intended for legacy browsers not other platforms
JakeChampion/fetch#746 (comment)

@joshmossas
Copy link
Contributor

Sorry, I should note that these issues I linked are specific to streamed responses, but it seems react native has long had issues with the way "Fetch" has worked in their library.

@joshmossas
Copy link
Contributor

joshmossas commented May 7, 2024

Btw the quick fix for this seems to be

    const hasBody =
      // react native whatwg-fetch check
      ((context.response as any)._bodyInit || context.response.body) &&
      !nullBodyResponses.has(context.response.status) &&
      context.options.method !== "HEAD";

Turns out we don't have to check for all the different fields whatwg-fetch sets, because it always sets the __bodyInit field. I tested on latest react native expo starter and it works. I'm willing to open a PR if this is the direction the team wants to go in. It seems like a pretty low overhead change.

Streams will still be broken, but I might be able to get it working with a polyfill on the react native side.

@joshmossas
Copy link
Contributor

joshmossas commented May 24, 2024

I've opened a PR with the solution I outlined above. I tested with the latest expo starter app and everything seems to work fine.

I've also created an issue in whatwg-fetch. JakeChampion/fetch#1454

Hopefully this will eventually get the ball rolling for this problem to be fixed in react-native itself. Although I suspect that it will take some time for everything to move downstream to react-native. Feel free to give it a thumbs-up over there so that they know there's interest in getting it fixed.

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

Successfully merging a pull request may close this issue.

3 participants