COMPUTER PROGRAMMING 1 (JAVASCRIPT) • PROBLEM SOLVING & MINI-PROJECTS

Building To-Do List — I can build a menu-based to-do list using an array with add/remove/display actions.

Combine arrays, loops, and user input to create your first interactive JavaScript application.

Historical Context & Motivation

Long before smartphones and sleek apps, people managed tasks with pen and paper. As computers entered everyday life, programmers realized that a simple to-do list was one of the most practical programs you could build. It touches every fundamental programming skill — storing data, accepting input, making decisions, and repeating actions. The to-do list has become the "Hello, World" of interactive applications because it forces you to combine multiple concepts into a single, working product.

1960s
Command-Line Interfaces Emerge
Early computers interacted with users through text-based menus. Programs would print numbered options and wait for the user to type a choice — the ancestor of every menu-driven app.
1995
JavaScript Is Born
Brendan Eich created JavaScript in just 10 days at Netscape. It gave web pages interactivity and became the most widely used language for building user-facing applications.
2000s
Arrays Become the Go-To Data Structure
As web apps grew, arrays proved to be the simplest way to store ordered lists of data. Every to-do app, shopping cart, and playlist relies on array operations like push, splice, and iteration.
2010s–Now
To-Do Apps as a Learning Standard
The to-do list became the classic first project in programming courses worldwide. Frameworks like React and Vue even use a to-do app as their official beginner tutorial.

So why build a to-do list? Because it answers a fundamental question: How do I write a program that keeps running, responds to user choices, and stores changing data? By the end of this lesson, you will have the skills to answer that question with working JavaScript code.

Core Principles & Definitions

Building a menu-based to-do list requires four core programming ideas working together. Understanding each one individually makes it much easier to see how they combine into a complete program.

1

Arrays as Data Storage

An array is an ordered collection of values stored in a single variable. In our to-do list, each element of the array is one task (a string). Arrays let you add, remove, and read items by their index position.
2

Menu-Driven Input

A menu-driven program presents the user with numbered options, reads their choice, and executes the matching action. In JavaScript, we use prompt() to collect input and if/else (or switch) to route it.
3

The Program Loop

A while loop keeps the menu visible until the user decides to quit. Without this loop, the program would run once and stop. The loop checks a boolean flag or a sentinel value each iteration.
4

CRUD Operations

CRUD stands for Create, Read, Update, Delete — the four basic operations on stored data. Our to-do list covers Create (add a task), Read (display tasks), and Delete (remove a task). These three operations form the backbone of almost every data-driven application.
✦ KEY TAKEAWAY
Think of the to-do list like a whiteboard on your wall. The array is the whiteboard itself — it holds all the items. The menu is like someone standing next to you asking, "Do you want to add something, erase something, or read what's there?" The loop keeps that person asking until you say, "I'm done." Together, these three pieces give you a complete, interactive tool.

Visual Explanation — Program Flow

Before writing code, it helps to see how all the pieces fit together. The diagram below shows the flow of a menu-based to-do list from start to finish. Notice how the loop brings the program back to the menu after every action.

The flowchart shows the program's lifecycle. After initialization, a loop displays the menu and routes the user's choice to the correct action. Add, Remove, and Display all loop back to the menu. Only "Quit" exits the loop and ends the program.

The key insight from this diagram is the cyclic nature of the program. Unlike a simple script that runs top-to-bottom and stops, a menu-driven program uses a loop to return to the starting point after every action. This pattern is extremely common — video games, ATMs, and even restaurant kiosks all follow the same basic structure.

How It Works — The Key JavaScript Methods

JavaScript provides built-in array methods that make adding and removing tasks straightforward. Let's look at the three essential operations our to-do list needs, along with the input/output functions that drive the menu.

Adding a Task — push()

The push() method appends a new element to the end of an array. When the user types a task name, we capture it with prompt() and pass it into tasks.push(newTask). The array grows by one element, and the new task sits at the highest index.

PUSH OPERATION
tasks.push("Buy groceries") → ["Study JS", "Buy groceries"]
Before: tasks = ["Study JS"]. After push: the array length increases by 1, and the new item occupies index 1.

Removing a Task — splice()

