studiobrain
studiobrain

Reputation: 1215

React Native unable to run a successful fetch to express API

Given the following setup:

server.js

const express = require('express')
const path = require('path')
const app = express()
const cors = require('cors')
const port = process.env.PORT || 8080

app.use(cors())

app.get('/api', (req, res) => {
  res.send({code: 200, message: 'I have arrived!'})
})

app.listen(port, () => console.log(`I can hear your thoughts on ${port}`))

and the presentational component with call:

App.js

componentDidMount() {
  fetch(`/api`, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  }).then(res => {
    console.log(res)
    return res.json()
  }).then(response => {
    console.log(response)
    this.data = response
  }).catch(error => {
    this.error = error.message || error.error
  })
}

package.json:

"scripts": {
  "start": "npm-run-all --parallel start:client start:server",
  "start:client": "node node_modules/react-native/local-cli/cli.js start",
  "start:server": "node server.js",
  "test": "jest"
},

I am running the app via yarn start, and I see the log: "I can hear your thoughts"... The fetch call, however, is never made. If I supply another fully qualified url within the fetch call it returns the data as expected, however I am unable to hit the express api from within the component.

How can I properly configure this to call the express api when running locally?

As always any and all direction is appreciated, so thanks in advance!

Upvotes: 0

Views: 2062

Answers (1)

Andrew
Andrew

Reputation: 28539

I believe the issue for this is two fold.


Firstly you are running the server and the bundler in the same terminal window. I believe that this is causing them to get confused.

Run them in separate windows. Yes that means you have to run an extra command but it will mean that you will be able to clearly see the logs for each of them.

Also you may have to restart you bundler, especially when you add new packages which will mean restarting your server.

Similarly when you update your server you will have to restart it also causing you to restart your bundler. It doesn't seem like a good idea running them in the same window.


Secondly you are using the localhost for the api. This works nicely on your computer because the api is running on your computer's localhost so it can find it. However, when you run it on a device and you use localhost it looks for the api on your device's localhost and cannot find it there, thus it doesn't bring back a result.


Your solution is quite clear. Firstly, run your bundler and your server in different terminal windows. And secondly use the ip address of your computer so that the emulator/simulator can easily find where the api is located.

I copied your code and made only two changes to the react-native code.

  1. Added alerts to show the response and error from the fetch request
  2. Used my local ip address of my computer rather than localhost

Here are some images of me running it on both Android and iOS, using your code and the changes that I detailed above.

Android

running on android

iOS

running on ios

Upvotes: 1

Related Questions