Introduction
In this post, we'll build a command line job search application using Node. It's a JavaScript runtime that allows the JavaScript code to run outside the browser.
We'll use the GitHub Jobs API to fetch data and present it in a tabular format on the command line interface.
We'll focus on the following three scenarios for this application:
- Job search command without any filter criteria that returns all the data
- Job search command with location filter returning data specific to that location
- Job search command with location and technology filter returning data specific to that location as well as technology
Step 1 - Setting up the project
First, create your project folder and navigate into it using the following commands:
mkdir job-search-app
cd job-search-app
Now, we'll be creating a package.json
file which holds the information about the project and the packages/dependencies we install. This is done using the following command
npm init
npm
will prompt few questions about your project before creating package.json
file. In case you want to escape the questions and have all the details filled with default values, you can use the following command
npm init -y
This will save you from the questions and generate a package.json
file directly.
Now, create a file called index.js
in the job-search-app
folder. We'll write the entire code of the application in this file.
The project structure should look like the following:
job-search-app
├──index.js
└──package.json
Step 2 - Installing the packages
- yargs - it is used to parse the command line arguments
- cli-table - it is used to display the data in a tabular format
- axios - it is used to make HTTP requests
Use the following command to install all the packages
npm install yargs cli-table axios
Now, we'll import all the packages in the index.js
file using the following lines of code.
const yargs = require('yargs');
const Table = require("cli-table");
const axios = require("axios");
Now, we'll define the header and the structure of the table that will contain the data
const dataTable = new Table({
head: ["Company Name", "Job Role", "Location", "Full Time", "Job Description"],
chars: { 'top': '' , 'top-mid': '' , 'top-left': '' , 'top-right': ''
, 'bottom': '' , 'bottom-mid': '' , 'bottom-left': '' , 'bottom-right': ''
, 'left': '' , 'left-mid': '' , 'mid': '' , 'mid-mid': ''
, 'right': '' , 'right-mid': '' , 'middle': '|' },
colWidths: [25, 30, 20, 11, 72],
style: {
head: ['bgBlue', 'white', 'bold'],
border: ['yellow']
}
});
We create a dataTable
instance using the Table
constructor function provided by the cli-table
package. An object is passed as an argument that sets the header and different properties of the table as defined below:
- head - it is an array of column header names for the table
- chars - it is an object defining how the table is drawn. Each property in the
chars
object represents the separator at the respective position - colWidths - it is an array that defines the column width
- style - it is an object that defines the style of the table.
head
property is an array that defines the background color, text color and font weight of the header.border
property is an array that defines the color of the separator
Step 3 - Creating the first command (Job search without any filter parameters)
In this step, you'll be creating your first job search command without any filter parameters.
Before writing code for the first command, let's look at the command that we'll type to run the application
node index.js searchAll
node index.js
is used to run the application and searchAll
is the command line argument passed along with it. searchAll
informs the application that it needs to do a job search and return the data on the commannd line interface. yargs
is used to parse this command line argument and perform the necessary operation.
Now, let's start with the code
yargs.command({
command: 'searchAll',
describe: 'Default search',
handler() {
axios.get("https://jobs.github.com/positions.json?markdown=true").
then(response => {
response.data.forEach(jobData => {
dataTable.push(
[jobData.company, jobData.title, jobData.location, jobData.type, jobData.url]
);
});
console.log(dataTable.toString());
});
}
});
yargs.command()
method from the yargs
package is used to create the command. An object is passed as an argument to it which defines all the options related to a particular command. The command
property is used to provide a name to the command. Here, searchAll
is the command name that we are going to use. You are free to provide any command name. The describe
property is used to provide description about the command. Here, "Default search"
is the description that we are giving to the command. You can provide any description as desired.
The handler
method holds the implementation of what the command will do. We'll call the GitHub Jobs API using axios.get()
method. axios.get()
returns a promise
and therefore, then
is chained to it which receives the response from the API.
response
is an object that is returned and response.data
is an array that holds the job data. You can now loop through the array and push the required details in the dataTable
instance as it's an array too. Once the data is pushed, the last line of code console.log(dataTable.toString())
displays the data on the command line interface in a tabular format.
At the end of the entire code, include the following line
....
....
yargs.parse();
This code is required at the end for yargs to parse our command line arguments.
Now, we can run our application using the following command:
node index.js searchAll
Step 4 - Creating the second command (Job search based on location)
In this step, you'll be creating your second command which will return job data based on the location option that you pass along with the command.
Let's look at the command first that we'll type to run the application
node index.js searchByLocation --location="india" // location can be a city name, zip code, or any other location search term.
Here, searchByLocation
is the command which is passed along with --location
option to return the job data of a particular location.
Now, add the following code block before yargs.parse()
and after the first command code:
yargs.command({
command: "searchByLocation",
describe: "Job search by location",
builder: {
location: {
describe: "Location",
demandOption: true,
type: 'string'
}
},
handler(argv) {
axios.get(`https://jobs.github.com/positions.json?markdown=true&location=${argv.location}`).
then(response => {
response.data.forEach(jobData => {
dataTable.push(
[jobData.company, jobData.title, jobData.location, jobData.type, jobData.url]
);
});
console.log(dataTable.toString());
});
}
});
This code block is similar to the previous one expect that it has an additional builder
property. The value of this property is an object which hold the options that were passed with the command; like the location
in this case.
location
property is an object where describe
is used to provide a description about the option. demandOption
is a boolean which when true
makes this option as required. type
property is used to provide the datatype of the option.
The handler
method provides the implementation of the command. Here, handler
takes an argument argv
which is an object that holds the value of options passed in the command. It can be accessed using argv.OPTION_NAME
. In this case, it is argv.location
. This value is used in the API url which then returns data for a particular location. The data is then pushed into the dataTable
instance and displayed on the command line interface.
Step 5 - Creating the third command (Job search based on location as well as technology)
Based on the previous command, we'll creating our third and final command that will return job data based on location as well as technology.
Let's look at the command first that we'll type to do a job search based on location and technology
node index.js search --location="india" --technology="react"
Here, search
is the command and --location
and --technology
are the options passed with it.
Now, add the following code block before yargs.parse()
and after the second command code:
yargs.command({
command: "search",
describe: "Job search by location and technology",
builder: {
location: {
describe: "Location",
demandOption: true,
type: 'string'
},
technology: {
describe: "Technology",
demandOption: true,
type: "string"
}
},
handler(argv) {
axios.get(` https://jobs.github.com/positions.json?markdown=true&location=${argv.location}&search=${argv.technology}`).
then(response => {
response.data.forEach(jobData => {
dataTable.push(
[jobData.company, jobData.title, jobData.location, jobData.type, jobData.url]
);
});
console.log(dataTable.toString());
});
}
});
This is similar to the previous command. Only the technology
filter is an additional parameter here which is defined in the builder
property too. The handler
holds the implementation here just like the previous commands .
Conclusion
In this post, we learned to create a command line job search application. We learned how to create a command using yargs.command()
method and how yargs.parse()
is an important line of code to be included at the end of the entire code. We also used the axios
package to trigger our API request and cli-table
to present our data in a tabular format.✌
Thanks for taking the time to read this post. I hope this post helped you!!😊😃 If you liked it, please share.
It would be great to connect with you on Twitter. Please do share your valuable feedback and suggestions👋
You can also check my other posts: