TypeError не может прочитать свойство "length" из неопределенного - angular 4 - PullRequest
0 голосов
/ 17 мая 2018

Каждый раз, когда я загружаю веб-страницу, мне приходится нажимать на логотип, чтобы мои данные полностью заполняли локальный массив в моем компоненте.Полученные данные находятся в локальном файле JSON.Необходимость обновлять страницу каждый раз довольно непрофессионально / раздражает.

Использование Angular CLI 1.3.2

Вот в чем моя проблема:

 @Injectable()
export class LinksService implements OnInit{
  siteFile : IFile[];


  constructor(private http: Http) {

    this.getJSON().subscribe(data => this.siteFile = data, error => 
     console.log(error));
  }

 public getJSON(): Observable<any> {
    return this.http.get('./assets/docs/links.json')
                     .map((res:any) => res.json());
 }
 getAllIpageLinks() : IPageLink[]{
    var selectedIPageLinks: IPageLink[] = new Array();
    var selectedFileLinks : IFile[] = new Array();

    selectedFileLinks = this.siteFile; 


   for (var i=0; i<selectedFileLinks.length; i++)
   {
       selectedIPageLinks =
       selectedIPageLinks.concat(selectedFileLinks[i].files);
   }
    return selectedIPageLinks.sort(this.sortLinks);
}

Компонент:

constructor(private elRef: ElementRef, private linksService: LinksService) {
   this._file = this.linksService.getAllIpageLinks();
  }

Редактировать Чтобы полностью отобразить массив IFile [], нужно щелкнуть заголовок.Я пытался установить IFile для пустого массива (IFile [] = []) Ошибка исчезает, однако, она будет отображать пустые данные.

Кажется, проблема в цикле For, он может 'т. длина.

1 Ответ

0 голосов
/ 17 мая 2018

Проблема:

Коды верны, но подход неправильный.Подписка на Observable getJSON() является асинхронной задачей.До того, как getJSON() вернет какие-либо данные, вы уже вызываете getAllIpageLinks() и, следовательно, получаете нулевое значение при самом первом запуске.Я полагаю, что поскольку вы внедрили сервис как одноэлементный компонент, данные заполняются при последующем вызове (при обновлении путем нажатия на логотип).

Решение:

  1. Примените изменения (которые вы вносите в getAllIpageLinks), используя оператор map для наблюдаемого.
  2. возвращает экземпляр этого наблюдаемого в компоненте.
  3. подпишитесь на это наблюдаемое вкомпонент (не в .service)

Добро пожаловать в StackOverflow .Пожалуйста, скопируйте и вставьте свои коды в вопрос вместо того, чтобы давать скриншот.Я мог бы дать вам точные коды

Справочные коды: Я не проверял синтаксис, но этого должно быть достаточно, чтобы вы могли ориентироваться.1. Refactor getAllIpageLinks() как показано ниже

public getAllIpageLinks(): Observable<any> {
return this.http.get('./assets/docs/links.json')
                 .map((res:any) => res.json());
                 .map(res => {

                    var selectedIPageLinks: IPageLink[] = new Array();
                    var selectedFileLinks : IFile[] = new Array();

                    selectedFileLinks = res; 
                    for (var i=0; i<selectedFileLinks.length; i++)
                        {
                            selectedIPageLinks =
                            selectedIPageLinks.concat(selectedFileLinks[i].files);
                        }
                        return selectedIPageLinks.sort(this.sortLinks);
                 });
 }
вызовите выше getAllIpageLinks () в вашем компоненте и подпишитесь на него там
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...