Wix query works for less than 1000 rows.

i am trying to add a dependent drop down list where two drop down list needs to be shown to customer to choose from. 1st drop down list will be showing 8 state names and second drop down list showing city names. each states has numerous city name. Minimum city connected to any state are almost 142 and maximum is more than 5000. I copied a velo code from one free online coding team, it only works for row numbers less than 1000. I tried to edit this code to accomodate my large city names, but in vain. in my list, there are 15000 city names. Customer can select any state name such as ACT then second drop down will be enabled and showing 142 city names. if customer choose NSW then 2nd drop down will show 4500 city names to be choose from. I appreciate if someone assist to update this code for me. Unfortunately i am not highly experienced in velo coding.

// API Reference: Introduction - Velo API Reference - Wix.com
// “Hello, World!” Example: Velo Learning Center

import wixData from ‘wix-data’ ;

$w . onReady ( function () {

uniqueDropDown1 (); 

});

function uniqueDropDown1 ( ){

wixData . query ( "location" ) 

    . limit ( 1000 ) 

  . find () 

  . then ( results  => { 

       const  uniqueTitles  =  getUniqueTitles ( results . items ); 

       $w ( "#dropdown1" ). options  =  buildOptions ( uniqueTitles ); 

  }); 

function getUniqueTitles ( items ) {

    const  titlesOnly  =  items . map ( item  =>  item . state ); 

 **return**  [... **new**  Set ( titlesOnly )]; 

} 

function  buildOptions ( uniqueList ) { 

    **return**  uniqueList . map ( curr  => { 

        **return**  { label : curr ,  value : curr }; 

    }); 

} 

}

export function dropdown1_change ( event , $w ) {

uniqueDropDown2 ();

$w ( “#dropdown2” ). enable ();

}

function uniqueDropDown2 ( ){

wixData . query ( "location" ) 

    . contains ( "state" ,  $w ( "#dropdown1" ). value ) 

    . limit ( 1000 ) 

  . find () 

  . then ( results  => { 

       const  uniqueTitles  =  getUniqueTitles ( results . items ); 

       $w ( "#dropdown2" ). options  =  buildOptions ( uniqueTitles ); 

  }); 

function getUniqueTitles ( items ) {

    const  titlesOnly  =  items . map ( item  =>  item . city ); 

 **return**  [... **new**  Set ( titlesOnly )]; 

} 

function  buildOptions ( uniqueList ) { 

    **return**  uniqueList . map ( curr  => { 

        **return**  { label : curr ,  value : curr }; 

    }); 

} 

}

/**

  • Adds an event handler that runs when the element is clicked.
    Read more
  • @param {$w.MouseEvent} event
    */

/**

  • Adds an event handler that runs when an input element’s value
    is changed.
    Read more
  • @param {$w.Event} event
    */

try removing .limit(1000) in your function uniqueDropDown1 ( )

Yes. The maximum items per queries is 1000.
There’s a solution.
[But first let me say that in my opinion, the user experience you planned is not the best. No one wants to select a city from a 5k-list. It’s too long and too annoying.
When I have long selection lists, I create a search input element where the user has to type at least the first 3 letters before I display a shorter select-list that fits the typed characters].

Now to the solution, if you wish to go by your plan:
Loop over to get the full data:

async function retrieveAllItems() {
  let results = await wixData.query("myCollection")
      .limit(1000)
      .find();
  let allItems = results.items;
  while (results.hasNext()) {
      results = await results.next();
      allItems = allItems.concat(results.items);
  }
  return allItems;
}

Hello J.D thank you for your opinion. will it be like this after i change the code—

$w . onReady ( function ()
{ uniqueDropDown1 ();
});

async function uniqueDropDown1 () {
let results = await wixData . query ( “location” )
. limit ( 1000 )
. find ();
let allItems = results . items ;
while ( results . hasNext ()) {
results = await results . next ();
allItems = allItems . concat ( results . items );
}
return allItems ;
}

is that i need to do ? please suggest

Assuming you wish to do something with the retrieved items, you’ll need to do it at the end of the uniqueDropDown1 function (instead of the return ).
For example:

import wixData from 'wix-data';
$w.onReady(uniqueDropDown1);

async function uniqueDropDown1() {
  let results = await wixData.query("location")
      .limit(1000)
      .find();
  let allItems = results.items;
  while (results.hasNext()) {
      results = await results.next();
      allItems = allItems.concat(results.items);
  }
let labels =  allItems.map(e => e.title);
labels = options.filter((e,i) => options.indexOf(e) === i);//to omit duplicate titles
$w('#dropdown1').options = labels.map(e => ({label: e, value: e}));
}
1 Like
  • in order to save time you can do the following:
  1. If the data are not too big, you can run the while loop on the backend and retrieve the final results (it will save you the back and forth).

  2. You may start the query before the $w is ready. In this case you’ll have to use Promise.all to ensure the data binding takes place only after the data has retrieved AND the $w is ready).

1 Like