如何在Angular组件HTML中迭代数组?

huangapple go评论61阅读模式
英文:

How do I iterate through an array in an Angular component HTML?

问题

我在尝试迭代时遇到了NG0900错误(Error trying to diff '[object Object]'. Only arrays and iterables are allowed)。

我的类:

export class AppComponent {
  public share?: share[] = [];

  constructor(http: HttpClient) {
    http.post<share[]>('/api/member/shares/get', { "getSharesRequestDto": { "accountNumber": "x123" } }).subscribe(result => {
      this.share = result;
      console.log(this.share);
    }, error => console.error(error));
  }
}

interface share {
  id: string;
  description: string;
}

我的HTML:

<div *ngIf="share">
  <div *ngFor="let s of share">
    <span>{{ s.id }}</span>
    <span>{{ s.description }}</span>
  </div>
</div>

在控制台中记录的对象:

{
    "share": [
        {
            "id": "x00",
            "description": "desc 00"
        },
        {
            "id": "x01",
            "description": "desc 01"
        }
    ]
}

根据Swagger,我的API请求对象如下:

{
  "getSharesRequestDto": {
    "accountNumber": "string"
  }
}

我的API响应如下:

{
  "share": [
    {
      "id": "string",
      "description": "string"
    }
  ]
}

我是Angular新手,不太理解错误消息。看起来我有一个包含数组的对象,但*ngFor应该迭代对象中的数组。

我尝试将对象映射到匿名数组,尝试删除类型并更改为any[],但似乎没有什么效果。

英文:

I'm getting error NG0900 (Error trying to diff &#39;[object Object]&#39;. Only arrays and iterables are allowed) when attempting to iterate.

My class:

export class AppComponent {
  public share?: share[] = [];

  constructor(http: HttpClient) {
    http.post&lt;share[]&gt;(&#39;/api/member/shares/get&#39;, { &quot;getSharesRequestDto&quot;: { &quot;accountNumber&quot;: &quot;x123&quot; } }).subscribe(result =&gt; {
      this.share = result;
      console.log(this.share);
    }, error =&gt; console.error(error));
  }
}

interface share {
  id: string;
  description: string;
}

My HTML:

&lt;div *ngIf=&quot;share&quot;&gt;
  &lt;div *ngFor=&quot;let s of share&quot;&gt;
    &lt;span&gt;{{ s.id }}&lt;/span&gt;
    &lt;span&gt;{{ s.description }}&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;

The object that's logged to the console:

{
    &quot;share&quot;: [
        {
            &quot;id&quot;: &quot;x00&quot;,
            &quot;description&quot;: &quot;desc 00&quot;
        },
        {
            &quot;id&quot;: &quot;x01&quot;,
            &quot;description&quot;: &quot;desc 01&quot;
        }
    ]
}

My API request object according to Swagger:

{
  &quot;getSharesRequestDto&quot;: {
    &quot;accountNumber&quot;: &quot;string&quot;
  }
}

My API response:

{
  &quot;share&quot;: [
    {
      &quot;id&quot;: &quot;string&quot;,
      &quot;description&quot;: &quot;string&quot;
    }
  ]
}

I'm new to Angular and don't understand the error message. It looks like I have an object containing an array, but the *ngFor should iterate through the array in the object.

I've tried mapping the object to an anonymous array, I've tried removing the type and changing to any[], but nothing seems to work.

答案1

得分: 1

你的API并不返回数组,而是返回一个包含属性“share”的对象,该属性包含一个列表。你可以像这样更新API调用:

constructor(http: HttpClient) {
    http.post<{ share: share[] }>('/api/member/shares/get', { "getSharesRequestDto": { "accountNumber": "x123" } }).subscribe(result => {
        this.share = result.share;
        console.log(this.share);
    }, error => console.error(error));
}
英文:

Your API doesn't return the array, it return the object with contains a property share which have list. You can update api call like that:

constructor(http: HttpClient) {
    http.post&lt;{ share: share[] }&gt;(&#39;/api/member/shares/get&#39;, { &quot;getSharesRequestDto&quot;: { &quot;accountNumber&quot;: &quot;x123&quot; } }).subscribe(result =&gt; {
      this.share = result.share;
      console.log(this.share);
    }, error =&gt; console.error(error));
  }

答案2

得分: 0

API返回的数据以对象形式返回,因此您正在迭代该对象,这就是您出现错误的原因。

this.share = result;
console.log(this.share);

尝试使用以下代码更改上面的代码:

this.share = result.share;
console.log(this.share);
英文:

api is returning data in object form and you are iterating over the object that's why you are getting error.

this.share = result;
console.log(this.share);

Tried to change the above code with this one

this.share = result.share;
console.log(this.share);

答案3

得分: 0

根据API实际响应,你只需要访问shared数组,如下所示:

this.shared = result.shared;

我建议将HTTP逻辑调用移至一个服务中,此外,在订阅API结果时,最好采用响应式方法,使用async管道,这样你就不必处理订阅。此外,我建议不要在构造函数中处理HTTP调用,而是在OnInit生命周期钩子中处理,这是通常用于处理所有代码初始化的地方:

服务

@Injectable({
  providedIn: 'root'
})
export class MyService {
  getShare(body: yourType): Observable<Share[]> {
    return http.post<Share[]>('/api/member/shares/get', body).pipe(
      map(response => response.share)
    );
  }
}

组件 ts

@Component({...})
export class AppComponent implements OnInit {
  share$!: Observable<Share[]>;

  ngOnInit(): void {
    const body = { "getSharesRequestDto": { "accountNumber": "x123" } };
    this.share$ = this.getShare(body);
  }
}

组件模板

<div *ngIf="share$ | async as shares">
  <div *ngFor="let share of shares">
    <span>{{ share.id }}</span>
    <span>{{ share.description }}</span>
  </div>
</div>

同时,将数据类型的首字母大写,所以应该使用Share,而不是share

英文:

Based on the actual response from the API, you are just missing accessing the shared array as:

this.shared = result.shared;

I recommend handling the HTTP logic call to a service, also, you should go with the reactive approach when subscribing to the API result with the async pipe so you don't have to handle the subscription, additionally, instead of handling the HTTP call in the constructor, I suggest you do that in the OnInit lifecycle hook, it's where you usually handle all the code initialization:

Service

@Injectable({
  providedIn: &#39;root&#39;
})
export class MyService {
  getShare(body: yourType): Observable&lt;Share[]&gt; {
    return http.post&lt;Share[]&gt;(&#39;/api/member/shares/get&#39;, body).pipe(
      map(response =&gt; response.share)
    );
  }
}

Component ts

@Component({...})
export class AppComponent implements OnInit {
  share$!: Observable&lt;Share[]&gt;;

  ngOnInit(): void {
    const body = { &quot;getSharesRequestDto&quot;: { &quot;accountNumber&quot;: &quot;x123&quot; } };
    this.share$ = this.getShare(body);
  }
}

Component template

&lt;div *ngIf=&quot;share$ | async as shares&quot;&gt;
  &lt;div *ngFor=&quot;let share of shares&quot;&gt;
    &lt;span&gt;{{ share.id }}&lt;/span&gt;
    &lt;span&gt;{{ share.description }}&lt;/span&gt;
  &lt;/div&gt;
&lt;/div&gt;

Keep the data types in upper case as well, so instead of share, it should be Share

huangapple
  • 本文由 发表于 2023年7月10日 22:37:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76654814.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定