当我们只有一个要接收的对象时如何在Angular 8中获取数据

Posted

技术标签:

【中文标题】当我们只有一个要接收的对象时如何在Angular 8中获取数据【英文标题】:How to get data in Angular 8 when only we have one object to be received 【发布时间】:2020-09-18 14:26:18 【问题描述】:

我得到的错误:

core.js:6260 ERROR 错误:找不到“object”类型的不同支持对象“[object Object]”。 NgFor 只支持绑定到 Arrays 等 Iterables。

在 NgForOf.ngDoCheck (common.js:4406) 在 callHook (core.js:4762) 在 callHooks (core.js:4722) 在 executeCheckHooks (core.js:4642) 在 refreshView (core.js:11979) 在 refreshComponent (core.js:13449) 在 refreshChildComponents (core.js:11689) 在 refreshView (core.js:12024) 在 refreshComponent (core.js:13449) 在 refreshChildComponents (core.js:11689)

如果我有多个对象,则下面的代码有效。当数据如下所示时,我知道数组或对象有问题,但我无法弄清楚。因此,当我有 2 个对象时,我会在下拉列表中获取数据,但是当它是一个对象时,我会收到上述错误。

[
..,
..
]

我的数据如下所示:


"details_id": 218,
"master_code": 218,
"MstCode": null,
"start_date": "2020-02-29T00:00:00",
"end_date": "2020-02-29T00:00:00",
"canceled": "False   ",
"data_archived": null,
"last_updated_on": "2020-02-28 11:37:08",
"last_updated_by": null

我的http get请求代码如下:

this.http.get(this.apiBaseUrl+"ProgramDets/"+id).toPromise().then(res => this.Details = res as TrDetails);

我的型号代码:

export class TrDetails 
    details_id: number;
    master_code: number;
    MstCode: number;
    start_date: Date;
    end_date: Date;
    canceled: string;
    data_archived: string;
    last_updated_on: Date;
    last_updated_by: string;

我的服务代码:

apiBaseUrl = "http://localhost:2676/api/";
Details : TrainingDetails;

GetDetails(id)
    this.http.get(this.apiBaseUrl+"ProgramDets/"+id).toPromise().then(res => 
    this.Details = res as TrDetails);
  

我的下拉代码:

<option *ngFor="let data of service.Details" [value]="data.start_date">data.program_start_date</option>

【问题讨论】:

你能不能显示你在 then 方法中 console.log(res) 时得到了什么以及你在哪里使用 GetDetails 方法 data_archived: null canceled: "False " last_updated_by: null last_updated_on: "2020-02-28 11:31:58" end_date: "2020-02-29T00:00:00" start_date: "2020-02-29T00:00:00" MstCode: null details_id: 217 master_code: 1 你在哪里使用GetDetails方法? 在我的组件 TypeScript 文件中 并且你的下拉代码属于组件 html 【参考方案1】:

我认为你需要的是:

GetDetails(id)
    this.http.get(this.apiBaseUrl+"ProgramDets/"+id).toPromise().then(res => 
    this.Details = res.json() as TrDetails);
  

经过讨论更新答案:

如果res 是一个对象,您需要将其转换为一个数组,否则如果它是一个数组,则按原样分配。如果有错误还需要catch

GetDetails(id)
    this.http.get(this.apiBaseUrl+"ProgramDets/"+id).toPromise().then(res =>
    if(Array.isArray(res))
        this.Details = res;
    else
        this.Details = [res] as any //change any to your type that matches
    
  ).catch(err => console.log(err));

【讨论】:

当我尝试这个时,我得到了一个错误。 Property json doesn't exist on type object 好的,现在很清楚了,res 是一个对象,而不是一个数组。所以ngFor 在这种情况下是行不通的。试着把 `*ngIf* 来检查它;首先是一个数组 console.log()打印数据。因此,您可以使用JSON.parse(res) 进行解析。但首先,我们需要知道res 正在打印什么。 顺便说一句,你试过res.json() as any而不是TrDetails 如何使用ngIf检查对象是数组还是对象?【参考方案2】:

service.Details 应该是 *ngFor 工作的数组,似乎service.Details 的值在这里是一个对象,因此您会收到错误。

理想情况下,你不应该在你的服务方法中订阅,你应该从你的服务中返回 observable 并在组件中订阅它。

我建议你把你的服务方式改成这个

 getDetails(id)
    return this.http.get(this.apiBaseUrl+"ProgramDets/"+id);
 

在你的组件中,无论你在哪里调用 getDetails 方法,你都可以这样做

this.details = this.service.getDetails(id).pipe(map(res => [res]))

然后在你的 html 中你可以简单地使用你的异步操作符来订阅。我建议使用 observable 模式而不是 promise 模式,这会让你的代码看起来更干净

<option *ngFor="let data of (details | async)" [value]="data.start_date">data.program_start_date</option>

【讨论】:

是的,我想通了,但我不知道如何获取数据。 当您使用具有可观察图案的棱角凝胶时,您不必遵循承诺模式,因此您应该遵循我的建议,我已经更新了答案,请检查。 好的,试试这个:res =&gt; [res] || [];,感谢您的帮助,但此解决方案有效,它由@RahulDwivedi 提供【参考方案3】:

如果您的逻辑在响应为数组时有效,则只需在使用前将任何对象响应添加到空数组即可。尝试将您的 GetDetails 方法主体更改为以下

this.http.get(this.apiBaseUrl+"ProgramDets/"+id).toPromise().then((res: TrDetails | TrDetails[]) => this.Details = Array.isArray(res) ? res : [res]);

【讨论】:

以上是关于当我们只有一个要接收的对象时如何在Angular 8中获取数据的主要内容,如果未能解决你的问题,请参考以下文章

仅在第一次加载 Angular 网页时使用 Safari 接收 401 状态

Angular 5 - 当用户关闭浏览器窗口时如何进行 API 调用?

如何在Angular中的路由之间传递非字符串对象?

Codeigniter + Angular Js:如何接收 JSON 数据

Angular2:当jquery插件附加到ng-form对象时如何触发ng-valid?

如果wen可以定义公共属性,Angular2为啥要使用getter