0

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)

3 Answers 3

1

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

app.get('/weather', async (req, res, next) => { 
    const data = await apiCall();
    res.send(data);
});
Sign up to request clarification or add additional context in comments.

1 Comment

You should use res.json(...)
0

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());
    }
    
});

2 Comments

Also you should't store the Api key in your code, or post it on stack overflow lol. You should look into storing and using environment variables. I recommend a package called dotenv npmjs.com/package/dotenv You can then add variables to a .env file. The .env file should also be listen in a .gitignore file that way you can keep your secret variables like api keys hidden from bad internet people. :)
api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY} Should probably be https://www.api.openweathermap.org/data/2.5/weather?q=toronto&appid=${KEY}
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.