angular6 RxJs проблема наблюдаемых
Я пытаюсь получить список задач из класса обслуживания в компоненте. Но это не работает. Пожалуйста, найдите код ниже:
todos.service.ts
import { Injectable } from '@angular/core';
import { Todos } from '../models/Todos';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of, BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class TodosService {
todos: Todos[];
httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
}
private todoSource = new BehaviorSubject<Todos>({ id: null, text: null, completed: null });
selectedTodo = this.todoSource.asObservable();
constructor(private http: HttpClient) {
this.http.get<Todos[]>('http://localhost:8888/api/todos').subscribe((todos) => {
this.todos = todos;
});
}
getTodos(): Observable<Todos[]> {
return of(this.todos);
}
addTodo(todo): Observable<Todos> {
return this.http.post<Todos>('http://localhost:8888/api/todos', todo, this.httpOptions);
}
setTodo(todo: Todos) {
this.todoSource.next(todo);
}
}
todoslist.component.ts
import { Component, OnInit } from '@angular/core';
import { Todos } from '../../models/Todos';
import { TodosService } from '../../services/todos.service';
@Component({
selector: 'app-todolist',
templateUrl: './todolist.component.html',
styleUrls: ['./todolist.component.css']
})
export class TodolistComponent implements OnInit {
todos: Todos[];
constructor(private _todosService: TodosService) {
}
ngOnInit() {
this._todosService.getTodos().subscribe(todos => {
console.log('getting todos', todos);
this.todos = todos;
});
}
onSelect(todo: Todos) {
this._todosService.setTodo(todo);
}
}
Метод ngOnInit компонента вызывает метод сервиса getTodos(). Но при входе в консоль задачи кажутся неопределенными. Что я здесь не так делаю?
Спасибо
2 ответа
Похоже, вы пытаетесь кешировать HTTP-ответ, чтобы второй HTTP-запрос не выполнялся, если методы getTodos() вызывались во второй раз.
Если я ошибаюсь, @Pankaj Parkar правильно.
Если я прав, то вместо этого вы хотите сделать следующее:
getTodos(): Observable<Todos[]> {
return (this.todos) ? of(this.todos) :
this.http.get<Todos[]>('http://localhost:8888/api/todos')
.pipe( tap(todos => this.todos = todos) )
}
В идеале аякс должен быть сделан из getTodos
сам метод. Имея звонок внутри constructor
не будет гарантировать, что данные будут доступны в первую очередь. Вот как работает асинхронный. Это можно просто вернуть, как показано ниже.
getTodos(): Observable<Todos[]> {
return this.http.get<Todos[]>('http://localhost:8888/api/todos');
}