Courses Learn Blog Contact
Get Started →
Lesson 5

Day 5: Project 1 - Make It Work

The first solo project: a task application built from a problem statement, with the ten requirements, the marking rubric and the Friday defence.

Webbo3 Level 2: JavaScript Development 15 min read Free

Webbo3 Level 2 · JavaScript Development · Day 5 of 20

Project 1: Make It Work

Your first solo build. A problem statement, not a tutorial, and a Friday where you have to defend what you wrote.

By the end of today you can

  • Turn a problem statement into a working application without being given steps
  • Use everything from Days 1 to 4 in one codebase
  • Push it to GitHub with a README somebody else could follow
  • Demonstrate it live and explain any line of it you are asked about

There is no tutorial today. You are given a problem and a standard, and the gap between them is the work. This is deliberate: copying a tutorial teaches you to copy tutorials, and the first time you face a blank file with nobody to copy is the first time you find out whether you can actually do this. Better that it happens here, on a Friday, with your instructor in the room.

The brief

Project 1 · Solo · One day

Build a personal task and productivity application that lets a person create, complete, edit, delete, filter and search their tasks. It runs entirely in the browser. No backend, no framework, no library.

That is the entire brief, and it is meant to feel slightly too open. Decide the rest yourself: what a task looks like, what happens to a completed one, what the empty state says. Those decisions are the part being assessed.

What it must do

#RequirementProves you understood
1Add a task from a text fieldEvents, form handling, preventDefault
2Refuse an empty task with a visible messageValidation, falsy values
3Mark a task complete and uncomplete againclassList.toggle, state
4Edit the text of an existing taskFinding one item, updating it
5Delete a taskEvent delegation, closest
6Filter: all, active, completedfilter, re-rendering from data
7Search tasks as the user typesThe input event, filter
8A count of what is leftfilter().length, derived values
9An empty state when there is nothing to showThinking about the user
10Works on a phone-width screenLast month's CSS, still your job

The one rule about how you build it

Keep your data in an array and render the page from it. Do not treat the DOM as your store of truth: do not read the list back off the page to find out what tasks exist. One array of task objects, one render() function that draws it, and every action changes the array and calls render() again.

JSapp.js
// the shape the whole project hangs off
let tasks = [
  { id: 1, text: 'Finish Day 4 exercise', done: true  },
  { id: 2, text: 'Push project to GitHub', done: false }
];

let filter = 'all';        // 'all' | 'active' | 'completed'
let search = '';

function visibleTasks() {
  return tasks
    .filter((t) => filter === 'all'
                || (filter === 'active' && !t.done)
                || (filter === 'completed' && t.done))
    .filter((t) => t.text.toLowerCase().includes(search.toLowerCase()));
}

console.log('all:', visibleTasks().length);
filter = 'active';
console.log('active:', visibleTasks().map((t) => t.text));
search = 'github';
console.log('active + search "github":', visibleTasks().map((t) => t.text));
Console

Notice visibleTasks() does not touch the page at all. It answers one question: given the current filter and search, which tasks should be on screen? Your render() then draws whatever it returns. Separating "what is true" from "what is drawn" is the single most useful structural idea in this project, and it is what React will do for you automatically in Level 3.

Why every task needs an id

You need to know which task a Delete button belongs to. Storing the id on the element with data-id and reading it back with event.target.closest('li').dataset.id is the standard way. Do not use the array index: it changes the moment anything is deleted, and you will delete the wrong row.

JSapp.js
// in render(): stamp the id onto the element
`<li data-id="${task.id}" class="${task.done ? 'done' : ''}"> ... </li>`

// in the delegated listener: read it back
const id = Number(event.target.closest('li').dataset.id);
const task = tasks.find((t) => t.id === id);

Number() there is not decoration. Everything in dataset is a string, so t.id === id compares a number to a string and is always false. That is Day 1 coming back to bite, and it will cost somebody in your cohort an hour today.

What to hand in

  1. A public GitHub repository with real commit messages. Not one commit called "final". At least six, each describing what changed.
  2. A README with: what it does, a screenshot, how to run it, and one honest paragraph on what you would improve with more time.
  3. The project folder structured the way you learned last month: index.html at the root, css/, js/.
  4. A deployed link if you can manage it. GitHub Pages is free and takes ten minutes. Not required today, required from Day 18.

