Search code examples
javascriptnode.jsreactjsexpresshttp-proxy

Error fetch from react to express without CRA(create-react-app)


import React,{Component} from 'react';
import '../styles/App.css';

class App extends Component{
  constructor() {
    super();
    this.state = {
      products: []
    };
  }
  componentDidMount() {
    fetch('http://localhost:4000/products', {
      method: 'GET',
      mode: "no-cors",
      headers: {"Content-Type": "application/json"}
    }).then(res => {console.log(res);res.json()})
      .then(products => this.setState({products}));
  }

  render() {
    return (
      <div>
        <h1>Hello, react.js!!!</h1>
        <ul>
        {this.state.products.map(product => <li>{product.product_name}</li>)}
        </ul>
      </div>
    );
  }
}

export default App;

express.js listen port 4000. This express.js part

app.get("/products", (req, res) => {
    conn.query('SELECT * FROM products', (err, result) => {
        if(err) {throw err;}
        console.log(result);

        res.json(result);
    });
});

If I just type in the address bar http://localhost:4000/products, then I will get a json response, but in the component application react.JS fetch returns an error because the response contains an empty body, which means that the address was not available. This error is related to CORS, but I don't know how to fix it.

Perhaps if you know how to use and configure a proxy for this, then I would be very grateful for a hint.

App.js uses fetch to access express

here are the error logs, it occurs because the body in the request is null, that is, the response comes with an empty body enter image description here


Solution

  • Whats happening is your code is not waiting for the call to finish.

    You can use async-await functionality.
    This link may help : https://www.valentinog.com/blog/await-react/

    Editing and adding a sample as OP is not able to reach the link.
    Try this:

      async componentDidMount() {
    const response = await fetch('http://localhost:4000/products', {
          method: 'GET',
          mode: "no-cors",
          headers: {"Content-Type": "application/json"}
        });
        const json = await response.json();
        // Do stuff with json
        console.log(json);
        this.setState(json);
      }
    

    As simple as this might also work but please check:

      async componentDidMount() {
        await fetch('http://localhost:4000/products', {
          method: 'GET',
          mode: "no-cors",
          headers: {"Content-Type": "application/json"}
        }).then(res => {console.log(res);res.json()})
          .then(products => this.setState({products}));
      }
    

    Also have you enabled CORS in your express project?