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(). Но при ведении журнала консоли задачи кажутся неопределенными. Что я здесь делаю неправильно?

Спасибо


person Ashy Ashcsi    schedule 06.09.2018    source источник
comment
Нет гарантии, что данные вернутся из службы к моменту вызова getTodos().   -  person user184994    schedule 06.09.2018


Ответы (2)


В идеале ajax должен быть сделан из самого метода getTodos. Наличие вызова внутри constructor не гарантирует, что данные будут доступны в первую очередь. Вот как работает асинхронность. Это может быть просто возврат, как показано ниже.

getTodos(): Observable<Todos[]> {
   return this.http.get<Todos[]>('http://localhost:8888/api/todos');
}
person Pankaj Parkar    schedule 06.09.2018

Похоже, вы пытаетесь кэшировать HTTP-ответ, чтобы второй HTTP-запрос не выполнялся, если методы getTodos() вызываются во второй раз.

Если я ошибаюсь, то @Pankj 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) )
}
person danday74    schedule 06.09.2018