Populate array from async function

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;
            })
        }
    })
});

Same result, nothing happens
cardsCntByName.toString() - TypeError: Cannot read properties of undefined (reading ‘toString’)

maybe this … without testing I’m just assuming some things

import wixData from 'wix-data';

let cardsCntByName = []; // Initialize the array
let names = []; // Initialize the names array

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 }; })
        let cnt = listOfNames.length;

        for (let 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.

$w.onReady( async () => {
    let results = await wixData.aggregate("NewSales").count('name').group("name").count().run()
});

This would give you an ouput of something like

/* Given the sample data above, items is:
 * [
 *   {
 *     "_id": {"name": "AI"},
 *     "count": 3,
 *     "name": "AI",
 *   },
 *   {
 *     ...etc
 *   }
 * ]
 */
1 Like

Excellent… Thanks works great

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

1 Like