Code a bus schedule CLI with Node.js and Python [ + Sqlite3 ]
Tags: node, javascript, sql, beginners
Published: 2023-03-12 17:29:40

Hey guys 👋 
This is a tutorial on how to create a bus schedule system using Node JS [ +bonus: Python version in the video].
I realized that a lot of beginner programmers jump immediately to learn React and Vue right after learning the basics of JavaScript; in fact that is a fatal mistake, you need to be aware of ES6, prototype, higher order functions, arrow functions, promises, callback functions, and so on and so forth.
So in this tutorial, I am building a simple command line application that allows users to view and update a bus schedule. The application uses several external packages, including Figlet, Chalk, SQLite3, and Readline.

The first section of the code sets up the SQLite3 database and initializes it with some initial bus schedule data. We create a new database connection using the sqlite3 package and then create a new table called schedule. The schedule table has two columns: time and route. The time column is set as the primary key, meaning that it must be unique for each row in the table. We then create an array of initial schedule data and use a prepared statement to insert the data into the schedule table.

```javascript
import figlet from 'figlet';
import chalk from 'chalk';
import sqlite3 from 'sqlite3';
import readline from 'readline';

const db = new sqlite3.Database('bus_schedule.db');
db.serialize(() => {
  db.run('CREATE TABLE IF NOT EXISTS schedule (time TEXT PRIMARY KEY, route TEXT)');
  const initialSchedule = [
    ['8:00am', 'Route 1'],
    ['9:30am', 'Route 2'],
    ['11:00am', 'Route 3'],
    ['1:00pm', 'Route 1'],
    ['2:30pm', 'Route 2'],
    ['4:00pm', 'Route 3']
  ];
  const stmt = db.prepare('INSERT OR IGNORE INTO schedule (time, route) VALUES (?, ?)');
  initialSchedule.forEach((scheduleItem) => {
    stmt.run(scheduleItem);
  });
  stmt.finalize();
});
```

Next, we use the Figlet package to generate a large ASCII art heading for our application. If the Figlet package encounters an error, we print an error message to the console and exit the application. Otherwise, we print the heading to the console in blue text.
After printing the heading, we use the Chalk package to print the current bus schedule from the database to the console. We use the db.all() method to retrieve all rows from the schedule table and then use a forEach loop to print each row to the console in green and yellow text.

```javascript
// Print the heading using Figlet
figlet('Bus Schedule', (err, heading) => {
  if (err) {
    console.log(chalk.red('Error: Failed to generate heading.'));
    return;
  }
  console.log(chalk.blue(heading));

  // Print the current schedule from the database using Chalk
  console.log('Current bus schedule:');
  db.all('SELECT * FROM schedule', (err, rows) => {
    if (err) {
      console.log(chalk.red('Error: Failed to retrieve bus schedule.'));
      return;
    }
    rows.forEach((row) => {
      console.log(chalk.green(row.time) + ': ' + chalk.yellow(row.route));
    });
    console.log('');
    promptUser();
  });
});
```

Finally, we define a promptUser() function that uses the Readline package to prompt the user for new bus schedule data. The function creates a new Readline interface and uses the rl.question() method to prompt the user to enter a new bus route and time. If the user enters an empty string, we print a goodbye message to the console, close the database connection, and exit the application. Otherwise, we parse the user input and use a prepared statement to insert the data into the schedule table. If the insertion is successful, we print a success message to the console and call the promptUser() function again to prompt the user for more data.
```javascript
// Prompt the user to enter new bus routes and times and update the database
function promptUser() {
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
  rl.question('Enter a new bus route and time (e.g. \'5:00pm Route 4\'), or press enter to quit: ', (input) => {
    rl.close();
    if (input.trim() === '') {
      console.log('Goodbye!');
      db.close();
      return;
    }
    const [time, route] = input.trim().split(' ');
    if (!time || !route) {
      console.log(chalk.red('Error: Invalid input. Please enter the bus route and time in the correct format.'));
      promptUser();
      return;
    }
    db.run('INSERT OR IGNORE INTO schedule (time, route) VALUES (?, ?)', [time, route], (err) => {
      if (err) {
        console.log(chalk.red('Error: Failed to add new bus route.'));
        promptUser();
        return;
      }
      console.log(chalk.green('New bus route added successfully!'));
      promptUser();
    });
  });
}

```

If you want to see how to do the same app with Python, check out the video tutorial:

{%youtube DZUl3oJGZTk %}

Overall, this CLI app demonstrates how to build a simple command line application which uses few external packages to generate a bus schedule colored, and allows you to alter the schedule by only adding routes and time using SQLite3 database. 
The application is designed to be simple and easy to use, with clear prompts and error messages to guide the user.
I hope you will like it, if so please do not forget to like the video, share it with your friends and subscribe to my channel to not miss the new tutorials and shorts uploaded each week.

Connect with me on social media:
* Follow me on Twitter: https://twitter.com/BekBrace
* Like my Facebook page: https://www.facebook.com/bekbrace/
* Follow me on Instagram: https://www.instagram.com/bek_brace/