Shopware sw-entity-listing映射实体ID后报page未定义错误及删除异常
问题
在Shopware后台管理中使用sw-entity-listing组件加载自定义实体条目,列表包含客户组、销售渠道、产品、maxcount四列,其中客户组和销售渠道为ID,产品为ID组成的JSON数组。尝试将这些ID映射为实际实体名称后,功能可运行,但控制台抛出错误:
"An error was captured in current module: TypeError: Cannot read properties of undefined (reading 'page')"
且组件删除功能异常:删除后页面不刷新且冻结。若不做ID到名称的映射,直接赋值this.cartCrossSell = result则无错误,但无法实现名称转换。
映射用代码如下:
getList() { this.isLoading = true; const criteria = new Criteria(); return this.cartCrossSellRepository.search(criteria, Shopware.Context.api).then(async (result) => { this.total = result.total; const cartCrossSell = result.map(async (item) => { const customerGroup = await this.getCustomerGroupName(item.customerGroupId); const salesChannel = await this.getSalesChannelName(item.salesChannelId); const products = await this.getProductNames(item.products); return { ...item, customerGroup, salesChannel, products }; }); this.cartCrossSell = await Promise.all(cartCrossSell); this.isLoading = false; }); }, async getCustomerGroupName(customerGroupId) { const criteria = new Criteria(); criteria.addFilter(Criteria.equals('id', customerGroupId)); const customerGroup = await this.customerGroupRepository.search(criteria, Shopware.Context.api); return customerGroup[0].translated.name; }, async getSalesChannelName(salesChannelId) { const criteria = new Criteria(); criteria.addFilter(Criteria.equals('id', salesChannelId)); const salesChannel = await this.salesChannelRepository.search(criteria, Shopware.Context.api); return salesChannel[0].translated.name; }, async getProductNames(productIds) { const criteria = new Criteria(); criteria.setIds(productIds); const products = await this.productRepository.search(criteria, Shopware.Context.api); const productNames = products.map((product) => product.productNumber); return productNames.join('<br>'); }
无错误但无名称转换的代码:
getList() { this.isLoading = true; const criteria = new Criteria(); return this.cartCrossSellRepository.search(criteria, Shopware.Context.api).then((result) => { this.total = result.total; this.cartCrossSell = result; this.isLoading = false; }) }
原因分析
sw-entity-listing组件依赖Shopware返回的SearchResult对象(而非普通数组)处理分页、状态同步(比如删除后的刷新)等逻辑。原代码中,通过Promise.all(result.map(...))将SearchResult对象转换成了普通数组,丢失了SearchResult自带的page、limit等属性,组件读取这些属性时就会抛出Cannot read properties of undefined (reading 'page')错误,进而导致删除功能异常。
解决方法
保留SearchResult对象的结构,仅对其中的items进行字段映射处理,具体步骤:
- 遍历SearchResult的
items数组,逐个处理ID到名称的映射 - 替换原SearchResult的
items为处理后的数组,保留原对象的分页、总数等属性 - 确保赋值给
this.cartCrossSell的仍然是SearchResult对象
修改后的代码:
getList() { this.isLoading = true; const criteria = new Criteria(); return this.cartCrossSellRepository.search(criteria, Shopware.Context.api).then(async (result) => { // 遍历并处理每个条目,保留原SearchResult结构 const processedItems = await Promise.all(result.items.map(async (item) => { const customerGroup = await this.getCustomerGroupName(item.customerGroupId); const salesChannel = await this.getSalesChannelName(item.salesChannelId); const products = await this.getProductNames(item.products); return { ...item, customerGroup, salesChannel, products }; })); // 替换原SearchResult的items,保留其他属性(page、total等) result.items = processedItems; this.cartCrossSell = result; this.total = result.total; this.isLoading = false; }); }, async getCustomerGroupName(customerGroupId) { const criteria = new Criteria(); criteria.addFilter(Criteria.equals('id', customerGroupId)); const customerGroup = await this.customerGroupRepository.search(criteria, Shopware.Context.api); return customerGroup[0]?.translated?.name || customerGroupId; // 增加空值容错,避免找不到数据时报错 }, async getSalesChannelName(salesChannelId) { const criteria = new Criteria(); criteria.addFilter(Criteria.equals('id', salesChannelId)); const salesChannel = await this.salesChannelRepository.search(criteria, Shopware.Context.api); return salesChannel[0]?.translated?.name || salesChannelId; // 增加空值容错 }, async getProductNames(productIds) { if (!productIds || productIds.length === 0) return ''; // 空数组处理 const criteria = new Criteria(); criteria.setIds(productIds); const products = await this.productRepository.search(criteria, Shopware.Context.api); // 匹配原ID顺序,避免返回结果顺序不一致 const productMap = new Map(products.map(p => [p.id, p.productNumber])); const productNames = productIds.map(id => productMap.get(id) || id); return productNames.join('<br>'); }
额外优化:
- 为获取名称的方法增加空值容错,避免实体不存在时抛出错误
- 产品名称映射时保留原ID顺序,避免因搜索返回顺序不一致导致名称对应错误
内容的提问来源于stack exchange,提问作者Jacky Raimond
相关产品推荐
相关产品推荐

