Dynamically defining Repeater contents

I’ve been coding with Velo for a few weeks now, and so far everything’s been working fantastically; http-functions, queries, dynamically defining dropdown lists, table contents, hiding/showing elements, etc.
Now I’m trying to use a Repeater on my website, and I must be doing something very basically wrong because nothing seems to be working the way I need.
Here’s the core of what seems to be the crux of the problem:
On the one hand, my repeater is showing multiple containers as expected, because the “title” text-box is linked to a column of a collection, and all unique values of this column are being represented on the page. So far so good.
However! Defining the link of a button element in the container (via forEachItem) is not having any effect. Worse! Using console.log to see where things are going wrong is showing that internally (or behind the scenes) the page is still only “seeing” the dummy containers present when adding the repeater to the page! So the console log is showing only 4 items, with title values of Entertainment, Lifestyle, Sports, Technology, which has nothing to do with the dataset-column supposedly linked to the repeater, and nothing to do with what I can visually see on the page…

What might I be doing wrong?? Maybe I shouldn’t be working in the onReady function of the page? Maybe some other basic thing I’m missing?

Any help would be very much appreciated!

You’ll need to provide just a bit more information in order to get assistance. Share the relevant code, properly formatted in a code block.

Ok. I’ll keep it really simple and add complications if they persist through the resolution of these simple problems.
I’ve simplified the repeater, and it now has a single container, with a text element with id ‘#text38’. The editor value of this text box for this single container is ‘Entertainment’:

Viewing this page shows the appropriate multiple containers:

But the following simple code snippet shows only the single “Entertainment” container being recognized and printed to console/site-events -

$w.onReady(function () {
 // wixLocation.to('/דברים-שבכתב')
    $w('#repeater1').forEachItem(($item, itemdata, index) => {
        console.log($item('#text38').text);
        })
 
});

Does that help narrow down my meaning and the problem?

What seems to be happening is that the code in the onReady() function runs before the Repeater is populated. Keep in mind that although the page is ready, the dataset that populates the Repeater may not yet be ready and the Repeater is only populated after forEachItem() runs. You can use the dataset.onReady() event handler in the page’s onReady() function to ensure that the dataset is ready before running certain code.

What are you trying to do? What do you need the forEachItem() code for?

Yes, that was my suspicion. What I’m trying to do is the following:
I’ve got another page with handles url-queries, basically as a search and filter mechanism with the results displayed in a table.
These containers are going to link to that page, with the appropriate url - query and all - and I need to create the button links accordingly and dynamically.
Something to this effect -

        $item('#iconButton1').link = 'https://www.haravyosefkalner.com/testing-haklatot/?sidra=' + $item('#text38').text;

How do I make sure this runs only after the repeater is populated? Or am I going about this all wrong?

You want to use the onItemReady() function (and not the forEachItem function). The onItemReady() function is triggered when the Repeater is populated, and you can then set specific elements as you want.

$w('#repeater1').data = // ---> some DATA

$w('#repeater1').onItemReady( ($item, itemData, index) => {
    console.log(index)
    console.log(itemData)
    
    $item('#iconButton1').link = 'https://www.haravyosefkalner.com/testing-haklatot/?sidra=' + $item('#text38').text
})

@yisrael-wix That seems to partially help? I mean, the links are being created now (which they weren’t before) but the text38 item is still not updating and is still only “Entertainment”.

@russian-dima I’m not sure I follow. I tried the onItemReady part, and as I mentioned it didn’t really work. Does your first line pertaining the repeater-data have a role in your suggested solution? If so I don’t quite follow.

@forautozoom3125 You don’t need that first line if you are populating your Repeater with a dataset.

You’ll need to share your code again so we know what you’re trying to do.


$w.onReady(function () {
    $w('#repeater1').onItemReady(($item, itemdata, index) => {
        $item('#iconButton1').link = 'https://www.haravyosefkalner.com/testing-haklatot/?sidra=' + $item('#text38').text; // All buttons are now with the same link, with the appended "Entertainment"...
        console.log($item('#text38').text); // Only shows Entertainment in log
        })  
});

Not very different and seemingly what you suggested.
Am I missing something obvious?

As Yisrael mentioned.
How do you populate your repeater with data?

  1. DATASET ?
  2. or manually with CODE ?

EDIT:
I myself prefer to do everything manually with CODE and do not use any DATASET.

Using a DATASET == => less flexibility
Using CODE = = => more flexibility

@russian-dima 1) Dataset. Specifically, the ‘#text38’ is connected to a column of choice.

@forautozoom3125

If you want you can try the manual way…like…

  1. You do a query and get some results —> results.items
import wixData from 'wix-data';


wixData.query("myCollection")
  .find()
  .then( (results) => {
    if(results.items.length > 0) {
      let firstItem = results.items[0]; //see item below
      let itemDATA = results.items
    } else {
      // handle case where no matching items found
    }
  } )
  .catch( (err) => {
    let errorMsg = err;
  } );
  1. Then you put the DATA into repeater… like …
$w('#repeater1').data = itemDATA
$w.onReady(function () {
    $w('#repeater1').onItemReady(($item, itemdata, index) => {
        $item('#iconButton1').link = 'https://www.haravyosefkalner.com/testing-haklatot/?sidra=' + $item('#text38').text; // All buttons are now with the same link, with the appended "Entertainment"...
        console.log($item('#text38').text); // Only shows Entertainment in log
        })  
});

No DATASET needed.

@russian-dima I’ll try that. It’s frustrating that the connector to the dataset is not working as expected.
The query results are not compatible with the repeater.data though.
The data expects an _id for instance, which I have no use or care for, and all I really need to control are the text-box and the button-link, which aren’t directly part of the repeater.data as far as I can tell.

@forautozoom3125
The CONSOLE is your best-friend.

Inspect the structure of QUERY-RESULTS to rebuild an own ITEM-DATA, which would be accepted by the REPEATER.

Build your own object, which will fill the REPEATER with accepted DATA.

{ “title” : “title” , “value” : “title”, and so on … }

@russian-dima I use the console a lot. All the time. But I’d like some help with this if possible…
The repeater I’m using has by default only the _id field.
The containers have the text boxes I’d like to adjust according to query results.
The container has the repeater as “parent”, but the repeater doesn’t seem to point to the containers, or hold any reference to the text38 box I need to work with…
I couldn’t find anything in the documentation either, and as mentioned, all the console prints I could conjure have been to no avail.
Thanks for all the help till this point! I feel like I’m on the verge of getting this to work…

Got it! Thanks for all the help!
I generated a hash code from the results of my query and used those for the _id, and I added a custom field for reference during the onItemReady function…
Thanks again!

:wink: