0

I'm new to node. I created a simple server. The idea is that at each request, this servers makes an http request to a Weather API, and when it gets the answer, it send the answer to the client. I think the server is sending the answer too fast. This is my code:

    var http = require("http");

    function getWeather()
    {
        var http2 = require("http");

        http2.get("http://api.openweathermap.org/data/2.5/weather?lat=48.914348&lon=2.300282&appid=blabla123456&units=metric", (resp) => {
            let data = '';
            var answer = '-';

            resp.on('data', (chunk) => {
                data += chunk;
            });

            resp.on('end', () => {
                answer += JSON.parse(data).name + ", " + JSON.parse(data).sys.country + "\n" +JSON.parse(data).main.temp + "C";
                return(answer);
            });
        }).on("error", (err) => {
            console.log("Error: " + err.message);
        });
    }

    function hi(){
        return(5);
    }

    http.createServer(function (request, resp) {
        resp.writeHead(200, {'Content-Type': 'text/plain'});
        resp.end("Answer: " + hi() + " " + getWeather());
    }).listen(8080);

    console.log('Server running');

As you see, function getWeather returns answer, and function hi returns 5. My server response is "Answer: 5 undefined", so the getAnswer() return isn't presented, but the hi() return is there.

In the console, answer is printed after my server's answer, and it is exactly what I want it to show, but just too late.

Hope you can help me to solve this :)

Thanks!

3
  • Nothing to do with your error, but you should JSON.parse only once. const result = JSON.parse(data); and then use: result.name, result.sys.country.... Your actual error is that getWeather is asynchronous, and you should wait until the request is done before calling: resp.end. Check the duplicate. Commented Jun 11, 2018 at 22:58
  • Duplicate of How do I return the response from an asynchronous call? Commented Jun 11, 2018 at 22:59
  • 1
    Thanks for the advice, I'll optimise my JSON parsing ;) Commented Jun 11, 2018 at 23:25

1 Answer 1

1

Because this event takes time to process, you cannot return it. Try using a callback instead!

function getWeather(callback)
    {
        var http2 = require("http");

        http2.get("http://api.openweathermap.org/data/2.5/weather?lat=48.914348&lon=2.300282&appid=blabla123456&units=metric", (resp) => {
            let data = '';
            var answer = '-';

            resp.on('data', (chunk) => {
                data += chunk;
            });

            resp.on('end', () => {
                answer += JSON.parse(data).name + ", " + JSON.parse(data).sys.country + "\n" +JSON.parse(data).main.temp + "C";
                callback(answer);
            });
        }).on("error", (err) => {
            console.log("Error: " + err.message);
        });
    }

Then for the http request

http.createServer(function (request, resp) {
        resp.writeHead(200, {'Content-Type': 'text/plain'});
        getWeather(function(data) {
            resp.end("Answer: " + hi() + " " + data);
        });
    }).listen(8080);

If you can't tell, this works by calling a function that is sent when the data is ready.

Sign up to request clarification or add additional context in comments.

2 Comments

Works, it's perfect, thanks! So the idea is that the server receives a request, it calls my getWeather function, and as a parameter I pass a function that will make the resp.end() with my data when everything is done. Nice, thanks!
this is a relatively simple way of doing it. If you want to get better, id suggest trying to use promises, or even more advanced - using async/await

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.