【问题标题】:TypeError cannot read property "length" of undefined - angular 4TypeError 无法读取未定义的属性“长度”-角度 4
【发布时间】:2018-10-28 00:00:54
【问题描述】:

每次加载网页时,我都必须单击徽标才能将数据完全填充到组件中的本地数组中。提取的数据位于本地 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。

【问题讨论】:

  • 你能告诉你具体的问题是什么以及它发生在哪里吗?
  • 抱歉造成混淆,我已经上传了控制台图片,可能有助于澄清问题。

标签: javascript angular typescript interface


【解决方案1】:

问题:

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

解决方案:

  1. 通过在 observable 上使用 map 运算符应用更改(您在 getAllIpageLinks 中所做的)。
  2. 在组件中返回该 observable 的实例。
  3. 订阅组件中的 observable(不在 .service 中)

欢迎使用 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. 并在那里订阅它

【讨论】:

  • 感谢您的帮助,并欢迎我加入 StackOverflow。我已经实现了代码;以防你想加价。
猜你喜欢
  • 2018-09-19
  • 2015-08-10
  • 2020-06-12
  • 1970-01-01
  • 2021-12-05
  • 2020-07-20
  • 2020-03-07
  • 1970-01-01
相关资源
最近更新 更多