Showing Values from Collection in Repeaters - Code Stopped Working

Background: Text boxes used to display Country, State etc from Google Location object field in collection.
The text boxes were in repeaters in a Dynamic List page.

Issue: The following code worked perfectly for months, until recently. Now, on all the repeaters it displays the same 1 value. The value is from the first item of the collection (I’ve changed the value and tested, it still queries & displays). Unlike before, the respective values of every item is not reflected on their repeaters.
Could this be an instance of past Velo code breaking?

Question: Can someone please send some updated code for this?

$w.onReady(async function () {
    const result = await wixData.query("Properties").find();
    if (result.items.length > 0) {
        const item = result.items[0];
        const location = item.mapLocation;

        if (location) {
            const country = location.country;
            const state = location.subdivision;
            const city = location.city;

            $w("#collapsibleText2").text = `${city}, ${state}, ${country}`;
        }
    }
});

1 Like

As is, this code shouldn’t ever have worked, it clearly sets a singular item variable to the first row fetched from the Properties collection (result.items[0]), then it sets all occurrences of #collapsibleText2 to the text generated from it

So, if your code worked populating a repeater for months, it wasn’t this snippet


Here’s a short code that may provide the functionality you desire:

$w('#repeater').onItemReady(($item, itemData) => {
    const location = itemData.location
    if (itemData.location) {
        const { city, state, country } = itemData.mapLocation // Deconstruction
        // not $w, so it only targets the specific repeater occurence
        $item('#collapsibleText2').text = `${city}, ${state}, ${country}`;
           
    } // else $item('#collapsibleText2').collapse()
})
  • I assume you want to populate a single text element with the text generated by the three properties of the mapLocation CMS field
  • I assume that repeater is already connected to the Properties connection through a dataset (As I see the other elements in your screenshots are displaying different values)

I really appreciate your response. I tried your code, but it showed errors (screenshot 1). As I’m not a coder I don’t know how to correct this or integrate this with the available code. I’ll paste the full current code in a code block at the end so that you could send the full solution, if possible.
Both your assumptions are right. But are there more lines to be included in your code? Like some in my old code like await../async../const.. . Has your code considered that it should pull from a location object? Just wondering as a noob, you prally know.


Also, I assumed that the #repeater should be replaced by #propertiesRepeater
Please lmk if I’m wrong

import wixData from 'wix-data';

$w.onReady(async function () {
    const result = await wixData.query("Properties").find();
    if (result.items.length > 0) {
        const item = result.items[0];
        const location = item.mapLocation;

        if (location) {
            const country = location.country;
            const state = location.subdivision;
            const city = location.city;

            $w("#collapsibleText2").text = `${city}, ${state}, ${country}`;
        }
    }
});

Dean was asking you about the DATASET not out of nowhere.
Normaly you should first wait for the DATASET to be ready first when you are interacting with Wix-Data → (Mixing Wix-Data+CODE and an already setted-up DATASET).

In none of provided codes i could find something like…

//Importing the neccessary libraries... (in your case wix-data)
import wixData from 'wix-data';

// This code is executed when the page is ready
$w.onReady(async()=> {
    $w('#myDataset').onReady(()=>{
        //...
        // ...your CODE here...
        //...
    });
});

This makes sure that your code will only start acting after both (PAGE & DATASET) are → READY! This is one of first biggest mistakes what is always done by a ongoing wix-coder.

Also why not first make things clear by making some clear definitions of what is what, generating a → USER-INTERFACE <—, like …

It looks like your main problem is the switch from dataset-based-setup → to a mixed-setup using dataset and wix-data (coding).

import wixData from 'wix-data';
// This code is executed when the page is ready

//Integrated USER-INTERFACE...
//xxxxxxxxxxxxxxxxxx [USER-INTERFACE] xxxxxxxxxxxxxx
const DATASET = "define your dataset here";
const DATABASE = "define your database here";
const FIELD = "define your field here";

//You could define maybe even more, depending on your setup, like this:
const VALUE = "define your value here";
const FILTER = "define your filter here";
const FILTERVALUE = "define your filter value here";
const FILTERFIELD = "define your filter field here";
//...and so on and so on....
//xxxxxxxxxxxxxxxxxx [USER-INTERFACE] xxxxxxxxxxxxxx

Ok, once done all your DEFINITIONS and DECLARATIONS, you now can continue with your code, using them…

