[英]How to align response json with TypeScript interface Angular6
I'm retrieving a list of uploaded files from a backend endpoint that returns it in the following format: 我正在从后端端点检索上传文件的列表,该文件以以下格式返回:
[
{
"filename": "setup.cfg",
"id": 1,
"path": C:\\back-end\\uploads\\setup.cfg",
"uploaded_at": "Fri, 01 Jun 2018 09:25:19 -0000"
},
{
"filename": "57760713_1467275948.jpg",
"id": 2,
"path": "C:\\back-end\\uploads\\57760713_1467275948.jpg",
"uploaded_at": "Mon, 04 Jun 2018 09:09:59 -0000"
},
.
.
.
]
And I have the following TypeScript interface to align them with: 而且我有以下TypeScript界面可以与它们对齐:
export interface UploadModel {
id: number;
name: string;
path: string;
uploadedAt: Date;
}
As you can see the retrieved data uses the snake_case naming convention as uploaded_at
while the interface uses the camelCase convention as uploadedAt
. 正如你可以看到检索到的数据使用snake_case命名约定
uploaded_at
而接口采用驼峰约定uploadedAt
。
I would like to use the following snippet to get the data from the backend: 我想使用以下代码片段从后端获取数据:
getUploads(): Observable<UploadModel[]> {
this.http.get(UPLOADS_ENDPOINT)
.map((response: Response) => {
// parse the json response here, and return an array of UploadModels
});
}
Is there any clever way to map these two representations, without mapping through the array of JSON objects? 是否有任何巧妙的方法可以映射这两种表示形式,而无需通过JSON对象数组进行映射?
You can write a general function that converts all keys from underscored to camel casing. 您可以编写一个通用函数,将所有键从下划线转换为驼峰式大写字母。 This is a rather crude version - you could make this more graceful and even recursive should you need to fix nested objects.
这是一个相当粗糙的版本-如果需要修复嵌套对象,则可以使它更为优美甚至递归。
const data = [
{
"filename": "setup.cfg",
"id": 1,
"path": "C:\\back-end\\uploads\\setup.cfg",
"uploaded_at": "Fri, 01 Jun 2018 09:25:19 -0000"
},
{
"filename": "57760713_1467275948.jpg",
"id": 2,
"path": "C:\\back-end\\uploads\\57760713_1467275948.jpg",
"uploaded_at": "Mon, 04 Jun 2018 09:09:59 -0000"
}
];
function underscoreToCamel(key: string) {
return key.replace(/_([a-z])/g, function (g) { return g[1].toUpperCase(); });
}
function convertKeys(input: any[]) {
const output = [];
for (const item of input) {
const obj = {};
for (const key in item) {
obj[underscoreToCamel(key)] = item[key];
}
output.push(obj);
}
return output;
}
const result = convertKeys(data);
console.log(result);
Output: 输出:
[
{
"filename":"setup.cfg",
"id":1,
"path":"C:\\back-end\\uploads\\setup.cfg",
"uploadedAt":"Fri, 01 Jun 2018 09:25:19 -0000"
},
{
"filename":"57760713_1467275948.jpg",
"id":2,
"path":"C:\\back-end\\uploads\\57760713_1467275948.jpg",
"uploadedAt":"Mon, 04 Jun 2018 09:09:59 -0000"
}
]
No, there isn't. 不,没有。
I would advise you to cope with your response, but it seems you don't want to do it. 我建议您应对您的答复,但似乎您不想这样做。
From that, you have three solutions : 由此,您有三种解决方案:
Create two interfaces : IUploadResponse
and IUpload
( model
is redundant). 创建两个接口:
IUploadResponse
和IUpload
( model
是冗余的)。 The objects instanciating those interface will make an explicit mapping in the constructor, 实例化这些接口的对象将在构造函数中进行显式映射,
Create an abstract class that has a transformation method : again, explicit mapping, 创建一个具有转换方法的抽象类:再次,显式映射,
Create a snake_case to camelCase converter, that creates a plain object from snake to camel. 创建一个snake_case到camelCase转换器,该转换器创建一个从蛇到骆驼的普通对象。 The advantage is that you can reuse that, the drawback is that you can't change
filename
to name
. 优点是可以重复使用,缺点是不能将
filename
更改为name
。 Also, it won't create Objects per se , so you won't have access to typeof
or instanceof
. 另外,它本身不会创建Objects,因此您将无法访问
typeof
或instanceof
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.