Angular2 пытается получить элемент в массиве перед заполнением массива
У меня есть сервис Angular2 следующим образом. Я пытаюсь использовать это как общий сервис между несколькими компонентами. Если это имеет значение, компоненты привязываются непосредственно к public books
, а также selectedBook properties
Я хочу кэшировать список книг и выбранную в данный момент книгу в сервисе и заполнять их только при первом вызове.
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
@Injectable()
export class BookService {
public books: Book[];
public selectedBook: Book;
constructor(private http: Http,
private router: Router) {
this.http.get('/api/book/list')
.subscribe(result => this.books = result.json() as Book[]);
}
public getBooks() {
return this.books;
}
public setSelectedBook(id) {
this.selectedBook = this.books.filter(x => x.id == id)[0];
}
}
Проблема в том, что иногда я пытаюсь прочитать массив или вызов setSelecteBook(id)
до фактического заполнения массива, что вызывает сбой. Я пытался найти пример того, как использовать Observables, но я не могу найти сценарий, достаточно близкий к моему, чтобы понять, как адаптировать его для решения моей проблемы.
3 ответа
Вы можете инициализировать массив книг в конструкторе пустым массивом.
Вы также можете сделать обходной путь и проверить длину перед доступом к массиву.
public setSelectedBook(id) {
if(this.books.length > 0) {
this.selectedBook = this.books.filter(x => x.id == id)[0];
}
}
Это не инициализирует массив, оно просто сообщает компилятору TypeScript, что это определенное свойство относится к этому типу. На самом деле иметь массив, а не быть undefined
, вы должны инициализировать его. Таким образом, filter
Функция будет работать:
@Injectable()
export class BookService {
public books: Book[] = [];
//...
}
В качестве более чистого решения я бы подписался на ваш компонент book-detail, например, на сервисный метод getBooksList.
Выполните вызов API с использованием this.bookService.getBooksList и, как только загрузится массив, выберите нужную книгу.