Files
NGRX-Playground/src/app/features/tasks/data-access/tasks-api.service.ts
T

83 lines
2.4 KiB
TypeScript

import { Injectable } from '@angular/core';
import { Observable, delay, of, throwError } from 'rxjs';
import { Task, TaskPriority } from './task.model';
const NETWORK_DELAY_MS = 250;
@Injectable({ providedIn: 'root' })
export class TasksApiService {
private tasks: Task[] = [
{
id: 'task-1',
title: 'Review signal store conventions',
completed: true,
priority: 'high',
updatedAt: '2026-03-08T08:00:00.000Z',
},
{
id: 'task-2',
title: 'Document persistence boundaries',
completed: false,
priority: 'medium',
updatedAt: '2026-03-08T08:02:00.000Z',
},
{
id: 'task-3',
title: 'Prepare lazy-loaded feature shell',
completed: false,
priority: 'low',
updatedAt: '2026-03-08T08:05:00.000Z',
},
];
getTasks(): Observable<Task[]> {
return of(this.tasks).pipe(delay(NETWORK_DELAY_MS));
}
createTask(title: string, priority: TaskPriority): Observable<Task> {
const trimmedTitle = title.trim();
if (!trimmedTitle) {
return throwError(() => new Error('Task title cannot be empty.'));
}
const task: Task = {
id: crypto.randomUUID(),
title: trimmedTitle,
completed: false,
priority,
updatedAt: new Date().toISOString(),
};
this.tasks = [task, ...this.tasks];
return of(task).pipe(delay(NETWORK_DELAY_MS));
}
toggleTask(taskId: string): Observable<Task> {
const task = this.tasks.find((item) => item.id === taskId);
if (!task) {
return throwError(() => new Error('Task not found.'));
}
const updatedTask: Task = {
...task,
completed: !task.completed,
updatedAt: new Date().toISOString(),
};
this.tasks = this.tasks.map((item) => (item.id === taskId ? updatedTask : item));
return of(updatedTask).pipe(delay(NETWORK_DELAY_MS));
}
archiveCompleted(): Observable<string[]> {
const archivedIds = this.tasks.filter((task) => task.completed).map((task) => task.id);
this.tasks = this.tasks.filter((task) => !task.completed);
return of(archivedIds).pipe(delay(NETWORK_DELAY_MS));
}
}