5. Add your first interaction

Let the service add tasks

class TaskService extends Service<TaskService> {
    // Remove hardcoded tasks
    private _tasks: ITask[];

    constructor() {
        super();
        this._tasks = [];
    }
    
    public addTask(): void {
        let id = 0;
        if (this._tasks.length > 0){
            id = Math.max(...this._tasks.map(task => task.id)) + 1;
        }

        const newTask: ITask = {
            id: id,
            name: `Task ${id + 1}`,
        };

        this._tasks.push(newTask);
    }
}

Generate the component

npm run generate component add-task
# Creates src/app/components/add-task/add-task.component.ts|html|scss

Add the callback

import { taskService } from '../../services/index.js';

const templateFn = () => `__TEMPLATE_PLACEHOLDER__`;

export class AddTaskComponent extends Component {
    /* ... */
    private _addTask(): void {
        taskService.addTask();
  }
}

Bind the callback

<div class="add-task">
    <button data-event="click:_addTask">Add Task</button>
</div>

A little bit of styling

.add-task {
    padding: 2rem;
    button {
        background: #3C3C3A;
        color: #FAFAF9;
        padding: 1rem 1.5rem;
        font-size: 1.2rem;
        border-radius: 8px;
        &:hover {
            background: #2C2C2A;
        }
    }
}

Use the component in the view

export class TaskCatalogView extends View {
    /* ... */

    registerChildren(): ComponentConfig[] {
        return [
            {
                selector: 'add-task',
                factory: (el) => new AddTaskComponent(el),
            },
            /* ... */
        ]
    }
}
<div class="task-catalog">
    <h1>Nutin Todo</h1>
    <!-- data-component attribute = "selector" target -->
    <div data-component="add-task"></div>
    <!-- ... -->
</div>

Make the view aware of task creation

Define an event

// src/app/globals.d.ts
declare interface AppEventMap {
    // to keep this lean, we'll reuse the same event for all operations
    'task-event': { taskId: number };
}

Emit the event

import { AppEventBus } from '../../../core/index.js';

class TaskService extends Service<TaskService> {
    /* ... */
    
    public addTask(): void {
        /* ... */
        AppEventBus.emit('task-event', { taskId: newTask.id });
    }
}

Listen to the event to re-render the view

export class TaskCatalogView extends View {
    constructor() {
        /* ... */
        this.listenToRenderEvents(['task-event']);
    }
}

Next step →