Pulling a random text item from dataset

Question:
I need to pull in text items from CMS database:

  1. a random item is displayed when the page loads
  2. a random item is displayed each time the “One more” button is clicked.

Currently, it pulls the items starting with #1 in the database and then showing them in exactly the same order on the button click.

Here’s the code:

import wixData from 'wix-data';

$w.onReady(function () {
    fetchRandomItem(); // Fetch a random item when the page loads

    $w('#Section1RegularButton1').onClick(() => {
        fetchRandomItem(); // Fetch a random item when the button is clicked
    });
});

function fetchRandomItem() {
    wixData.query('QuestionRoulette')
        .find()
        .then((results) => {
            if (results.items.length > 0) {
                const randomIndex = Math.floor(Math.random() * results.items.length);
                const randomItem = results.items[randomIndex];
                $w('#title').text = randomItem.title; // Update the title element

                // Update repeater or other elements if needed
                // Example: $w("#repeater4").data = [randomItem];
            }
        })
        .catch((error) => {
            console.error(error);
        });
}

Product:
Wix Editor

What are you trying to achieve:
Create an exercise for people to pull a random question and reflect on it. Link to page: https://www.theedgeyouneed.com/questionsroulette

This looks correct. Can you confirm it wasn’t just retrieving items randomly but in the correct order? Perhaps from a small data set?

1, 2, 3 is as valid of a random sequence as 3, 1, 2, or 1, 1, 1.

Also side note that this function is rather expensive as it runs a query to get the same data each time and then runs what’s inside the .then(). This is optional but one way to optimize this is to do the query once on page load, store the resulting array in a variable, and then randomly pull from that array instead.

Hi Anthony, thanks for the answer.

  1. The dataset is 107 text items, so yes - it retrieves them in the correct order 1,2,3,4,5…
  2. I have zero coding knowledge, so i just used the internet + ChatGPT to come up with this code. I got something right, because, as you can see, the page works. It’s just that the randomization is off. I’d happily follow your lead if you help out with the code or a prompt.

Thanks!
Sergey

Perhaps the button is doing something like getting the Next item of the dataset? Like in the visual editor options, not in your code.

Spot on! The button was linked to “Next Item”, which I changed to “Next page” now.

It works now, but… it always pulls the same items in the same order. I.e., it’s not randomized. And then it stops after 6 iterations (the “Spin” button turns grey and deactivates. When I refresh the site, it will again give me the same items in the same order.

What I mean is that the click action should not connect to any action here as you’re handling it in code. You should set the click action on this button to “Not connected”.

Nope. If I set the click action to “Not connected”, nothing happens when I click the button.

Can you also set the Dataset to “Not connected” / otherwise remove the data connection to this button?

Tried both - no luck. The button becomes inactive whatsoever.

ANTHONY gave you a very very important tip/hint!!!

DO NOT QUERY YOUR DATASE TO OFTEN !!!
QUERY YOUR DATABASE ONLY → ONCE <—, this will safe you money.

You would have to change your code to something like the following example:
import wixData from ‘wix-data’;

$w.onReady(async()=> {console.log('Page ready...');
    let myData = await get_Data(); 
    
    //NOW! --> AFTER YOU GOT YOUR WHOLE DATA INSIDE A --> VARIABLE --> 
    //you can randomize it and get your random item and title and what ever you want.
    let randomizedData = await start_Randomization(myData); console.log('Randomized-Data: ', randomizedData);
    
    $w('#title').text = randomizedData.randomItem.title; // Update the title element
    
    
    // --> now you want to feed your repeater with data ????
    $w('#repeater4'.data = randomizedData);    
    $w('#repeater4').onItemReady(($i, iData, i)=>{console.log('Repeater ready...');
    	consoole.log('ITEM-DATA: ', iData);
      console.log('INDEX: ', i);
      //---------------------
 			//---> continiue here.....
    });
    
    
  	// Update repeater or other elements if needed
  	// Example: $w("#repeater4").data = [randomItem];
    
    //--------------------------------------------------------------
    $w('#Section1RegularButton1').onClick((e)=> {console.log(e.target.event+'-clicked'); start_Randomization(myData);});
});

function get_Data() {
  return wixData.query('QuestionRoulette')
  .limit(1000)
  .find().then((results)=> {
    if (results.items.length>0) {
			console.log('Some data has been found!');
      return results;
    }
    else {console.log('No data has been found, check your databse!');}
  }).catch((error)=> {console.error(error);});
}


function  start_Randomization(data) {let msg = {};	
  const randomIndex = Math.floor(Math.random() * data.items.length);
  const randomItem = data.items[randomIndex];
  msg.randomIndex = randomIndex;
  msg.randomItem = randomItem;
  msg.author = 'russian-dima';
  //-------------------------
  return msg;
}

I just created it on the fly and did not test, it, but it should show you the right way of how to do…

Also i did not see → .limit(1000) ← in your code, so you load every-time just 50-items?
How much items are inside of your databse? More or less than 50? Will your database grow soon ?

1 Like

Terrific! Thanks, @CODE-NINJA - now it runs like clockwork!

1 Like