$w.onReady(()=> {console.log('I am the page and i am ready now, but is the dataset also already --> READY ???');        
    
    $w(`#${DATASET}`).onReady(async()=>{console.log('I am the dataset and i am ready now...');        
        
        // DATA-PART --> Let us first retrieve your data from the database and then we can use it in the repeater (we do not forget to use the async/await pattern here).
        const myDataQuery = await wixData.query(DATABASE).find(); console.log('myDataQuery: ', myDataQuery); 
        
        // REPEATER-PART...
        $w(`#${REPEATER}`).onItemReady(($item, itemData, idex) => {console.log('Item-Data: ', itemData); // Log the itemData to see its structure.  
            // Check if itemData is defined and is not null...
            if(itemData) {console.log('Item-Data is defined and not null...');
                // Check if itemData has a location property...
                if (itemData[FIELD]) { console.log('Item-Data has a location property...');
                    // Get the location data from itemData...
                    const mapLocation = itemData[FIELD]; // Assuming itemData has a mapLocation property.  FIELD = "mapLocation", defined above.
                    // Going the more simple way... instead of ---> const { city, state, country } = itemData.mapLocation; // Deconstruction
                    const city = mapLocation.city; // Assuming mapLocation has a city property.
                    const state = mapLocation.state; // Assuming mapLocation has a state property.
                    const country = mapLocation.country; // Assuming mapLocation has a country property.
                    // Not $w, so it only targets the specific repeater occurence --> (Wix-RULE: OUTSIDE of REPEATERS => $w and INSIDE of REPEATERS => $item)
                    $item('#txtElemntCity').text = `${city}`; // This will show CITY in one of the appropirate text elements.
                    $item('#txtElemetState').text = `${state}`; // This will show STATE in one of the appropirate text elements.
                    $item('#txtElementCountry').text = `${country}`; // This will show COUNTRY in one of the appropirate text elements.
                    $item('#txtElementAlltogether').text = `${city}, ${state}, ${country}`; // This will show the full address in just one text appropirate elements.
                } else {console.log('Item-Data does not have a location property...');}  
            } else {console.log('Item-Data is not defined or null...');} // If itemData is not defined or null, do nothing.
        });
        
    });

});

But looks like something is still missing! What could it be?

Also check if all your ELEMENT-IDs are correct regarding the provided code!
Either adjust the code, or your IDs accordingly.

NO! NOT THE CODE → BECAUSE YOU HAVE NOW YOUR → USER-INTERFACE !!!
THE USER-INTERFACE IS NOW THE AREA FOR MAKING CHANGES, REGARDING YOUR VALUES & IDs!!! :upside_down_face:

USE MORE → CONSOLE-LOGS and check them inside of your → CONSOLE!
THIS WAY YOU WILL UNDERSTAND YOUR OWN CODE BETTER !!!

Almost, FULL-CODE…

import wixData from 'wix-data';

//xxxxxxxxxxxxxxxxxx [USER-INTERFACE] xxxxxxxxxxxxxx
const DATASET = "myDatasetID"; // the name of your dataset, which you still did not mention in this context !!!
const DATABASE = "Properties"; // the name of your database, which is in your case --> PROPERTIES !!!
const REPEATER = "myRepeaterID"; // the name of your repeater, which you still did not mention in this context !!!
const FIELD = "mapLocation"; // the name of your field, in your case --> mapLocation !!!
//xxxxxxxxxxxxxxxxxx [USER-INTERFACE] xxxxxxxxxxxxxx


$w.onReady(()=> {console.log('PAGE-READY...');        
    $w(`#${DATASET}`).onReady(async()=>{console.log('DATASET READY...');
        const myDataQuery = await wixData.query(DATABASE).find(); console.log('myDataQuery: ', myDataQuery); 
        // REPEATER-PART...
        $w(`#${REPEATER}`).onItemReady(($item, itemData, idex) => {console.log('Item-Data: ', itemData);
            if(itemData) {console.log('Item-Data found!');
                if (itemData[FIELD]) { console.log('Location-Property found!');
                    const mapLocation = itemData[FIELD];
                    const city = mapLocation.city;
                    const state = mapLocation.state;
                    const country = mapLocation.country;
                    $item('#txtElemntCity').text = `${city}`;
                    $item('#txtElemetState').text = `${state}`;
                    $item('#txtElementCountry').text = `${country}`;
                    $item('#txtElementAlltogether').text = `${city}, ${state}, ${country}`;
                } else {console.log('Location-Property NOT found!');}  
            } else {console.log('Item-Data is not defined or null...');}
        });
    });
});

Complete the code…

And next time also provide some data-example from your setup, like…

