Todo List App – Lesson 2 – Item class and service

Author: Dawid Adach

-

Goal

Within this tutorial, we will learn how to build a ToDo application which allows us to add/remove and complete tasks and organize time in handful lists. You can check a live demo of the app here.

1. Creating the Todo Class

Angular CLI generates TypeScript (TS) files. If you don't know what TS is - don't worry. We will explain that in next lessons. For now, you just have to know that TS is an extended version of JavaScript allows you to use extra functionalities. You might wonder how TS will be running in WebBrowser - actually, it won't. Angular uses compiler to transpile TypeScript into JavaScript which can be parsed by the browser.

  1. Generate Todo class using CLI, run:
    ng generate class todos/Todo --spec
    
    which will create;
    src/app/todos/todo.spec.ts
    src/app/todos/todo.ts
    
  2. Open up src/app/todos/todo.ts (you can use any editor, I strongly recommend Visual Studio Code):
    export class Todo {
    }
    
    and add the logic:
    export class Todo {
        id: number;
        title = '';
        complete = false;
        category: number;
    
        constructor(values: Object = {}) {
          Object.assign(this, values);
        }
    }
    
    In this Todo class definition, we specify that each Todo instance will have four properties:
    • id: unique id number of the todo
    • title: todo item title
    • complete: boolenan (yes/no), status of completion
    • category: id of todo list
  3. We used the --spec option. This instructed CLI to generate src/app/todos/todo.spec.ts for us with a basic unit test:
    import { Todo } from './todo';
    
    describe('Todo', () => {
      it('should create an instance', () => {
        expect(new Todo()).toBeTruthy();
      });
    });
    
    the following file is a place where we will write test scenarios for our components/services/classes. We will cover that in detail in advanced tutorials. For now, we will just generate them for a future use.

2. Creating the TodoDataService Service

The TodoDataService will be responsible for managing our Todo items. It will allow us to create/remove and change the status of todo item.

  1. Generate TodoDataService:
    ng generate service todos/TodoData
    
    which output is:
      create src/app/todos/todo-data.service.spec.ts (387 bytes)
      create src/app/todos/todo-data.service.ts (114 bytes)
    
    as you may noticed, CLI generates a unit test for a service by default, therefore there is no need for --spec option.
  2. Open src/app/todos/todo-data.service.ts:
    import { Injectable } from '@angular/core';
    
    @Injectable()
    export class TodoDataService {
    
      constructor() { }
    
    }
    
    and add following logic:
    import { Injectable } from '@angular/core';
    import {Todo} from './todo';
    
    @Injectable()
    export class TodoDataService {
    
      // Placeholder for last id so we can simulate
      // automatic incrementing of id's
      lastId = 0;
    
        // Placeholder for todo's
        todos: Todo[] = [];
    
      constructor() { }
    
      // Simulate POST /todos
      addTodo(todo: Todo): TodoDataService {
        if (!todo.id) {
          todo.id = ++this.lastId;
        }
        this.todos.push(todo);
        return this;
      }
    
      // Simulate DELETE /todos/:id
      deleteTodoById(id: number): TodoDataService {
        this.todos = this.todos
          .filter(todo => todo.id !== id);
        return this;
      }
    
      // Simulate PUT /todos/:id
      updateTodoById(id: number, values: Object = {}):  Todo | any {
        const todo = this.getTodoById(id) ;
        if (!todo) {
          return this;
        }
        Object.assign(todo, values);
        return todo;
      }
    
      // Simulate GET /todos
      getAllTodos(): Todo[] {
        return this.todos;
      }
    
      // Simulate GET /todos/:id
      getTodoById(id: number):  Todo | any {
        return this.todos
          .filter(todo => todo.id === id)
          .pop();
      }
    
      // Simulate GET /todos/:category
      getTodoByCategory(id: number): Todo[] {
        return this.todos
          .filter(todo => todo.category === id);
      }
    
      // Toggle todo complete
      toggleTodoComplete(todo: Todo) {
        const updatedTodo = this.updateTodoById(todo.id, {
          complete: !todo.complete
        });
        return updatedTodo;
      }
    }
    
    

Now when our Todo item part is ready we can start creating a Class and the Service to maintain categories.


Next lesson

Spread the word:
Do you need help?: Use our support forum

About author

Dawid Adach
For more than 5 years Dawid was working as an IT Consultant specializing in SOA/EAI/ESB for banking domain. He was gaining experience working in countries like Netherlands, Belgium, Poland and India developing enterprise-class systems for the biggest companies within a domain. Since 2 years as a co-founder of mdbootstrap.com & brandflow.net is using and teaching others technologies like Angular, TypeScript, PHP, AJAX, Mongo, SQL, Hadoop Stack, Virtualization, Automation and many others...