COVID19 Lockdown Dev Log – Day 27, Simple HTTP Request In NodeJs

What I Worked On

The Weather App.

What I Learned

I use Axios for sending HTTP requests in my weather app. I got curious and wanted to try and do it without an HTTP client module from npm and instead use NodeJs’ own core HTTP module.

Let’s import the HTTP module and add a URL to request from. The URL is from WeatherStack where I have an account that provides an API key. The key is replaced with ‘myAPIkey’ in this example 🙂

const http = require('http');

const url = `http://api.weatherstack.com/current?access_key=myAPIkey&query=55.067434,10.607282`

Next up we setup the request. We call the ‘http.request’ function from the HTTP module and store it in a variable. The function takes two arguments, the url and a callback function:

const request = http.request(url, (response) => {
    response.on('data', () => {
    
    })
})

NodeJs listens for the HTTP data which can come streamed in multiple chuncks. Therefore we need to listen for all these chuncks of data coming in and for when the request/stream is done. We start by using ‘on()’, which is a function that allows us to register a handler. There are a few events we can register handlers on in the ‘on()’ and the one we need is ‘data’, which is provided as a string argument followed by a callback function:

const request = http.request(url, (response) => {
    response.on('data', (dataChunk) = {
      console.log(dataChunk)
    })
})

The data (dataChunk) that we receive is a databuffer (link to Buffers in NodeJs is in Resources), which returns raw data that, in this case, looks like this:

<Buffer 7b 22 72 65 71 75 65 73 74 22 3a 7b 22 74 79 70 65 22 3a 22 4c 61 74 4c 6f 6e 22 2c 22 71 75 65 72 79 22 3a 22 4c 61 74 20 34 30 2e 30 30 20 61 6e 64 ... 671 more bytes>

Let’s make it readable. We need to stringify it and convert it to a JSON object so we can read it. We can create a variable ‘data’, which will be an empty string and then add the raw data to it like so:

const request = http.request(url, (response) => {
    let data = ''
    response.on('data', (dataChunk) = {
      data = data + dataChunk.toString()
      console.log(dataChunk)
    })
})

Great! Now we have our data in a string. Last thing we need to do is convert it to a JSON object with JSON.parse(). Let’s think about it: We want to it when we have all the datachunks from the stream, which would be when it ends. To do that we use the ‘end’ event with ‘on()’, which fires once the stream ends:

    response.on('end', () => {
        const dataBody = JSON.parse(data)
        console.log(dataBody)
    })

Lastly we need to end the request with ‘http.end’. Since we have the HTTP stored in the variable, ‘request’, we call it like so at the end of our script:

request.end()

For the sake of it let’s add some error handling to the script. We will use the ‘on()’ with the ‘error’ event. It takes the event as a string and a callback function, which returns the error:

request.on('error', (error) => {
    console.log('Error occured: ', error)
})

There! Let’s run the script:

node httpscript
{
  request: {
    type: 'LatLon',
    query: 'Lat 55.07 and Lon 10.61',
    language: 'en',
    unit: 'm'
  },
  location: {
    name: 'Pasop',
    country: 'Denmark',
    region: 'Syddanmark',
    lat: '55.067',
    lon: '10.600',
    timezone_id: 'Europe/Copenhagen',
    localtime: '2020-05-01 17:34',
    localtime_epoch: 1588354440,
    utc_offset: '2.0'
  },
  current: {
    observation_time: '03:34 PM',
    temperature: 9,
    weather_code: 266,
    weather_icons: [
      'https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0017_cloudy_with_light_rain.png'
    ],
    weather_descriptions: [ 'Light drizzle' ],
    wind_speed: 27,
    wind_degree: 83,
    wind_dir: 'E',
    pressure: 1007,
    precip: 3.3,
    humidity: 92,
    cloudcover: 100,
    feelslike: 5,
    uv_index: 4,
    visibility: 5,
    is_day: 'yes'
  }
}

Awesome! It works. We get the weather data and return it in a JSON format 😀 To clarfy the final script ends up looking like this:

const http = require('http');

const url = `http://api.weatherstack.com/current?access_key=myAPIkey&query=55.067434,10.607282`

const request = http.request(url, (response) => {
    let data = '';
    response.on('data', (chunk) => {
        data = data + chunk.toString()
    })

    response.on('end', () => {
        const dataBody = JSON.parse(data)
        console.log(dataBody)
    })
    
})

request.on('error', (error) => {
    console.log('Error occured: ', error)
})

request.end()

What Distracted Me During The Day

  • Lots of phone calls
  • Messenger

Resources