Jalal Qureshi
Jalal Qureshi

Reputation: 35

Problem sending json from express to react

I'm learning express and having an issue sending json from my express server to my react app.

On my express server I do an API call to openweathermap API and then send the JSON to react where I pick it up using axios. The problem is, my react app will get the JSON but the data field will be blank, I tried manually sending a JSON using res.json({name:"blank"}) and that sent but the result from my API call won't.

The first code snippet is my Express server and the second snippet is my React app. The last snippet is the error I am getting.

const express = require('express');

const path = require('path');

const app = express();

const fetch = require('node-fetch');

app.get('/test', (req, res) =>
    res.send('Welcome to backend this is from node')
);

const port = process.env.PORT || 3001;

app.listen(port);

console.log('App is listening on port ', port);

const apiCall = async () => {
    try {
        const KEY = fd3909829b4fbfcfcca7c595a56c7632;
        const api_res = await fetch(
            'api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY}'
        );
        response = await api_res.json();
        console.log(response);
        return response;
    } catch (error) {
        console.log('error: ', error);
    }
};

app.get('/weather', async (req, res) => {
    const data = await apiCall();
    res.json(data);
});

import React from 'react';
import './App.css';
import axios from 'axios';

import Weather from './components/weather';

const hitBackend = () => {
    axios.get('/weather').then((res) => {
        console.log(res);
    });
};

function App() {
    return (
        <div className='App'>
            <Weather />
            <button onClick={hitBackend}>Send Request!</button>
        </div>
    );
}

export default App;
error:  ReferenceError: fd3909829b4fbfcfcca7c595a56c7632 is not defined
[server]     at apiCall (C:\Users\Jalal\Desktop\Coding\React\weather\server\index.js:21:15)
[server]     at C:\Users\Jalal\Desktop\Coding\React\weather\server\index.js:34:21
[server]     at Layer.handle [as handle_request] (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\layer.js:95:5)
[server]     at next (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\route.js:137:13)
[server]     at Route.dispatch (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\route.js:112:3)
[server]     at Layer.handle [as handle_request] (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\layer.js:95:5)
[server]     at C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\index.js:281:22
[server]     at Function.process_params (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\index.js:335:12)
[server]     at next (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\router\index.js:275:10)
[server]     at expressInit (C:\Users\Jalal\Desktop\Coding\React\weather\node_modules\express\lib\middleware\init.js:40:5)

Upvotes: 0

Views: 2165

Answers (3)

Isaiah Ballah
Isaiah Ballah

Reputation: 16

Your API key variable isn't being set properly

const KEY = fd3909829b4fbfcfcca7c595a56c7632;

Should be

const KEY = "fd3909829b4fbfcfcca7c595a56c7632";

Next you are not handling errors correctly. Because you are catching the error(s) in the callApi method, when you are sending the response back to react, you have no way of knowing if the apiCall function succeeded or not.

Also in order to use the ${} notation in a string, you need to use `` instead of " ".

so

'api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY}'

Becomes

`https://www.api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY}`

This is how I would code it to properly catch errors and also let react know if the request failed.

app.get('/weather', async (req, res) => {
    try {
        const KEY = "fd3909829b4fbfcfcca7c595a56c7632";
        const api_res = await fetch(
            `https://www.api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY}`
        );
        response = await api_res.json();
        console.log(response);
        return res.json(response);;
    } catch (error) {
        console.log('error: ', error);
        return res.status(400).send('error: ' + error.toString());
    }
    
});

Upvotes: 0

Juan Cerrutti
Juan Cerrutti

Reputation: 1

The main problem on your express app is that you are not awaiting the apiCall method on your route. So, the function is executing but not awaiting the async code that you had over there.

So, you will need to await that, like this:

app.get("/weather", async (req, res, next) => {
  const weather = await apiCall()
  res.send(weather);
});

Also, I see that you are using fetch for getting the API response from weather, but not requiring any module. Fetch is a browser API. You can install node-fetch or use axios for this purpose.

Upvotes: 0

Prateek Thapa
Prateek Thapa

Reputation: 4938

You need to await your apiCall since it's asynchronous.

app.get('/weather', async (req, res, next) => { 
    const data = await apiCall();
    res.send(data);
});

Upvotes: 1

Related Questions