Search code examples
node.jsreactjsjsonexpressfetch

unexpected end of data at line 1 column 1 of the JSON data in express with React


I am working on a node API with React and Express. Node retrieves the data from Postgress like this:

router.get('/getRestaurants', async(req, res) => {
console.log('Restaurants');
try {
    const { rows } = await db.getAllRestaurants();
    console.log(rows);
    res.json(rows);
} catch(error) {
    console.error(`Error ${error}`);
    res.status(500).send({message: `API internal error`});
}});

The console.log it shows the data without problem and if I use Postman or Curl it seems to work fine. But when I try to retrieve the data from my frontend React I get this error:

Uncaught (in promise) SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data

React makes the POST request like this:

useEffect(() => {
    async function fetchData() {
        const response = await fetch('http://172.20.0.4:3000/getRestaurants', {
            method: 'GET', // *GET, POST, PUT, DELETE, etc.
            mode: 'no-cors', // no-cors, *cors, same-origin
            cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
            credentials: 'same-origin', // include, *same-origin, omit
            headers: {
                'Content-Type': 'application/json'
                // 'Content-Type': 'application/x-www-form-urlencoded',
            },
            redirect: 'follow', // manual, *follow, error
            referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
            });
            const data = await response.json();
            console.log(data);
        return data;
    }
    fetchData();
});

It's probably not hard to see but there's something I'm missing. Thank you in advance!


Solution

  • I think you have a problem with CORS, since you are fetching data from another origin, you need to set mode: 'cors', which means that you will fetch data across origins. when you set it to mode: 'no-cors' that mean that you don't allow cross origins and that is the cause of the problem. cos as you said. your express app has a different origin than your react app. but it will still not work until you allow your express api, the origin you are fetching from. by setting headers to: ACCESS-CONTROLLE-ALLOW-ORIGIN * and the star * means allow all kind of origins. but if you want to allow a specific origin, replace the * with url of your react app. you can also use a node.js package that will help you at this in a clean and easy way, example using cors package https://github.com/expressjs/cors:

    const cors = require("cors");
    let whitelist = ["http://localhost:3000"];
    
    // Middleware
    app.use(
        cors({
            origin: function (origin, callback) {
                if (!origin) return callback(null, true);
                if (whitelist.indexOf(origin) === -1) {
                    var message =
                        "The CORS policy for this origin doesnt " +
                        "allow access from the particular origin.";
                     return callback(new Error(message), false);
    
                }
                return callback(null, true);
            },
        })
    );