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

JSON解析意外空格错误:AppwriteDB字符串数组转对象解决方法

Angular中Appwrite DB的orderItems字段解析与*ngFor展示问题

问题背景

Angular项目中,Appwrite数据库的orderItems字段以string[]类型存储(Appwrite仅支持该数组类型),尝试用*ngFor直接展示该字段内容失败;使用JSON.parse()转换时触发「意外空格检测」错误,以下两种尝试均无效:

已尝试方法

方法1

res.documents.map((el:any) => {return JSON.parse(el.orderItems)} );

错误原因:el.orderItems是数组类型,直接传给JSON.parse()会报错,因为该方法仅接受字符串参数。

方法2

res.documents.map((el:any) => {
    return el.orderItems.map((el2:any) => {return JSON.parse(el2)})
})

问题:该代码仅返回了解析后的orderItems数组,未修改原订单对象的orderItems字段,导致模板中仍使用未解析的原数据。

数据结构

[
  {
    "orderStatus": "New",
    "orderPayment": "Paid",
    "orderItems": [
      "{\"productName\":\"Nokia Windows mobile\",\"productPrice\":299,\"productDetails\":\"Nokia windows 10 mobile\",\"productAvailable\":true,\"qty\":1,\"$id\":\"65f21c5cdd3449f30f68\",\"$createdAt\":\"2024-03-13T21:36:28.906+00:00\",\"$updatedAt\":\"2024-03-13T21:36:28.906+00:00\",\"$permissions\":[],\"$databaseId\":\"smartCartDB\",\"$collectionId\":\"Products\"}"
    ],
    "$id": "65f6fcc4e65c46fc6e97",
    "$createdAt": "2024-03-17T14:23:00.944+00:00",
    "$updatedAt": "2024-03-17T14:23:00.944+00:00",
    "$permissions": [],
    "products": [],
    "$databaseId": "smartCartDB",
    "$collectionId": "Orders"
  },
  {
    "orderStatus": "New",
    "orderPayment": "Paid",
    "orderItems": [
      "{\"productName\":\"Samsung s25\",\"productPrice\":1499,\"productDetails\":\"Samsung mobile, 1TB\",\"productAvailable\":true,\"qty\":1,\"$id\":\"65f21c2d5ded54bcacf3\",\"$createdAt\":\"2024-03-13T21:35:41.385+00:00\",\"$updatedAt\":\"2024-03-13T21:35:41.385+00:00\",\"$permissions\":[],\"$databaseId\":\"smartCartDB\",\"$collectionId\":\"Products\"}",
      "{\"productName\":\"Apple Iphone\",\"productPrice\":1299,\"productDetails\":\"Apple Iphone 256GB\",\"productAvailable\":true,\"qty\":1,\"$id\":\"65f0f3c878c1a95a63fe\",\"$createdAt\":\"2024-03-13T00:31:04.495+00:00\",\"$updatedAt\":\"2024-03-13T00:31:04.495+00:00\",\"$permissions\":[],\"$databaseId\":\"smartCartDB\",\"$collectionId\":\"Products\"}"
    ],
    "$id": "65f79c39d27f2846a512",
    "$createdAt": "2024-03-18T01:43:21.907+00:00",
    "$updatedAt": "2024-03-18T01:43:21.907+00:00",
    "$permissions": [],
    "products": [],
    "$databaseId": "smartCartDB",
    "$collectionId": "Orders"
  },
  {
    "orderStatus": "New",
    "orderPayment": "Paid",
    "orderItems": [
      "{\"productName\":\"Nokia Windows mobile\",\"productPrice\":299,\"productDetails\":\"Nokia windows 10 mobile\",\"productAvailable\":true,\"qty\":1,\"$id\":\"65f21c5cdd3449f30f68\",\"$createdAt\":\"2024-03-13T21:36:28.906+00:00\",\"$updatedAt\":\"2024-03-13T21:36:28.906+00:00\",\"$permissions\":[],\"$databaseId\":\"smartCartDB\",\"$collectionId\":\"Products\"}",
      "{\"productName\":\"Moto Edge 40 Neo\",\"productPrice\":799,\"productDetails\":\"Moto Edge 40 Neo 256GB\",\"productAvailable\":true,\"qty\":1,\"$id\":\"65f21c437b6056836618\",\"$createdAt\":\"2024-03-13T21:36:03.506+00:00\",\"$updatedAt\":\"2024-03-13T21:36:03.506+00:00\",\"$permissions\":[],\"$databaseId\":\"smartCartDB\",\"$collectionId\":\"Products\"}"
    ],
    "$id": "65f79d9eb083ae49c565",
    "$createdAt": "2024-03-18T01:49:18.723+00:00",
    "$updatedAt": "2024-03-18T01:49:18.723+00:00",
    "$permissions": [],
    "products": [],
    "$databaseId": "smartCartDB",
    "$collectionId": "Orders"
  },
  {
    "orderStatus": "New",
    "orderPayment": "Paid",
    "orderItems": [
      "{\"productName\":\"Samsung s25\",\"productPrice\":1499,\"productDetails\":\"Samsung mobile, 1TB\",\"qty\":4}",
      "{\"productName\":\"Apple Iphone\",\"productPrice\":1299,\"productDetails\":\"Apple Iphone 256GB\",\"qty\":5}"
    ],
    "$id": "65f7a621020a4525e698",
    "$createdAt": "2024-03-18T02:25:37.009+00:00",
    "$updatedAt": "2024-03-18T02:25:37.009+00:00",
    "$permissions": [],
    "products": [],
    "$databaseId": "smartCartDB",
    "$collectionId": "Orders"
  }
]

