I have a collection of non-unique names and need to display the name with the highest number of appearances and the number of appearances. So let’s say if my collection
Al, Al, Bob, Steve, Bob, Al, then I want to display: Al - 3.
I’m not sure how to properly build an array of numbers of appearances, everything else is working fine.
The line cardsCntByName[i] = results; is bad. I’m not sure how to deal wuth the results type ‘void’
Here is my code -
import wixData from ‘wix-data’;
let cnt;
let cardsCntByName = [];
let names = [];
let arrToSort = [];
$w.onReady(() => {
wixData.query("NewSales") .limit(1000) .distinct("name").then(results => {
let listOfNames = results.items.map(element => { return { value: element }; })
cnt = listOfNames.length;
for (var i = 0; i < cnt; i++){
names[i] = listOfNames[i].value;
getFilter(names[i], i).then(function(results)
{
cardsCntByName[i] = results;
})
}
})
});
async function getFilter(nm, k) {
await $w("#dataset1").setFilter(wixData.filter().eq('name', nm)).then(() => {
let num = $w('#dataset1').getTotalCount();
return num;
})
}
export function btnShow_click(event) {
for (let i = 0; i < cnt; i++){
arrToSort.push({"name": names[i], "count": cardsCntByName[i]})
}
arrToSort.sort((a, b) => b.count - a.count)
$w('#textCnt1').text = arrToSort[0].count.toString();
$w('#textName1').text = arrToSort[0].name;
}
Try this code. The getFilter function is an asynchronous function, which means it returns a Promise. However, in your code, you’re not properly handling the Promise returned by getFilter. The getFilter function is supposed to return the count of names, but it’s not returning anything. This is why you’re getting a void type error. You need to return the count from the getFilter function and then use it in the then function.
import wixData from ‘wix-data’;
async function getFilter(nm, k) {
await $w("#dataset1").setFilter(wixData.filter().eq('name', nm));
let num = await $w('#dataset1').getTotalCount();
return num;
}
$w.onReady(() => {
wixData.query("NewSales").limit(1000).distinct("name").then(results => {
let listOfNames = results.items.map(element => { return { value: element }; })
cnt = listOfNames.length;
for (var i = 0; i < cnt; i++){
names[i] = listOfNames[i].value;
getFilter(names[i], i).then(function(results) {
cardsCntByName[i] = results;
})
}
})
});
The concepts are on the right track, but Wix actually provides a function for this specific case. Instead of using query, you should be using the WixData.aggregate function. - aggregate - Velo API Reference - Wix.com
So in your case you could do the following. I’ve switched a piece from your example to Async/Await so it’s easier to read.
let results = await wixData.aggregate(“NewSales”).group(“name”).descending(“count”).count().limit(1000).run().then((results)
and then
items = results.items;
items[0].name & items[0].count