The splice() method removes (and optionally replaces) elements at a specific index. The syntax is array.splice(startIndex, deleteCount). For our to-do list, tasks.splice(index, 1) removes exactly one task at the given position. All elements after it shift down to fill the gap.

SPLICE OPERATION
tasks.splice(0, 1) → ["Buy groceries"]
Before: tasks = ["Study JS", "Buy groceries"]. After splice(0, 1): the element at index 0 is removed. "Buy groceries" shifts from index 1 to index 0.

Displaying Tasks — Looping with for

To display all tasks, we iterate through the array using a for loop. On each iteration, we print the index number (plus one, so humans see 1-based numbering) and the task string. If the array is empty, we print a friendly message like "No tasks yet!" instead.

Collecting User Input — prompt() and alert()

The prompt() function opens a dialog box and returns whatever the user types as a string. The alert() function displays a message to the user. Together, these two functions handle all communication between the program and the user in a browser environment. Keep in mind that prompt() always returns a string, so if you need a number (like a task index), you must convert it using Number() or parseInt().

Detailed Breakdown — Code Architecture

Now let's see how all the pieces fit together in actual code. The diagram below shows the complete structure of our to-do list program, highlighting how each section maps to the concepts we've discussed.

Left panel: pseudocode showing the structure of the program. Right panel: a plain-English explanation of each colored section. The while loop wraps everything, and the flag variable controls when it stops.

Notice the nesting: the if/else if chain lives inside the while loop, and each branch contains its own logic. This layered structure is called nesting, and it is completely normal in menu-driven programs. Indentation is your best friend for keeping track of which block you're inside.

⚠️ Common Pitfall
Remember that prompt() returns a string, not a number. If the user types "2" and you compare it with === to the number 2, the condition will be false. Always compare to string literals like "2", or convert the input using Number(choice).

Worked Example — Building the Complete Program

Let's walk through building the full to-do list program step by step. Each step adds a new capability, and by the end, you'll have a fully functioning interactive application.

Building a Menu-Based To-Do List
1
Step 1 — Declare the Array and FlagStart by creating an empty array to store tasks and a boolean variable to control the loop. let tasks = []; creates an empty array. let running = true; sets a flag that the while loop will check each cycle.
let tasks = []; let running = true;
2
Step 2 — Create the While Loop and Menu PromptWrap all logic in while (running) { ... }. Inside the loop, use prompt() to display the menu and capture the user's choice. Use \n to put each option on a new line.
while (running) { let choice = prompt("To-Do List Menu:\n1. Add Task\n2. Remove Task\n3. Display Tasks\n4. Quit");
3
Step 3 — Implement the Add ActionWhen the user enters "1", prompt them for a task name and push it onto the array. Then confirm the addition with alert().
if (choice === "1") { let task = prompt("Enter a new task:"); tasks.push(task); alert('"' + task + '" has been added!'); }
4
Step 4 — Implement the Remove ActionWhen the user enters "2", first display the tasks so they can see the numbers, then ask which number to remove. Convert the input to a number, subtract 1 (because we show 1-based numbering but arrays are 0-based), and validate the index before calling splice().
} else if (choice === "2") { if (tasks.length === 0) { alert("No tasks to remove!"); } else { let list = ""; for (let i = 0; i < tasks.length; i++) { list += (i + 1) + ". " + tasks[i] + "\n"; } let num = Number(prompt("Which task number?\n" + list)); if (num >= 1 && num <= tasks.length) { let removed = tasks.splice(num - 1, 1); alert('"' + removed[0] + '" removed!'); } else { alert("Invalid number."); } } }
5
Step 5 — Implement Display and QuitFor display, loop through the array and build a string, then show it with alert(). For quit, set running = false so the while loop ends on the next check. Add a final else clause for invalid inputs.
} else if (choice === "3") { if (tasks.length === 0) { alert("No tasks yet!"); } else { let list = "Your Tasks:\n"; for (let i = 0; i < tasks.length; i++) { list += (i + 1) + ". " + tasks[i] + "\n"; } alert(list); } } else if (choice === "4") { running = false; alert("Goodbye!"); } else { alert("Please enter 1, 2, 3, or 4."); } } // end while
🧩 PUTTING IT ALL TOGETHER
Each step above adds one building block. The final program is roughly 35 lines of code, yet it creates a genuinely interactive experience. Copy all the result blocks together in order, paste them into your browser console or an HTML file's <script> tags, and you'll have a working to-do list.

