'parseHasMany - Model type for relationship x not found' - 如何使用 Angular2-jsonapi 将嵌套 JSON 映射到模型
'parseHasMany - Model type for relationship x not found' - How do I map nested JSON to models with Angular2-jsonapi
我是 API 和 Angular 的新手,我 运行 遇到了一个我似乎无法解决的问题。
对于我目前正在进行的项目,我已经使用 fast_jsonapi. This formats my JSON responses to be in line with JSON:API. I then have an Angular app which should take in that response and map it with the Angular2-jsonapi 模块设置了一个简单的 Rails API。
对于这个问题,假设我们有角色和责任。一个角色可以有 0 到多个责任。问责制属于单一角色。
当我向 return 所有角色发送请求时,我收到 JSON 响应,然后模块将其正确映射到模型。当我尝试包含关系时出现问题。
根据 readme 我必须像这样定义要包含在 .findAll 方法中的关系:
{ include: 'accountabilities' }
从 rails API 请求了正确的数据,因为它与我之前使用 Postman 测试的请求相同。但是,我的浏览器控制台中出现的错误如下:
{留言:"parseHasMany - Model type for relationship accountability not found."}
我已经尝试过其他关系,现在已经完成了几次设置过程,但我看不出哪里出了问题。 Google、Github 和 Whosebug 上的搜索在这种情况下对我没有帮助。非常感谢任何帮助。
这是相关代码。如果需要任何其他信息或代码,请告诉我,我会很乐意更新此 post.
示例 JSON 响应:
{
"data": [
{
"id": "1",
"type": "role",
"attributes": {
"name": "Farming Engineer",
"purpose": "Iure voluptatum rem dolores.",
"created_at": "2020-01-16T18:38:26.151Z",
"updated_at": "2020-01-16T18:38:26.151Z"
},
"relationships": {
"accountabilities": {
"data": [
{
"id": "6",
"type": "accountability"
},
{
"id": "12",
"type": "accountability"
}
]
}
}
},
{
"id": "2",
"type": "role",
"attributes": {
"name": "IT Supervisor",
"purpose": "Iusto fuga fugiat qui.",
"created_at": "2020-01-16T18:38:26.161Z",
"updated_at": "2020-01-16T18:38:26.161Z"
},
"relationships": {
"accountabilities": {
"data": []
}
}
}
],
"included": [
{
"id": "6",
"type": "accountability",
"attributes": {
"description": "penetrate the market",
"created_at": "2020-01-16T18:38:26.480Z",
"updated_at": "2020-01-16T18:38:26.480Z"
},
"relationships": {
"role": {
"data": {
"id": "1",
"type": "role"
}
}
}
},
{
"id": "12",
"type": "accountability",
"attributes": {
"description": "immersive experience",
"created_at": "2020-01-16T18:38:26.507Z",
"updated_at": "2020-01-16T18:38:26.507Z"
},
"relationships": {
"role": {
"data": {
"id": "1",
"type": "role"
}
}
}
}
]
}
role.model.ts
import {
JsonApiModelConfig,
JsonApiModel,
Attribute,
HasMany,
BelongsTo
} from 'angular2-jsonapi';
import { Accountability } from '@app/shared/models/accountability.model';
@JsonApiModelConfig({
type: 'roles'
})
export class Role extends JsonApiModel {
@Attribute()
name: string;
@Attribute()
purpose: string;
@Attribute({ serializedName: 'created_at' })
createdAt: Date;
@Attribute({ serializedName: 'updated_at' })
updatedAt: Date;
@HasMany()
accountabilities: Accountability[];
}
accountability.model.ts
import {
JsonApiModelConfig,
JsonApiModel,
Attribute,
BelongsTo
} from 'angular2-jsonapi';
import { Role } from '@app/shared/models/role.model';
@JsonApiModelConfig({
type: 'accountabilities'
})
export class Accountability extends JsonApiModel {
@Attribute()
description: string;
@Attribute({ serializedName: 'created_at' })
createdAt: Date;
@Attribute({ serializedName: 'updated_at' })
updatedAt: Date;
@BelongsTo()
role: Role;
}
datastore.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {
JsonApiDatastoreConfig,
JsonApiDatastore,
DatastoreConfig
} from 'angular2-jsonapi';
import { Role } from '@app/shared/models/role.model';
import { Accountability } from '@app/shared/models/accountability.model';
const config: DatastoreConfig = {
baseUrl: 'http://localhost:3000/api',
apiVersion: 'v1',
models: {
roles: Role,
accountabilities: Accountability
}
};
@Injectable()
@JsonApiDatastoreConfig(config)
export class Datastore extends JsonApiDatastore {
constructor(http: HttpClient) {
super(http);
}
}
role.component.ts
import { Component, OnInit } from '@angular/core';
import { Datastore } from '@app/datastore';
import { Role } from '@app/shared/models/role.model';
import { JsonApiQueryData } from "angular2-jsonapi";
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.sass']
})
export class HomeComponent implements OnInit {
roles: Role[];
constructor(private datastore: Datastore) { }
ngOnInit() {
this.datastore
.findAll(Role, { include: 'accountabilities' })
.subscribe((roles: JsonApiQueryData<Role>) => {
console.log('>>>>>>>>>>>>>', roles);
console.log('>>>>>>>>>>>>>', roles.getModels());
this.roles = roles.getModels();
});
}
}
在 this Github topic 的大量帮助下,我终于设法解决了这个问题。
最初导致该问题的原因是,我从 API 得到的响应列出了 relationships
中的 type
和 included
的单数形式,而它们需要是复数形式。
将 record_type: :accountabilities
添加到我的序列化程序中的 has_many
关系改变了这一点并成功地将响应映射到对象。
我是 API 和 Angular 的新手,我 运行 遇到了一个我似乎无法解决的问题。
对于我目前正在进行的项目,我已经使用 fast_jsonapi. This formats my JSON responses to be in line with JSON:API. I then have an Angular app which should take in that response and map it with the Angular2-jsonapi 模块设置了一个简单的 Rails API。 对于这个问题,假设我们有角色和责任。一个角色可以有 0 到多个责任。问责制属于单一角色。 当我向 return 所有角色发送请求时,我收到 JSON 响应,然后模块将其正确映射到模型。当我尝试包含关系时出现问题。
根据 readme 我必须像这样定义要包含在 .findAll 方法中的关系:
{ include: 'accountabilities' }
从 rails API 请求了正确的数据,因为它与我之前使用 Postman 测试的请求相同。但是,我的浏览器控制台中出现的错误如下:
{留言:"parseHasMany - Model type for relationship accountability not found."}
我已经尝试过其他关系,现在已经完成了几次设置过程,但我看不出哪里出了问题。 Google、Github 和 Whosebug 上的搜索在这种情况下对我没有帮助。非常感谢任何帮助。
这是相关代码。如果需要任何其他信息或代码,请告诉我,我会很乐意更新此 post.
示例 JSON 响应:
{
"data": [
{
"id": "1",
"type": "role",
"attributes": {
"name": "Farming Engineer",
"purpose": "Iure voluptatum rem dolores.",
"created_at": "2020-01-16T18:38:26.151Z",
"updated_at": "2020-01-16T18:38:26.151Z"
},
"relationships": {
"accountabilities": {
"data": [
{
"id": "6",
"type": "accountability"
},
{
"id": "12",
"type": "accountability"
}
]
}
}
},
{
"id": "2",
"type": "role",
"attributes": {
"name": "IT Supervisor",
"purpose": "Iusto fuga fugiat qui.",
"created_at": "2020-01-16T18:38:26.161Z",
"updated_at": "2020-01-16T18:38:26.161Z"
},
"relationships": {
"accountabilities": {
"data": []
}
}
}
],
"included": [
{
"id": "6",
"type": "accountability",
"attributes": {
"description": "penetrate the market",
"created_at": "2020-01-16T18:38:26.480Z",
"updated_at": "2020-01-16T18:38:26.480Z"
},
"relationships": {
"role": {
"data": {
"id": "1",
"type": "role"
}
}
}
},
{
"id": "12",
"type": "accountability",
"attributes": {
"description": "immersive experience",
"created_at": "2020-01-16T18:38:26.507Z",
"updated_at": "2020-01-16T18:38:26.507Z"
},
"relationships": {
"role": {
"data": {
"id": "1",
"type": "role"
}
}
}
}
]
}
role.model.ts
import {
JsonApiModelConfig,
JsonApiModel,
Attribute,
HasMany,
BelongsTo
} from 'angular2-jsonapi';
import { Accountability } from '@app/shared/models/accountability.model';
@JsonApiModelConfig({
type: 'roles'
})
export class Role extends JsonApiModel {
@Attribute()
name: string;
@Attribute()
purpose: string;
@Attribute({ serializedName: 'created_at' })
createdAt: Date;
@Attribute({ serializedName: 'updated_at' })
updatedAt: Date;
@HasMany()
accountabilities: Accountability[];
}
accountability.model.ts
import {
JsonApiModelConfig,
JsonApiModel,
Attribute,
BelongsTo
} from 'angular2-jsonapi';
import { Role } from '@app/shared/models/role.model';
@JsonApiModelConfig({
type: 'accountabilities'
})
export class Accountability extends JsonApiModel {
@Attribute()
description: string;
@Attribute({ serializedName: 'created_at' })
createdAt: Date;
@Attribute({ serializedName: 'updated_at' })
updatedAt: Date;
@BelongsTo()
role: Role;
}
datastore.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {
JsonApiDatastoreConfig,
JsonApiDatastore,
DatastoreConfig
} from 'angular2-jsonapi';
import { Role } from '@app/shared/models/role.model';
import { Accountability } from '@app/shared/models/accountability.model';
const config: DatastoreConfig = {
baseUrl: 'http://localhost:3000/api',
apiVersion: 'v1',
models: {
roles: Role,
accountabilities: Accountability
}
};
@Injectable()
@JsonApiDatastoreConfig(config)
export class Datastore extends JsonApiDatastore {
constructor(http: HttpClient) {
super(http);
}
}
role.component.ts
import { Component, OnInit } from '@angular/core';
import { Datastore } from '@app/datastore';
import { Role } from '@app/shared/models/role.model';
import { JsonApiQueryData } from "angular2-jsonapi";
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.sass']
})
export class HomeComponent implements OnInit {
roles: Role[];
constructor(private datastore: Datastore) { }
ngOnInit() {
this.datastore
.findAll(Role, { include: 'accountabilities' })
.subscribe((roles: JsonApiQueryData<Role>) => {
console.log('>>>>>>>>>>>>>', roles);
console.log('>>>>>>>>>>>>>', roles.getModels());
this.roles = roles.getModels();
});
}
}
在 this Github topic 的大量帮助下,我终于设法解决了这个问题。
最初导致该问题的原因是,我从 API 得到的响应列出了 relationships
中的 type
和 included
的单数形式,而它们需要是复数形式。
将 record_type: :accountabilities
添加到我的序列化程序中的 has_many
关系改变了这一点并成功地将响应映射到对象。