rammi22
rammi22

Reputation: 403

Shopware 6: sw-inherit-wrapper property currentValue does not update on select

I've a custom entity enterprise, which is assigned to product.extensions.myPlugin.enterpriseId.

Now i want to select the enterprise within Shopware Vue-Component sw-entity-single-select wrapped by sw-inherit-wrapper:

<sw-inherit-wrapper
    v-model="product.extensions.myPlugin.enterpriseId"
    :has-parent="false"
    :inherited-value="null">
    <template #content="{currentValue, updateCurrentValue, isInherited}">
        <sw-entity-single-select
            class="enterprise-name"
            :key="isInherited"
            :value="currentValue"
            entity="enterprise"
            :placeholder="$tc('inputEnterprise.placeholder')"
            show-clearable-button
            allow-entity-creation
            :entity-creation-label="$tc('inputEnterprise.labelCreation')"
            @change="updateCurrentValue"></sw-entity-single-select>
    </template>
</sw-inherit-wrapper>

This template ist part of a modal.

On select a enterprise from given list, the <sw-entity-single-select__selection-text> does not update.

Step out step in into the template (close and reopen the parent modal), the enterprise is set and printed out on the <sw-entity-single-select__selection-text>.
So the entity extension was updated but not the property currentValue in <sw-entity-single-select__selection-text>

As example i follow the sw_product_basic_form_manufacturer_field

Question: Why property currentValue does not update in <sw-entity-single-select> on select from its list?

EDIT #1
The extension is set in overridden component sw-product-detail like this:

// sw-product-detail/index.js
...
Component.override('sw-product-detail', {
    ...
    computed: {
        myPluginRepository() {
            return this.repositoryFactory.create('my_plugin');
        },
    }
    watch: {
        product() {
            if(this.product.id) {
                this.__setMyPluginExtension()
            }
        }
    },
    methods: {
        ...
        __setMyPluginExtension() {
            let extension = this.product.extensions.myPlugin ?? null;
            if(null === extension) {
                extension = 
                this.myPluginRepository.create(Shopware.Context.api);
                extension.enterpriseId = null
            }
            this.product.extensions.myPlugin = extension;
        },        
    }

}

Inside the overridden child component sw-product-detail-base the modal is loaded.
I think, the extension is known when the component is loaded and rendered. I've check it with a debug breakpoint inside the created() in the custom component, the extension is known like defined in parent component.
Even more, if i set extension.enterpriseId a real default value instead null then the enterprise is printed out in <sw-entity-single-select__selection-text>, what me indicate, the extension is known.

Btw, i used the change method, but i'm looking for my error...

Upvotes: 0

Views: 383

Answers (2)

rammi22
rammi22

Reputation: 403

As addition of @dneustadt answers:

...
const extension = this.myPluginRepository.create(Shopware.Context.api);
extension.enterpriseId= null

this.$set(this.product.extensions, 'myPlugin', extension)
...

Use the repository create() method instead create a simple object because of required method entity.getEntityName() in changeset-generator.data.js

Upvotes: 0

dneustadt
dneustadt

Reputation: 13161

Best guess without knowing more of the stack would be that this.product.extensions.myPlugin.enterpriseId isn't reactive. That would be the case if the property doesn't exists when the product is originally set and it is declared like this:

this.product.extensions.myPlugin = {
    enterpriseId: 'asdf'
};

Any further changes to enterpriseId would then not be reactive and the view would subsequently not be updated when it changes.

To be safe you could add a @change listener to sw-inherit-wrapper and update the property reactively:

onEnterpriseIdChange(enterpriseId) {
    if (!this.product.extensions.myPlugin) {
        this.$set(this.product.extensions, 'myPlugin', {});
    }
    if (!this.product.extensions.myPlugin.enterpriseId) {
        this.$set(this.product.extensions.myPlugin, 'enterpriseId', enterpriseId);
    }
}

Upvotes: 1

Related Questions