Bind dynamically localizedlist item's value

Hello!

I would like to know how to bind a localized list item’s value to an element.

Here is my symbol:

It has two input field:
image

A data reference, and a locale, so when I add this symbol to my page, I can pick dynamically the reference and the locale (symbol localization+custom field localization is my goal)

On my page you can see that:

For your help, my data entry has 4 property, but only two of them is localized:

As you can see, in the symbol I could bind a simple property (localized or not) to the element, and I could also achieve to repeat element with the list (localized or not), but I could not solve to bind the localizedItem.value to the element, I got undefined

I console.log the state, but was not able to find the localized item value:

{
    "deviceSize": "large",
    "location": {
        "path": "",
        "query": {}
    },
    "hero": {
        "@type": "@builder.io/core:Reference",
        "id": "b4f1a1eace524d39b97d2f8e0a07d813",
        "model": "localizemodelexample",
        "value": {
            "createdBy": "uw0UJ7VD7hS21zDPkekcB9zZgAD3",
            "createdDate": 1646399897370,
            "data": {
                "description": "Description without localization as well yes",
                "listnolocale": [
                    {
                        "titlem": "elsonemlocale"
                    },
                    {
                        "titlem": "masodiknemlocale"
                    }
                ],
                "localelist": {
                    "@type": "@builder.io/core:LocalizedValue",
                    "en": [
                        {
                            "titlem": "en first title"
                        },
                        {
                            "titlem": "en second item name"
                        }
                    ],
                    "hu": [
                        {
                            "titlem": "magyar elso listitem"
                        },
                        {
                            "titlem": "magyar masodik listitem"
                        }
                    ]
                },
                "title": {
                    "@type": "@builder.io/core:LocalizedValue",
                    "Default": "Hungarian text",
                    "de": "German text",
                    "en": "English text",
                    "hu": "Hungarian text"
                },
                "titlenolocale": "Ez nincs localized text"
            },
            "id": "b4f1a1eace524d39b97d2f8e0a07d813",
            "lastUpdatedBy": "uw0UJ7VD7hS21zDPkekcB9zZgAD3",
            "meta": {
                "kind": "data"
            },
            "modelId": "a72b5ec0082646f7aaf702a80453410c",
            "name": "test",
            "published": "published",
            "query": [],
            "testRatio": 1,
            "variations": {},
            "lastUpdated": 1649154152629,
            "firstPublished": 1646400091673,
            "rev": "3b2igug546k"
        }
    },
    "locale": {
        "locales": "hu"
    },
    "isBrowser": true,
    "isServer": false,
    "device": "mobile",
    "result": {
        "results": [
            {
                "createdBy": "uw0UJ7VD7hS21zDPkekcB9zZgAD3",
                "createdDate": 1646399897370,
                "data": {
                    "description": "Description without localization as well yes",
                    "listnolocale": [
                        {
                            "titlem": "elsonemlocale"
                        },
                        {
                            "titlem": "masodiknemlocale"
                        }
                    ],
                    "localelist": {
                        "@type": "@builder.io/core:LocalizedValue",
                        "en": [
                            {
                                "titlem": "en first title"
                            },
                            {
                                "titlem": "en second item name"
                            }
                        ],
                        "hu": [
                            {
                                "titlem": "magyar elso listitem"
                            },
                            {
                                "titlem": "magyar masodik listitem"
                            }
                        ]
                    },
                    "title": {
                        "@type": "@builder.io/core:LocalizedValue",
                        "Default": "Hungarian text",
                        "de": "German text",
                        "en": "English text",
                        "hu": "Hungarian text"
                    },
                    "titlenolocale": "Ez nincs localized text"
                },
                "id": "b4f1a1eace524d39b97d2f8e0a07d813",
                "lastUpdatedBy": "uw0UJ7VD7hS21zDPkekcB9zZgAD3",
                "meta": {
                    "kind": "data"
                },
                "modelId": "a72b5ec0082646f7aaf702a80453410c",
                "name": "test",
                "published": "published",
                "query": [],
                "testRatio": 1,
                "variations": {},
                "lastUpdated": 1649154152629,
                "firstPublished": 1646400091673,
                "rev": "4gvx51591z7"
            }
        ]
    },
    "$index": 1,
    "$item": {
        "titlem": "magyar masodik listitem"
    },
    "resultsItem": {
        "createdBy": "uw0UJ7VD7hS21zDPkekcB9zZgAD3",
        "createdDate": 1646399897370,
        "data": {
            "description": "Description without localization as well yes",
            "listnolocale": [
                {
                    "titlem": "elsonemlocale"
                },
                {
                    "titlem": "masodiknemlocale"
                }
            ],
            "localelist": {
                "@type": "@builder.io/core:LocalizedValue",
                "en": [
                    {
                        "titlem": "en first title"
                    },
                    {
                        "titlem": "en second item name"
                    }
                ],
                "hu": [
                    {
                        "titlem": "magyar elso listitem"
                    },
                    {
                        "titlem": "magyar masodik listitem"
                    }
                ]
            },
            "title": {
                "@type": "@builder.io/core:LocalizedValue",
                "Default": "Hungarian text",
                "de": "German text",
                "en": "English text",
                "hu": "Hungarian text"
            },
            "titlenolocale": "Ez nincs localized text"
        },
        "id": "b4f1a1eace524d39b97d2f8e0a07d813",
        "lastUpdatedBy": "uw0UJ7VD7hS21zDPkekcB9zZgAD3",
        "meta": {
            "kind": "data"
        },
        "modelId": "a72b5ec0082646f7aaf702a80453410c",
        "name": "test",
        "published": "published",
        "query": [],
        "testRatio": 1,
        "variations": {},
        "lastUpdated": 1649154152629,
        "firstPublished": 1646400091673,
        "rev": "4gvx51591z7"
    },
    "$resultsItemIndex": 0,
    "locales]Item": {
        "titlem": "magyar masodik listitem"
    },
    "$locales]ItemIndex": 1
}