Strengths, Limitations & Alternatives

Our prompt/alert-based to-do list is an excellent learning tool, but it has trade-offs compared to other approaches. Understanding these helps you appreciate what you've built and what comes next.

Comparison of strengths and limitations of the prompt/alert to-do list approach.
AspectStrengthsLimitations
User InterfaceWorks in any browser with zero setup. No HTML or CSS required.Prompt/alert dialogs are clunky and block the page. You can't see the list and the menu at the same time.
Data PersistenceSimple array storage is easy to understand and debug.All tasks vanish when you refresh the page. There is no save mechanism.
ScalabilityGreat for small lists. Array operations are fast for dozens of items.No categories, priorities, or due dates. Hard to extend without restructuring.
Error HandlingBasic validation (checking index range) is straightforward to add.If the user clicks Cancel on a prompt, it returns null, which could cause bugs if not handled.
🔭 THE BIGGER PICTURE
Every real-world to-do app — Todoist, Apple Reminders, Google Tasks — is built on the exact same CRUD pattern you just learned. They simply replace prompt() with fancy input fields and swap the array for a database. The logic underneath is the same.

Connection to Advanced Concepts

The menu-driven to-do list you've built is a stepping stone to far more powerful applications. The table below compares what you've done here with what you'll encounter as you continue learning JavaScript and web development.

How today's concepts evolve into professional-grade tools.
This LessonNext Level
prompt() and alert() for I/OHTML forms with <input> elements and DOM manipulation for a real web page UI.
Array of stringsArray of objects — each task stores a name, priority, due date, and completion status.
Data lost on refreshlocalStorage to save tasks in the browser, or a back-end database for permanent storage.
if/else if chainEvent listeners (addEventListener) that respond to button clicks, replacing the menu loop entirely.
Procedural code in one fileFunctions, modules, or even frameworks like React that organize code into reusable components.

The most important lesson here is that the core logic never changes. Whether you're using prompt boxes or a React interface, your program still needs to store data, accept input, decide what to do with it, and update the display. Mastering this pattern now gives you a head start on everything that follows.

Practice Problems

PROBLEM 1 — CONCEPTUAL
Why does the to-do list program use a while loop instead of just running the code from top to bottom? What would happen without the loop?
PROBLEM 2 — BASIC CALCULATION
Suppose tasks = ["Math HW", "Read Ch. 5", "Laundry"]. The user wants to remove "Read Ch. 5". They see it listed as item 2 in the display. Write the exact splice() call that removes it, and state what the array looks like afterward.
PROBLEM 3 — INTERMEDIATE
Modify the remove feature so that if the user enters a number that is less than 1 or greater than the array length, the program shows an error message instead of crashing. Write the JavaScript code for the entire "remove" branch, including the validation.
PROBLEM 4 — APPLIED
A student wants to add a fifth menu option: "5. Clear All Tasks" that empties the entire list at once. Write the JavaScript code for this new option and explain which array technique you would use and why.
PROBLEM 5 — CRITICAL THINKING
Right now, every task is just a string. Suppose you wanted each task to also store whether it's been completed (true or false). How would you change the data structure? Sketch out how the add, display, and a new "mark as done" feature would work with this new structure. You don't need full code — pseudocode or a detailed explanation is fine.

Lesson Summary

In this lesson, you built a complete menu-based to-do list using JavaScript. The program stores tasks in an array, uses prompt() and alert() for user interaction, and keeps running through a while loop controlled by a boolean flag. You learned three essential array operations: push() to add tasks, splice() to remove them by index, and a for loop to display them all.

This project demonstrated the CRUD pattern (Create, Read, Delete) that powers virtually every data-driven application. You also practiced input validation by checking array bounds before removing a task, and you handled the string vs. number distinction that trips up many beginners. Moving forward, you can upgrade this project with HTML interfaces, localStorage for persistence, and object-based tasks with completion status — all building on the exact same logic you mastered today.

Varsity Tutors • Computer Programming 1 (JavaScript) • Building To-Do List