-1

I have a todo-list component and I'd like to populate that component with a todo-service. This service is grabbing the data from a local JSON file.

My todo-list component looks like this:

import 'zone.js/dist/zone';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TodosService } from './todo.service';
import { Todo } from './todo.model';

@Component({
  selector: 'app-todo',
  standalone: true,
  imports: [CommonModule],
  providers: [TodosService],
  template: `
    <p>Hello from todo.component</p>
    <ul>
      <li *ngFor="let todo of todos">{{todo.description}}</li>
    </ul>
  `,
})
export class TodoList {
  todos: Todo[] = [];
  constructor(private todoService: TodosService) {}

  ngOnInit() {
    console.log('todo-list: ', this.todoService.getTodos());
  }
}

My service looks like this

import { Todo } from './todo.model';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable()
export class TodosService {
  private allTodos: Todo[] = [];

  constructor(private http: HttpClient) {}

  public getTodos() {
    this.http.get<Todo>('./assets/todos.json').subscribe((todos: Todo) => {
      console.log(`returned: ${todos}`, todos);

      this.allTodos.push(todos);

    });
    return this.allTodos;
  }
}

I can see from my console logs that my http request is successful.

Todo json response

But I'm not able to set my private property on the service. If I console log it in the service and after the request, it's still empty.

Here is what I tried to fix this. My 2nd attempt, I thought maybe I could just set the value of the property rather than pushing to it.

  //Attempt 2
  this.allTodos = todos;

But I got the following error:

Type 'Todo' is missing the following properties from type 'Todo[]': length, pop, push, concat, and 26 more.

I'm assuming I got this because my JSON response is returning an object and my allTodos property expects an array of objects instead. So my next thought was that I have to iterate through the response and push these values to my property instead.

  //Attempt 3
  this.allTodos.push({
    description: todos.description,
    complete: todos.complete,
  });

This doesn't error out, but my component is still showing it as a blank array in the console.log.

ngOnInit() { console.log('todo-list: ', this.todoService.getTodos()); }

empty todo list

I'm drawing a blank here. What am I doing wrong? I've created a stackblitz here

onTheInternet
  • 6,421
  • 10
  • 41
  • 74
  • in `./assets/todos.json`, you have multiple todos or only ONE ? From your work, I would say many. So it would be `this.http.get('./assets/todos.json').subscribe((todos: Todo[])` – Wandrille May 12 '23 at 15:45
  • 1
    You are returning `this.allTodos;` before data came so return http observable `return this.http.get – Saptarsi May 12 '23 at 16:48

1 Answers1

2

I think you are following a wrong approach. An easy and understandable solution would be like this:

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TodosService } from './todo.service';
import { Todo } from './todo.model';

@Component({
  selector: 'app-todo',
  standalone: true,
  imports: [CommonModule],
  providers: [TodosService],
  template: `
    <p>Hello from todo.component</p>
    <ul>
      <li *ngFor="let todo of todos">{{todo.description}}</li>
    </ul>
  `,
})
export class TodoList {
  todos: Todo[] = [];
  constructor(private todoService: TodosService) {}

  ngOnInit() {
    this.todoService.getTodos().subscribe(todos => this.todos = todos);
    
  }
}

And for service:

import { Todo } from './todo.model';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, tap } from 'rxjs';

@Injectable()
export class TodosService {
  constructor(private http: HttpClient) {}

  public getTodos(): Observable<Todo[]> {
    return this.http.get<Todo[]>('./assets/todos.json');
  }
}

I also modified your Stackblitz implementation. You can find it here

Fiorelo
  • 71
  • 4