DMarlon Studio

Lección 20 · 20 de 20

Proyecto: lista de tareas · JavaScript

Un pequeño proyecto en JavaScript que lo reúne todo: una lista de tareas con órdenes de texto, objetos, arrays, funciones, errores y JSON.

JavaScript · Proyecto: lista de tareas en DMarlon Studio: el código del ejemplo y su salida en la terminal

Este programa junta lo visto en el curso en una lista de tareas que se maneja con órdenes de texto: add añade una tarea, done la marca como hecha y remove la quita. Las órdenes están en el array commands, como si alguien las hubiera tecleado.

Cada tarea es un objeto con id, title y done, y todas se guardan en el array tasks. nextId es un let porque aumenta con cada tarea nueva; nextId++ devuelve el valor actual y después le suma 1.

La función run interpreta una orden. Con desestructuración y rest, const [command, ...words] = line.split(" ") separa la primera palabra del resto, y join vuelve a unir el título. Para done y remove, find busca la tarea por su número y splice la quita del array.

Cuando algo no cuadra, run lanza un error con throw: la tarea 7 no existe y jump no es una orden conocida. El bucle principal llama a run dentro de un try/catch, así que cada error se muestra y el programa sigue con la orden siguiente.

Al final se escribe la lista con [x] o [ ] según done (un ternario), padStart alinea los números, filter cuenta las pendientes y JSON.stringify la prepara para guardarla. Es el mismo JavaScript con el que se programan las aplicaciones Electron, React, Next.js y React Native de DMarlon Studio.

Código · main.js

// A small to-do list driven by text commands.const commands = ["add Buy milk", "add Call the dentist", "add Water the plants",  "done 1", "remove 2", "done 7", "add Finish the JavaScript course", "jump 3"];const tasks = [];let nextId = 1;function run(line) {  const [command, ...words] = line.split(" ");  const text = words.join(" ");  if (command === "add") {    tasks.push({ id: nextId, title: text, done: false });    return `added #${nextId++} "${text}"`;  }  const task = tasks.find((t) => t.id === Number(text));  if (!task) throw new Error(`there is no task #${text}`);  if (command === "done") task.done = true;  else if (command === "remove") tasks.splice(tasks.indexOf(task), 1);  else throw new Error(`unknown command "${command}"`);  return `${command} #${task.id}`;}for (const line of commands) {  try { console.log("ok   ", run(line)); }  catch (error) { console.log("error", error.message); }}for (const { id, title, done } of tasks) {  console.log(`${done ? "[x]" : "[ ]"} ${String(id).padStart(2)}  ${title}`);}const pending = tasks.filter((t) => !t.done).length;console.log(`${tasks.length} tasks, ${pending} pending`);console.log("Saved as JSON:", JSON.stringify(tasks).length, "characters");

Salida · node main.js

ok    added #1 "Buy milk"
ok    added #2 "Call the dentist"
ok    added #3 "Water the plants"
ok    done #1
ok    remove #2
error there is no task #7
ok    added #4 "Finish the JavaScript course"
error unknown command "jump"
[x]  1  Buy milk
[ ]  3  Water the plants
[ ]  4  Finish the JavaScript course
3 tasks, 2 pending
Saved as JSON: 151 characters

Para recordar

  • Los datos: un array de objetos, uno por tarea.
  • Una función por tarea concreta: aquí, run interpreta cada orden.
  • throw para los errores y try/catch para que el programa continúe.
  • find, filter, splice, plantillas y JSON trabajan juntos.

Ejercicio

Añada la orden rename 3 Nuevo título, que cambie el título de una tarea, y la orden clear, que quite todas las tareas hechas con filter.