The Friday evaluation

You do not submit and go home. You demonstrate, and you answer questions. Fifteen minutes each.

PartWhat happensMarks
DemoYou drive. Show every one of the ten requirements working.30
Code walkthroughOpen your JavaScript and explain how the render loop works.20
The bug storyDescribe one bug you hit, how you found it, and how you fixed it.15
Three questionsTechnical questions on your own code, picked live.20
Repo and READMECommit history, structure, and a README that helps.15

The rule that governs everything from here

Never submit code you cannot explain. If you cannot say what a line does and why it is there, it does not belong in your project yet. This applies equally to code you found online and code an AI wrote for you, and it is the standard the whole of Week 4 is built on.

The kind of question you will be asked

  • Show me where the task actually gets deleted. Why does that work for a row you added thirty seconds ago?
  • You used === here and == nowhere. What would break if you swapped them?
  • Your search runs on every keystroke. What happens with two thousand tasks?
  • If I typed <b>hello</b> as a task, what appears on screen, and why?
  • Walk me through what happens, in order, between my click and the row disappearing.
How do I prepare for questions I have not seen?

You do not memorise answers. The evening before, do this instead: open your own file and read it top to bottom out loud, saying what each block does. Anywhere you hesitate is a question you cannot answer yet, so go and understand that part.

That exercise takes twenty minutes and it is the single highest-return thing you can do the night before any technical interview for the rest of your career.

The marking rubric

BandWhat it looks like
Distinction, 85+All ten requirements work. Data lives in an array and the page is rendered from it. One delegated listener, not many. User text handled with textContent. Readable names, small functions. README somebody else could follow. Answers every question without hesitating.
Strong, 70 to 84All ten work. Structure mostly clean with some repetition. Explains the code confidently with one or two gaps.
Pass, 50 to 69Seven or more requirements work. Code runs but reads the DOM as its source of truth, or attaches a listener per button. Can explain most of it.
Not yet, below 50Requirements missing, or code the student cannot explain. Resubmit Monday.

If you finish early

Do not add features. Do two things instead: delete every line that is not earning its place, and rename anything called data, temp, x or handleClick2. A smaller, clearly-named project marks higher than a bigger confused one, every single time.

Questions you will have today

I am stuck and it is 11am. Do I ask for help?

Yes, after fifteen minutes of your own attempt and not before. Before you ask, write down three things: what you expected, what actually happened, and the two things you have already tried.

That is not a hoop to jump through. Writing those three lines solves the problem outright surprisingly often, and when it does not, it turns "it is not working" into a question somebody can actually answer in thirty seconds.

Can I use code from a tutorial or from an AI?

Yes, on one condition, and it is the same condition for both: you must be able to explain every line of it. You will be asked about specific lines this afternoon, picked at random. Code you pasted and did not read is code that will cost you marks, not because it was pasted but because you cannot defend it.

I finished the ten requirements by 2pm. What now?

Do not add an eleventh. Spend the time on three things instead: delete every line that is not doing anything, rename anything vague, and hand your laptop to the person next to you and watch them use it without helping. Every place they hesitate is a real finding, and you cannot see those yourself because you already know where everything is.

Mine looks plain compared to the person beside me. Does that matter?

Not today. The rubric has no marks for visual design and twenty for whether the data and the render are separated properly. A plain project where deleting a row updates the count correctly marks well above a beautiful one where it does not. Make it work, then make it nice, in that order.

Tick before you move on

  • All ten requirements work, and I checked each one deliberately
  • My tasks live in an array and the page renders from it
  • Delete uses one delegated listener and a real id, not an index
  • I tested with <b>bold</b> as a task name
  • Six or more meaningful commits and a README with a screenshot
  • I read my own code aloud and can explain every line

Quick recap

A problem statement, not steps: the decisions are the assessment · One array of truth, one render function, every action re-renders · Ids on elements with data-id, read back with Number() · Never submit code you cannot explain, whoever or whatever wrote it

Next week: JavaScript that talks to the outside world. Modules, asynchronous code, HTTP and real APIs, ending in your first group build.

Learn this with a real instructor

Free lessons take you a long way on your own. The full programmes add live classes, assignments, Skill Points and a certificate — built for African students.