TypeError无法读取属性" length"未定义的 - 角4

时间:2018-05-17 16:16:56

标签: javascript angular typescript interface

每次加载网页时,我都必须按顺序点击徽标才能完全填充组件中的本地数组。提取的数据位于本地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循环中,它无法识别.length。

1 个答案:

答案 0 :(得分:0)

问题:

代码是正确的,但方法是错误的。订阅Observable getJSON()是异步任务。在getJSON()返回任何数据之前,您已经调用了getAllIpageLinks(),因此在第一次运行时您将获得空值。我相信,因为您已将服务注入组件中的单例,所以数据将在后续调用中填充(通过单击徽标进行刷新)。

<强>解决方案:

  1. 在observable上使用getAllIpageLinks运算符应用更改(您在map中所做的更改)。
  2. 返回组件中该observable的实例。
  3. 订阅组件中的observable(不在.service中)
  4. 欢迎使用StackOverflow 。请复制粘贴问题中的代码,而不是提供截屏。我能提供给你的确切代码

    参考代码: 我还没有测试过语法,但应该足以指导你。 1.重构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);
                     });
     }
    
    1. 调用组件中的getAllIpageLinks()
    2. 并在那里订阅