Randomizing a repeater in 2020

On the home page of my site, I have a “Featured Artworks” repeater.

In this repeater, I would like to display 4 artworks from my dataset ‘Artwork’

This dataset will grow more and more as the business grows, potentially tens of thousands.

I would like to include a code that randomizes the artworks in the repeater so that every time someone visits the page it will show 4 new artworks.

I have been looking already however I’ve read that some codes are now out of date and others don’t do what I am looking to do.

Help would be much appreciated.

First of all check how many entries you have.
Then, use Math.random() * total to pick up a randomIndex.
Then run a query with skip(randomIndex).limit(4)
if the randomIndex is one of the last 3, get also the items from the beginning.

Thank you JD, the amount of entries will change daily, is there a way around that?

Also I am new to coding on corvid, I have managed a couple before buut i am complete laymans terms please.

It doesn’t matter that it changes. I didn’t mean that you’ll manually add the number to your code.
You should get the total number by running a query.
First you should decide whether to use a dataset or a direct query.
Have a look at there links:
Dataset:
https://www.wix.com/corvid/reference/wix-dataset/dataset/gettotalcount
https://www.wix.com/corvid/reference/wix-dataset/dataset/gettotalpagecount
https://www.wix.com/corvid/reference/wix-dataset/dataset/loadpage

Direct query:
https://www.wix.com/corvid/reference/wix-data/wixdataaggregate/count
https://www.wix.com/corvid/reference/wix-data/query
https://www.wix.com/corvid/reference/wix-data/wixdataquery/skip

Random numbers:

Thanks JD, mi reading what you send but dont actually know how to put it all together to actually work. What would you recommend, sorry to ask.

This is code I currently have.

import wixData from ‘wix-data’ ;

$w.onReady( function () {

let max = 4 ;
let skip = Math.floor(Math.random() * max) + 1 ;

wixData.query( “Artwork” )
.ascending( “artist” )
.skip(skip)
.limit( 4 )
.find()
.then( (results) => {
let items = results.items;

let itemData = [
{
“_id” :items[ 0 ]._id,
“text1” :items[ 0 ].text
},
{
“_id” :items[ 1 ]._id,
“text1” :items[ 1 ].text
},
{
“_id” :items[ 2 ]._id,
“text1” :items[ 2 ].text
}
];

$w( “#repeater1” ).data = itemData;
} )
. catch ( (error) => {
let errorMsg = error.message;
let code = error.code;
} );

$w( “#repeater1” ).onItemReady( ($w, itemData, index) => {

const repeatedText = $w( “#text1” );
repeatedText.text = itemData.text1;

}); 

});

You wrote:
let max = 4 ;
However max should be the total number of entries.
Check the total number first and then pick up the random number.
If you want to save time, run the function on a backend jsw file.

@jonatandor35 What do you mean total amount of entries? As I mentioned early the data set will grow more and more everyday…

@reynoldselliott21 I mean you can do something like:

//FRONT END
import {getRandomItems} from 'backend/random-item.jsw';
let randomItems, is$wReady;
getRandomItems()
.then(r => {
randomItems = r;
if(is$wReady){
bindDataToRepeater();
}
});
$w.onReady(() => {
is$wReady = true;
if(randomItems){
bindDataToRepeater();
}
})
function bindDataToRepeater(){
$w("#repeater1").data = randomItems;
}

//backend/random-item.jsw
export async function getRandomItems(){
const numberOfRandomItems = 4;
 let randomItemsIndexes = [];
  const getTotal  = await wixData.aggregate("Artwork").count().run();
  const count = getTotal.items[0].count;
  let allIndexes = [];
  for (let i = 0; i < count; i++){
    allIndexes.push(i);
  }
  for (let i = 0; i < numberOfRandomItems; i++){
randomItemsIndexes.push(allIndexes.splice(Math.floor(Math.random() * allIndexes.length), 1));
  }
  randomItemsIndexes = randomItemsIndexes.flat();
  const toRetrieve = await Promise.all(randomItemsIndexes.map(e => wixData.query("Artwork").skip(e).limit(1).find()));
  const selectedItems  = toRetrieve.map(e => e.items).flat();
  return selectedItems;
}

HI JD,

Ive copied those exactly, frontend into the page tab and backend into the site tab however I am getting errors on lines 4 and 15 with WIXDATA underlined in Red.

Really sorry and I appreciate your help.

The backend code shouldn’t be on the site tab.
It should be in a jsw file on the backend.

  • You need to add to the backend code: import wixData from ‘wix-data’;

P.S.
Instead of using backend code, you can put everything on the page code panel (and remove the import from backend line) . However it might be slightly slower (you can try it).

Ohhh man it worked. Sorry I didnt know what the backend was, now I found it and added the jsw file and boom perfect!

Thank you so much for your patience and understanding. Brilliant!

@jonatandor35 HI JD, I have a similar problem, could you take a look for me. https://www.wix.com/corvid/forum/community-discussion/repeater-help?origin=member_posts_page

Hi, Just wanted to say thank you for this thread. After days of trying to achieve the same effect I have it working.
I do however get the following console error;
Wix code SDK Warning: The text parameter of “text40” that is passed to the text method cannot be set to null or undefined.

text40 is the field in the dynamic repeater on the dynamic page and is only referred to in the code on this line;
const repeatedText = $w ( “#text40” );
repeatedText . text = itemData . text ;

To be clear the effect of randomising the results in the dynamic repeater on the dynamic page is working, i just have this console error.

This helped me in 2023! Thank you so much for putting your insight online!!