I use a <sw-entity-single-select>
component like this:
<sw-entity-single-select
entity="sales_channel"
v-model="setting.salesChannels"
@change="selectSalesChannel"
>
</sw-entity-single-select>
salesChannels
in my entity has this Definition:
(new ManyToManyAssociationField('salesChannels', SalesChannelDefinition::class, CustomSettingSalesChannelDefinition::class, 'custom_setting_id', 'sales_channel_id'))->addFlags(new ApiAware(), new CascadeDelete()),
When I select a SalesChannel inside setting.salesChannels
I have the ID of the selected entity. I know that I use a ManyToMany Field here, but only a single select and not a multi select in my component. I want it that way, because most likely I need to enhance it to a multi select in the future.
So this works, I can save the custom entity and the relation to the SalesChannel is set - I do not do this with the repository in JS, but with PHP and a custom controller like this:
'salesChannels' => [
[
'id' => $setting->getSalesChannels()
]
],
My issue is now, that when I use the same UI/Component to edit an item, I get the Objects from the Database, but I need the Ids in v-model
to pre-fill the selected item in the entity-single-select component.
When I do this, the item is pre-filled and selected. However when I want to save my custom entity - and here I do not use the same php logic as above, but the repository pattern in Vue - then it does not work and I get JS errors like this:
draft.has is not a function
or some failure with draft.forEach
When I do not use the ID in setting.salesChannels
but the Object which comes from the database and save the custom entity, it works. But the item is not pre-filled in the select component.
So the component needs the IDs to pre-fill the item, but the object to save it?
How can I solve this - or where is my mistake? Thanks for any help!
In your component you could have a computed property that slices of the first id of your sales channel collection for providing the value of the entity select. In the change listener you then create a collection and add the one item selected. You also won't need the server side workaround that way.
const { EntityCollection } = Shopware.Data;
// ...
computed: {
salesChannelId() {
if (!this.setting.salesChannels.length) {
return null;
}
return this.setting.salesChannels.first().id;
}
},
methods: {
selectSalesChannel(id, item) {
const collection = new EntityCollection('/sales_channel', 'sales_channel', Shopware.Context.api);
if (item) {
collection.add(item);
}
this.setting.salesChannels = collection;
}
}
<sw-entity-single-select
entity="sales_channel"
:value="salesChannelId"
@change="selectSalesChannel"
>
</sw-entity-single-select>