Create a Node.js Weather App - Get the weather from the command line

In this article, we’ll make a weather app CLI (command-line interface). We’ll use the OpenWeather API, axios, and pure Node.js. So before we get started, head on over to OpenWeather and create an account, you’ll need an API key to continue with the article.

Setting up

Create a new directory, called weather, with a file index.js:

user@user:~$ mkdir weather
user@user:~$ touch index.js

We’re also going to need to initiate npm:

user@user:~$ npm init

Just hit enter for each prompt.

Now that we got that out of the way, let’s install axios:

user@user:~$ npm i axios

Axios is a promise based HTTP client for the browser and node.js. Basically, it’s what we’re going to use to fetch data from the OpenWeather API.

Your folder structure should now look like this:

user@user:~$ ls
index.js node_modules package.json package-lock.json

Now that our project is set up, let’s start writing our code.

Setting up index.js

We’re going to need to include some things before we begin prompting users for their location, such as a way to make our file executable, import the axios library, and setting some API information.

#!/usr/bin/env node
const axios = require("axios");

const BASE_PATH = "http://api.openweathermap.org/data/2.5/weather";
const API_KEY = "<your key here>";

Note: To get your API key, click your username on the navigation bar on the OpenWeather website. Select “My API keys”. Copy and paste it to the API_KEY variable.

To make our file executable, we’ll need to run a command: chmod +x index.js. After entering this command, we’ll be able to run our file by typing ./index.js. Note: Our file can still be executed by typing node index.js.

We can now start writing some code.

First, we need to be able to prompt users for their location. We can accomplish this with a function, prompt:

const prompt = (message, callback) => {
  const stdin = process.stdin;
  const stdout = process.stdout;

  stdin.resume();
  stdout.write(message);

  stdin.once("data", (data) => {
    callback(data.toString().trim());
  });
};

(Using the DRY principle, this is the same function we used in this article).

The above function will ask a user for their location and then do something (i.e. fetch data from the API) with that information via the callback.

Let’s call the function:

prompt("Enter a location or a postal code: ", function (location) {
  if (!location) {
    console.log("Please try again");
    process.exit();
  }
});

And test it out:

user@user:~$ ./index.js
Enter a location or a postal code:

Nothing will actually happen yet, as we haven’t implemented our API call. Lets do that now.

prompt("Enter a location or a postal code: ", function (location) {
  if (!location) {
    console.log("Please try again");
    process.exit();
  }

  axios
    .get(`${BASE_PATH}?q=${location}&units=imperial&appid=${API_KEY}`)
    .then((response) => {
      const weather = response;
      const message = `\nCurrent date and time: ${weather.headers.date}\nIt's ${weather.data.main.temp} degrees in ${location}.`;

      console.log(message);
      process.exit();
    })
    .catch((err) => {
      console.log(`Error: ${err.response.data.message}`);
      process.exit();
    });
});

We’ve now added our API call. First, axios will .get the data based on the location entered. It’s in the parameter as ${location}, along with the API key that we defined at the beginning of this article. Then, we’ll store the response in a variable called weather, which we’ll use in the message variable to access the date, temperature, and location.

After our data is fetched, and we have then stored it in a variable (message), we’ll log it to the console, exiting the process, as it’s complete.

If it fails (e.g. an invalid location was entered), an error message will be logged to the console instead.

Full Code

#!/usr/bin/env node
const axios = require("axios");

const BASE_PATH = "http://api.openweathermap.org/data/2.5/weather";
const API_KEY = "<your key here>";

const prompt = (message, callback) => {
  const stdin = process.stdin;
  const stdout = process.stdout;

  stdin.resume();
  stdout.write(message);

  stdin.once("data", (data) => {
    callback(data.toString().trim());
  });
};

prompt("Enter a location or a postal code: ", function (location) {
  if (!location) {
    console.log("Please try again");
    process.exit();
  }

  axios
    .get(`${BASE_PATH}?q=${location}&units=imperial&appid=${API_KEY}`)
    .then((response) => {
      const weather = response;
      const message = `\nCurrent date and time: ${weather.headers.date}\nIt's ${weather.data.main.temp} degrees in ${location}.`;

      console.log(message);
      process.exit();
    })
    .catch((err) => {
      console.log(`Error: ${err.response.data.message}`);
      process.exit();
    });
});

Conclusion

You might want to expand on this small program to make it better. For example, you might want to store your API keys more securely. You can create some environment variables to hide your key. Whatever you decide to do, please share it with us in the comments below.

Happy coding!

comments powered by Disqus

Related Posts

Creating a Real Time Chat Application with React, Node, and TailwindCSS

In this tutorial, we will show you how to build a real-time chat application using React and Vite,as well as a simple Node backend.

Read more

The Importance of Staying Active as a Software Developer

In today’s fast-paced digital world, developers often find themselves glued to their screens for extended periods. While this dedication is commendable, it comes with its own set of challenges.

Read more

JavaScript DOM Mastery: Top Interview Questions Explained

Mastering the Document Object Model (DOM) is crucial for any JavaScript developer. While many developers rely heavily on front-end frameworks, the underlying DOM concepts are still important.

Read more