Trying to get a custom UFM filter working

Hi @cryothic ,

As @BishalTimalsina12 mentioned that async needs to be removed and there’s one other small change needed on the code which I have added below. Please paste this and try it out:

commerce-country-name.component.js

import { UmbUfmComponentBase } from '@umbraco-cms/backoffice/ufm';
import './commerce-country-name.element.js';

export class CommerceCountryNameApi extends UmbUfmComponentBase {
    render(token) {
        const propertyAlias = (token.value || token.text)?.trim();
        return `<umb-commerce-country-name property-alias="${propertyAlias}"></umb-commerce-country-name>`;
    }
}

export { CommerceCountryNameApi as api };

commerce-country-name.element.js

import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { html } from '@umbraco-cms/backoffice/external/lit';
import { UMB_BLOCK_ENTRY_CONTEXT } from '@umbraco-cms/backoffice/block';

class CommerceCountryNameElement extends UmbLitElement {
    static properties = {
        propertyAlias: { type: String, attribute: 'property-alias' },
        _countryName: { type: String, state: true }
    };

    constructor() {
        super();
        this.propertyAlias = '';
        this._countryName = 'Loading...';
        this._currentGuid = null;
    }

    connectedCallback() {
        super.connectedCallback();

        this.consumeContext(UMB_BLOCK_ENTRY_CONTEXT, async (context) => {
            if (!context) return;

            const contentObservable = await context.contentValues();

            this.observe(contentObservable, (contentData) => {
                if (!contentData) return;

                let guid = null;

                // Safely extract the value regardless of how U17 shapes the data object
                if (Array.isArray(contentData)) {
                    const property = contentData.find(v => v.alias === this.propertyAlias);
                    guid = property ? property.value : null;
                } else if (contentData.values && Array.isArray(contentData.values)) {
                    const property = contentData.values.find(v => v.alias === this.propertyAlias);
                    guid = property ? property.value : null;
                } else {
                    guid = contentData[this.propertyAlias];
                }

                if (guid && guid !== this._currentGuid) {
                    this._currentGuid = guid;
                    this._fetchCountryName(guid);
                } else if (!guid) {
                    this._countryName = 'No country selected';
                }
            }, 'observeCountryContent');
        });
    }

    async _fetchCountryName(guid) {
        this._countryName = 'Fetching...';

        try {
            const response = await fetch(`/umbraco/commerce/storefront/api/v1/country/${guid}`, { credentials: 'include' });

            if (response.ok) {
                const data = await response.json();
                this._countryName = data.name ?? guid;
            } else {
                this._countryName = guid;
            }
        } catch {
            this._countryName = guid;
        }
    }

    render() {
        return html`<span>${this._countryName}</span>`;
    }
}

customElements.define('umb-commerce-country-name', CommerceCountryNameElement);

I have also tested this with a simple setup to just print the field data as label and it worked:

Regards,
Shekhar

1 Like