正确转换方案

1. 数据转换逻辑

遍历每个订单对象,将其orderItems数组中的每个JSON字符串逐个解析,并替换原对象的orderItems字段;添加try-catch块避免单个解析失败导致整个流程中断,同时便于排查格式错误的字符串:

// 假设res.documents是从Appwrite获取的订单数组
const parsedOrders = res.documents.map((order: any) => {
  // 解析每个orderItems中的JSON字符串
  order.orderItems = order.orderItems.map((itemStr: string) => {
    try {
      // 若仍有空格问题,可添加trim()处理:JSON.parse(itemStr.trim())
      return JSON.parse(itemStr);
    } catch (error) {
      console.error(`解析订单${order.$id}的商品失败:`, itemStr, error);
      return null; // 返回null或空对象,避免模板报错
    }
  });
  return order;
});

// 将解析后的数组赋值给组件变量,供模板使用
this.orders = parsedOrders;

2. 模板中使用*ngFor展示

转换完成后,即可在模板中正常使用*ngFor遍历订单及订单商品:

<div *ngFor="let order of orders">
  <div class="order-card">
    <h4>订单ID: {{order.$id}}</h4>
    <p>状态: {{order.orderStatus}} | 支付状态: {{order.orderPayment}}</p>
    <h5>商品列表:</h5>
    <div *ngFor="let item of order.orderItems" class="product-item" *ngIf="item">
      <p>商品名: {{item.productName}}</p>
      <p>价格: {{item.productPrice}} | 数量: {{item.qty}}</p>
      <p>{{item.productDetails}}</p>
    </div>
  </div>
</div>

额外优化建议

建议定义TypeScript接口规范订单和商品类型,避免any类型带来的隐患:

interface Product {
  productName: string;
  productPrice: number;
  productDetails: string;
  productAvailable?: boolean;
  qty: number;
  $id?: string;
  $createdAt?: string;
  // 其他字段...
}

interface Order {
  orderStatus: string;
  orderPayment: string;
  orderItems: Product[];
  $id: string;
  $createdAt: string;
  // 其他字段...
}

// 转换时使用接口
const parsedOrders = res.documents.map((order: Order) => {
  // ...转换逻辑
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:55:55