You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 18 @for语法报错:TypeError: newCollection[Symbol.iterator] is not a function

问题

我一直使用Angular 7至14版本开发,现尝试用Angular 18.1做电影列表演示应用。编写基础服务从API获取数据后,使用新版本@for语法渲染列表时出现错误:ERROR TypeError: newCollection[Symbol.iterator] is not a function,但控制台打印数据显示正常。附上相关代码及API响应,请问该问题是版本导致还是代码疏漏?

组件.ts代码

export class MovielistComponent implements OnInit{
  movies: movie[] = [];
  constructor(
    private movieService: GetMoviesService,
  ) { }
  ngOnInit() {
    this.getMoviesList();
  }

  getMoviesList() {
    this.movieService.getMovies().subscribe(
      data => {
        this.movies = data;
        console.log('Movies: ', this.movies);
      }
    )
  }

}

HTML文件代码

<ul>
  @for (movie of movies; track movie.attributes) {
    <li>{{ movie.attributes.name }}</li>
  } @empty {
    <li>There are no items.</li>
  }
</ul>

模型.ts代码

export interface movie {
  id: number,
  attributes: {
    name: string,
    imageUrl: string,
    synopsis: string,
    year: string,
    genre: string,
  }
}

API响应

{
    "data": [
        {
            "id": 1,
            "attributes": {
                "name": "The Shawshank Redemption",
                "imageUrl": "https://m.media-amazon.com/images/M/MV5BNDE3ODcxYzMtY2YzZC00NmNlLWJiNDMtZDViZWM2MzIxZDYwXkEyXkFqcGdeQXVyNjAwNDUxODI@._V1_FMjpg_UY1800_.jpg",
                "synopsis": "Over the course of several years, two convicts form a friendship, seeking consolation and, eventually, redemption through basic compassion.",
                "year": "1994",
                "genre": "drama",
                "createdAt": "2024-07-16T12:34:06.769Z",
                "updatedAt": "2024-07-16T12:36:29.952Z",
                "publishedAt": "2024-07-16T12:36:29.951Z"
            }
        },
        {
            "id": 2,
            "attributes": {
                "name": "The Godfather",
                "imageUrl": "https://m.media-amazon.com/images/M/MV5BM2MyNjYxNmUtYTAwNi00MTYxLWJmNWYtYzZlODY3ZTk3OTFlXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_FMjpg_UY1982_.jpg",
                "synopsis": "Don Vito Corleone, head of a mafia family, decides to hand over his empire to his youngest son, Michael. However, his decision unintentionally puts the lives of his loved ones in grave danger.",
                "year": "1972",
                "genre": "crime, drama",
                "createdAt": "2024-07-16T12:36:14.143Z",
                "updatedAt": "2024-07-16T12:36:15.723Z",
                "publishedAt": "2024-07-16T12:36:15.720Z"
            }
        },
        {
            "id": 3,
            "attributes": {
                "name": "The Dark Knight",
                "imageUrl": "https://m.media-amazon.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_FMjpg_UY2048_.jpg",
                "synopsis": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, Batman must accept one of the greatest psychological and physical tests of his ability to fight injustice.",
                "year": "2008",
                "genre": "action, crime, drama, thriller",
                "createdAt": "2024-07-22T09:37:42.564Z",
                "updatedAt": "2024-07-22T09:38:19.346Z",
                "publishedAt": "2024-07-22T09:38:19.343Z"
            }
        }
    ],
    "meta": {
        "pagination": {
            "page": 1,
            "pageSize": 25,
            "pageCount": 1,
            "total": 3
        }
    }
}
解决方案

这是代码疏漏,和Angular版本无关。核心问题是API响应结构处理错误:

  • API返回的是一个包含data数组的完整对象,但你直接把整个响应对象赋值给了movies数组。@for语法要求遍历的是可迭代对象(比如数组),而普通对象不具备迭代能力,因此抛出Symbol.iterator is not a function错误。
  • 控制台打印数据正常是因为你打印的是完整响应对象,里面确实包含data数组,但movies变量实际存储的不是数组,而是整个响应对象。

修复步骤

  1. 修正数据赋值逻辑:在组件的getMoviesList方法中,将响应的data属性赋值给movies:
getMoviesList() {
  this.movieService.getMovies().subscribe(
    data => {
      this.movies = data.data; // 仅提取data数组部分
      console.log('Movies: ', this.movies);
    }
  )
}
  1. 优化类型定义(可选):新增API响应的接口,避免类型不匹配问题:
export interface MovieApiResponse {
  data: movie[];
  meta: {
    pagination: {
      page: number;
      pageSize: number;
      pageCount: number;
      total: number;
    }
  }
}

// 在服务中指定返回类型:Observable<MovieApiResponse>
  1. 优化track表达式:建议使用唯一标识(如movie.id)作为track的值,比movie.attributes更可靠:
<ul>
  @for (movie of movies; track movie.id) {
    <li>{{ movie.attributes.name }}</li>
  } @empty {
    <li>暂无电影数据</li>
  }
</ul>

内容的提问来源于stack exchange,提问作者weinde

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 16:24:53