Hope I was just dummy and did not notice anything, and you can tell me the easiest solution for this, because I have a lot of symbols where I should follow this approach!
My goal would be, if I add later localization to my entries, that I don’t have to change anything in my current bindings, only pass the [locale] property to it, which is working for simple properties, but looks like, the list binding is more difficult than that…

Thanks in advance!
Let me know please as soon as possible, because we are building our production app with Builder using Growth plan.

Hi @radikris,

To make sure I’m on the same page, can you clarify where localizedItem.value should be pulled in from? I see the text repeating for localelist, are you wanting to bind the text to the values in localelist?

Yes. I repeat for localelist (with the dynamic locale, hu, en, de etc), and would like to bind the localelistItem.titlem to this textfield, which is not working if you see my example above.

For non localized list it is working perfectly, but with locales it is not.

Hey @radikris if you select an item and click the console in the Data tab
Screen Shot 2022-04-06 at 6.31.08 PM

And enter $block.eval('state') you will see the state elements available to that item:

I was able to get it working by using the $index value:
state.resultsItem.data.localelist[state.locale.locales][$index].titlem

I think it is getting a little confused on all the nested lists which makes it a little more confusing, but this seems to be working. Check it out!

Yes it is working, but would be great an easier solution for it, because I don’t want to rewrite all my bindings for this format, and I have a lot of symbol where I have to change all of my bindings for the localization. (Because currently our data models are not localized, but we will add custom field localization later, and we don’t want to change all of our bindings).

If you check for simple binding (text, img, richtext) :



Nothing changed, only need to add [state.locale.locales] after the property.

And the repeat element is also the same:
No localized:
image

state.resultsItem.data.listnolocale

Localized:
image

state.resultsItem.data.localelist[state.locale.locales]

So until this point, everything is fine, but the difference is when we want to bind the item of the list:

No localized:

state.listnolocaleItem.titlem

Localized (currently your solution):

state.resultsItem.data.localelist[state.locale.locales][$index].titlem

But would be great if something similar would be working like before, because in my opinion this would be the expected behaviour of this binding, if I bind the localizedlist, the child element should know where is it, and simply this should work, we wouldn’t need to change all of our bindings:

state.localelistItem.titlem

Please let me know, how can we find a simpler solution for this like the others binding.

Hi @maddy could you find another solution for it then @TimG ?
Any help is really appreciated, because we need this feature asap in our growth plan production app.

Hey @radikris the difference is that state.resultsItem.data.listnolocale is an array of key value pairs, while state.resultsItem.data.localelist is an object. Are you able to change the data model that localelist is based off of to match exactly the listnolocale? Then we could expect them to have the same behavior. Throwing in the fact that you are using a variable from state (state.locale.lcales) to find the value within localelist, this is a bit of an edge case.

I will agree that this could probably be improved, and I can create a ticket for our backlog to investigate, it will most likely not be a top priority ticket.

I wonder if there is a way to utilize the new locale query updates to address these issues, though you might know better than me considering your understanding of how your various models and data is currently structured. Any ideas?

I will check out this new feature:

And for the fact that the lists are not match, I disagree, because I did not do anything with it, except localized:

The lists:


They are matching the exact same structure, but the localization the only difference between them, so that’s why it is an object.


I saw you tried something but does not seem to work the binding for the localizedlist now.

Throwing in the fact that you are using a variable from state (state.locale.lcales) to find the value within localelist, this is a bit of an edge case.

UPDATE:
I tried this beta feature, doesn’t seem to be working for our solution, where we have a symbol with a reference field, we don’t use the Builder data model, so we just add a symbol to our page, and pick the entry, I thought we can expect that this locale will be passed dynamically to my symbol automatically to the state.
Symbol: Builder.io: Drag and drop page builder and CMS
When we add to the page, you can see:

Because we cannot pick a concrete entry on the symbol, we need to pick the entry on the fly, when we add that symbol to the page. But this new feature seems working only for fixed, picked entry (but the feature works there correctly btw, just not for our use case)

How could I achieve this, with references:

Would be great, if the fetched data by the reference would also know that the locale is hu, and the localelist should be the localized version. (Or how could we avoid the reference but pick the dataentry on the fly, not hard coded in the symbol)

Hope you understand my issue and can help me with it.

Hey @radikris I understand your request, and I will file it as a ticket. As you mentioned I tried to see if it would work within the object, but for nested arrays the XItem notations is not currently supported.

Could you clarify on your last point? Are you saying that the correct data is being set based on locale on the page that a symbol is placed on, but not within the editor of the symbol itself?

The main goal is, that this new beta localization feature is working perfectly for a fixed data entry and as we can see in the photo: only the binded type of the localizedlist (only the selected locale type HU) will be in the state, nevertheless with our reference approach where we pick the entries on the fly (when we add it to the page) you can see all of the localelizedlist type HU,EN,DE will be in the state which we know it is problematic to bind correctly.

So what do you think, is it possible that we dont hardcode any entry inside the symbol, we only bind the data model reference (after that we will fetch dynamically by id), and only the binded version of the localized properties will be in the state (just like similarly as a fixed entry)

Does it make more sense now or should I explain better?

Hey @radikris this update has been going through a few updates, it should be released in its final beta form later next week, it is possible that this will be resolved by that update. If not, I have raised this issue with our dev team and we can include a ticket in our backlog to be prioritized and fixed hopefully soon

Thanks, as always for bringing it to our attention! Let me know if the working solution of using
state.resultsItem.data.localelist[state.locale.locales][$index].titlem no longer works in the meantime!