Torben
Torben

Reputation: 5494

How to use <sw-entity-single-select> correctly?

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!

Upvotes: 2

Views: 1749

Answers (1)

dneustadt
dneustadt

Reputation: 13161

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>

Upvotes: 2

Related Questions