Todo Data Model
What you'll build
A `todos` array of task objects `{ id, title, done }` plus three pure functions: `addTodo`, `toggleTodo`, and `listTodos` that operate on the array.
Goals
- Model a real-world entity (a task) as an object
- Use an array as a collection and mutate it safely
- Write functions that take state and return new state
- Practice unique-id generation with a counter
Prerequisites
- Objects and property access
- Arrays and array methods (push, map, find)
- Functions with parameters
Steps
- 1
Define a task shape
Decide what a single task looks like. A minimal task has an
id(number), atitle(string), and adone(boolean). Write a helpermakeTask(id, title)that returns such an object so every task is shaped consistently.Codefunction makeTask(id, title) { return { id, title, done: false }; }Expected result
makeTask(1, "Learn loops") returns { id: 1, title: "Learn loops", done: false }.
- 2
Set up the collection
Create a
todosarray and anextIdcounter starting at 1. The counter guarantees every task gets a unique id even after deletions.Codelet todos = []; let nextId = 1;Expected result
An empty list and a counter ready to assign id 1 to the first task.
- 3
Implement addTodo
Write
addTodo(title)that creates a task with the currentnextId, pushes it totodos, incrementsnextId, and returns the new task. Returning the task lets the caller know what was added.Codefunction addTodo(title) { const task = makeTask(nextId, title); todos.push(task); nextId++; return task; }Expected result
addTodo("Buy milk") returns the task and todos now has length 1.
- 4
Implement toggleTodo
Write
toggleTodo(id)that finds the task by id and flips itsdoneflag. If the id is not found, return a message. Finding by id is safer than by title because titles can repeat.Codefunction toggleTodo(id) { const task = todos.find(t => t.id === id); if (!task) return "Task not found"; task.done = !task.done; return task; }Expected result
After toggling id 1, that task's done flag flips from false to true.
- 5
Implement listTodos and test
Write
listTodos()that returns a readable list of all tasks. Then add three tasks, toggle one, and print the list to confirm the model works end-to-end.Codefunction listTodos() { return todos.map(t => `[${t.done ? "x" : " "}] #${t.id} ${t.title}` ); } addTodo("Learn loops"); addTodo("Write calculator"); addTodo("Build todo model"); toggleTodo(2); console.log(listTodos());Expected result
Three lines printed: task #2 shows [x], the others show [ ].
Try it yourself
let todos = [];
let nextId = 1;
function makeTask(id, title) {
// TODO: return a task object
}
function addTodo(title) {
// TODO: create, push, increment, return
}
function toggleTodo(id) {
// TODO: find and flip done
}
function listTodos() {
// TODO: return formatted strings
}let todos = [];
let nextId = 1;
function makeTask(id, title) {
return { id, title, done: false };
}
function addTodo(title) {
const task = makeTask(nextId, title);
todos.push(task);
nextId++;
return task;
}
function toggleTodo(id) {
const task = todos.find(t => t.id === id);
if (!task) return "Task not found";
task.done = !task.done;
return task;
}
function listTodos() {
return todos.map(t => `[${t.done ? "x" : " "}] #${t.id} ${t.title}`);
}
addTodo("Learn loops");
addTodo("Write calculator");
addTodo("Build todo model");
toggleTodo(2);
console.log(listTodos());What you learned
You modeled a real feature as data (objects in an array) plus operations (functions), and used a counter for unique ids — the same shape used by production todo apps, just with a UI on top.
Related Resources
Related Lessons
Related Practice
- Functions Concept
Functions that take state and return new state.
- Data Types MCQ
Objects and arrays — the two types this model is built from.
Related Tools
- JSON Formatter
Inspect the todos array as formatted JSON — exactly how it would be stored.
Related Cheatsheets
- JavaScript Cheatsheet
Object, array, and function syntax reference.
Related Reference
- JavaScript Array Methods
push, find, and map methods used in the model.
- JavaScript Object
Object property access and methods.
Related Errors
- Index Out of Range
Accessing invalid array indices.
- Type Error
Operating on incompatible types.
Related Glossary
A beginner-friendly glossary explains jargon in plain English — variables, functions, DOM, Promise, and more.
Related Errors
Plain-English explanations of common errors — what they mean, why they happen, and how to fix them.
- Index Out of Range
Accessing invalid array indices.
- Type Error
Operating on incompatible types.