sw-entity-listing: 无法读取未定义的属性(读取’page’)

huangapple go评论84阅读模式
英文:

sw-entity-listing: Cannot read properties of undefined (reading 'page')

问题

在我使用的管理界面中,我使用了sw-entity-listing组件,用于加载自定义实体的条目。该列表有四列(客户组、销售渠道、产品和最大数量)。客户组和销售渠道包含一个ID,产品列包含一个包含ID的JSON。

我想要做的是将这些ID映射到实际的实体名称。为此,我创建了以下JS代码:

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>');
}

一切都正常工作,但是我在控制台日志中收到了一个错误:An error was captured in current module: TypeError: Cannot read properties of undefined (reading 'page')

当我使用以下代码时,错误消失了,但是我没有数据映射:

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;
    })
}

由于这个错误,组件的删除功能无法按预期工作(删除后页面不会重新加载并且冻结)。是什么导致了这个问题,我该如何解决?

英文:

In the administration I'm using the sw-entity-listing component where I load the entries of a custom entity. The listing has four columns (customer group, sales channel, products and maxcount). customer group and sales channel contains an ID and products contains an JSON with ID's.

What I'm trying to do is map the ID's to the actual entity names. For that part I've created this JS:

getList() {
            this.isLoading = true;
            const criteria = new Criteria();
            return this.cartCrossSellRepository.search(criteria, Shopware.Context.api).then(async (result) =&gt; {
                this.total = result.total;

                const cartCrossSell = result.map(async (item) =&gt; {
                    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(&#39;id&#39;, 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(&#39;id&#39;, 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) =&gt; product.productNumber);

            return productNames.join(&#39;&lt;br&gt;&#39;);
        }

All is working fine but I'm getting an error in my console log: An error was captured in current module: TypeError: Cannot read properties of undefined (reading &#39;page&#39;).

When I use something like this the error is gone but then I don't have the data mapping:

getList() {
			this.isLoading = true;
			const criteria = new Criteria();
			return this.cartCrossSellRepository.search(criteria, Shopware.Context.api).then((result) =&gt; {
				this.total = result.total;
				this.cartCrossSell = result;
				this.isLoading = false;
			})
		}

Because of the error, the delete function of the component isn't working as expected (page isn't reloading after delete and freezes). What is causing the problem and how can I fix this?

答案1

得分: 2

该列表期望返回一个EntityCollection类型,通常情况下,存储库上的search调用会返回该类型。然而,您通过映射原始结果返回了一个通用对象的数组。这里有一些不太理想的地方。显然,您有一个指向customer_groupsales_channel的外键。因此,我假设您的实体定义部分如下所示:

new FkField('customer_group_id', 'customerGroupId', CustomerGroupDefinition::class),
new FkField('sales_channel_id', 'salesChannelId', SalesChannelDefinition::class),
new ManyToOneAssociationField('customerGroup', 'customer_group_id', CustomerGroupDefinition::class, 'id'),
new ManyToOneAssociationField('salesChannel', 'sales_channel_id', SalesChannelDefinition::class, 'id'),

然后,当通过cartCrossSellRepository获取实体时,您可以简单地将相应的关联添加到条件中。这样,您就不必在每次迭代时获取sales_channelcustomer_group的单个实例,从而使整个过程更加高效。

const criteria = new Criteria();
criteria.addAssociation('customerGroup');
criteria.addAssociation('salesChannel');

this.cartCrossSellRepository.search(criteria, Shopware.Context.api).then(async (result) => {
    result.forEach((item) => {
        // 应该记录由关联获取的相应实体数据
        console.log(item.customerGroup);
        console.log(item.salesChannel);
    });
});

对于产品,最好也使用相应的关联。然而,看起来您的products属性只是一个包含ID的JSON字段?如果还没有这样做,我建议将其改为适当的ManyToManyAssociationField

如果您想继续使用当前的方法,您可以简单地迭代EntityCollection的项,并将附加数据设置为实体的未映射属性。

this.cartCrossSellRepository.search(criteria, Shopware.Context.api).then(async (result) => {
    result.forEach((item) => {
        item.productNames = await this.getProductNames(item.products);
    });

    return result;
});
英文:

The listing is expecting a type of EntityCollection which the search call on the repository would normally return. You however return an array of generic objects by mapping the original result. There are a few things that don't seem optimal here. You obviously have a foreign key to customer_group, as well as sales_channel. So I assume your entity definition partially looks like this:

new FkField(&#39;customer_group_id&#39;, &#39;customerGroupId&#39;, CustomerGroupDefinition::class),
new FkField(&#39;sales_channel_id&#39;, &#39;salesChannelId&#39;, SalesChannelDefinition::class),
new ManyToOneAssociationField(&#39;customerGroup&#39;, &#39;customer_group_id&#39;, CustomerGroupDefinition::class, &#39;id&#39;),
new ManyToOneAssociationField(&#39;salesChannel&#39;, &#39;sales_channel_id&#39;, SalesChannelDefinition::class, &#39;id&#39;),

Then you could simply add the corresponding association to the criteria when fetching the entities by the cartCrossSellRepository. That way, you wouldn't have to fetch individual instances of sales_channel and customer_group on each iteration, making the whole procedure much more performant.

const criteria = new Criteria();
criteria.addAssociation(&#39;customerGroup&#39;);
criteria.addAssociation(&#39;salesChannel&#39;);

this.cartCrossSellRepository.search(criteria, Shopware.Context.api).then(async (result) =&gt; {
    result.forEach((item) =&gt; {
        // should log the respective entity data fetched by association
        console.log(item.customerGroup);
        console.log(item.salesChannel);
    });
});

For the products you ideally should also use the corresponding association as well. However it seems like your products property is just a json field containing the ids? I would advise to make it a proper ManyToManyAssociationField if not already the case.

If you want to stick with your current approach, you could simply iterate the items of the EntityCollection and set your additional data as an unmapped property to the entity.

this.cartCrossSellRepository.search(criteria, Shopware.Context.api).then(async (result) =&gt; {
    result.forEach((item) =&gt; {
        item.productNames = await this.getProductNames(item.products);
    });

    return result;
});

huangapple
  • 本文由 发表于 2023年8月9日 17:13:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76866232.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定