{
  "_id": "12345",
  "title": "Cool Engineering Project",
  "description": "An AI-powered project.",
  "location": true, // Possibly just a flag to show there's a location
  "mapLocation": {
    "city": "San Francisco",
    "state": "CA",
    "country": "USA",
    "latitude": 37.7749,
    "longitude": -122.4194
  },
  "image": "wix:image://v1/abcd.jpg/project.jpg#originWidth=1024&originHeight=768"
}

This can speed up everything!

Further steps, where you should do some → BRAINSTORMING on!

  1. Why the code is still not complete? → What part is missing?
  2. Would it make sense to use a separate RETURN-FUNCTION for DATA-QUERY? → (UPGRADE) → What would be the benefit?
  3. What is the benefit of the → USER-INTERFACE ← (already mentioned above) :laughing:
  4. Should i maybe pay more attention in my future, when mixing Wix-Data with a DATASET connected setup?
  5. Do i have 2 different DATABASES involved in my setup?
  6. Did i really mention my whole setup in detail?

EDIT: The following can be also written like …

$item('#txtElemntCity').text = city;
$item('#txtElemetState').text = state;
$item('#txtElementCountry').text = country;
$item('#txtElementAlltogether').text = `${city} / ${state} / ${country}`;
1 Like

The error in my code is I accidentally left a small comma at the end of the line there, remove it and that should be it

The code says thus:

  • repeater.onItemReady - when a repeater item is rendered, refer to the context as $item and to the data linked to it as itemData
  • if the location exists
    • Deconstruct the location into the three parameters according to property names
    • Set the collapsibleText element (which should probably be tagged #location?)

So, since the repeater already has the data it needs to populate itself, we never need to actually use wixData to make another fetch request from the database

1 Like

As long as DATABSE is the same.

Wow…. No, there’s quite a lot to read and I don’t have the time at the moment, but generally, if you already have the data from a dataset, you do not need wixData to query anything, that was my point

There’s also no reason to wait for the dataset to be ready because:

  1. the itemready always happens after the dataset is ready, as it needs the data
  2. Setting a trigger within a trigger will result in onItemReady firing multiple times if you reload the dataset with different filters

Thank you very much for your help!!!

Vielen Dank for putting all that together! This help was so exceptional you’ll ascend to Elysium. This community should honor you in someway.
How can I thank you? I checked out your profile, I’d like to learn more about what you do, follow & support.
PS if you ever need my kidney, dann melden Sie sich

No problem. Und danke für das Angebot, aber das ist alles GRATIS (so lange es freiwillig in meiner Freizeit passiert :slight_smile: ).

However, first try to get → DeanAyalon’s solution to work, since his setup is more simple, relying more on a more code-free-solution using the dataset as most as possible.

My solution is a more CODE-related one (i like to have always full control over my page by code).

There are still some questions open, at least out of my view.

  1. Not clear how many DATABASES are involved in your setup.
  2. It would surely help to see your dynamic page-setup.

Just some facts: → Working on a dynamic page means…

  1. You can show always ONLY 1 ITEM at once.
  2. Controlling your repeater by code → gives you ALWAYS more freedom! (everything what you control by code → will give you more freedom and space for own creations and solutions).
  3. Working on a DYNAMIC-PAGE → you can also use → Get Current Item | Velo

Back to Dean’s response…

…if you already have the data from a dataset, you do not need wixData to query anything, that was my point…

This is of course correct.

And the following also correct…

There’s also no reason to wait for the dataset to be ready because:

  1. the itemready always happens after the dataset is ready, as it needs the data
  2. Setting a trigger within a trigger will result in onItemReady firing multiple times if you reload the dataset with different filters.

But only in case you are not working and interferring with Wix-Data and you are working mostly with the dataset already connected and (onReady/Load) is activated in the options.

Maybe i also gone to deep into the setup.

I would recommend to read all the stuff about DATASETS/Wix-Data/ and REPEATERS absolutely in detail! → There you will find even more ways of how to solve your issue.

  1. Wix-Data → Velo Wix Data Introduction | Velo
  2. REPEATER → Display Database Collection Content in a Repeater
  3. DATASET → Dataset Introduction | Velo

You can find dozens of more informations (inside this forum and inside the VELO-API).

VIELE WEGE FÜHREN NACH ROM (bzw. zum RUHM) :wink:

EDIT: Also read this one → Velo: Overview of the Wix Data and Wix Dataset APIs | Help Center | Wix.com

1 Like

I’ll consider them. Thanks again sensei. Your genuine willingness, the sincere helpfulness, you’re rare. I’m curious about what you do. I work full time in charity, and it’s nice to come across a genuine one.

1 Like