.then failing??

Hello, hoping someone can help with this one.

I am trying to retrieve values from multiple datasets, multiply them together and total up the final result.

My code seems to fail at the multiply function, can anyone streamline this a bit?

export async function userStatsSpecificationValue(userId) {

 var firstDayOfCurrentYear = new Date(new Date().getFullYear(), 0, 1);

 let arrA = [];
 let arrB = [];
 let arrC = [];

    wixData.query("projectproducts")
        .eq("_owner", userId)
        .eq("specified", true)
        .ge("_createdDate", firstDayOfCurrentYear)
        .find()
        .then((results) => {

            arrA = results.items;

            for (var i = 0; i < results.items.length; i++) {

                arrB.push({
                     "_id": arrA[i].product,
                     "productQuantity": arrA[i].productQuantity
                         });

                let quant = arrA[i].productQuantity;

                wixData.query('products')
                    .eq("_id", arrB._id)
                    .find()
                    .then((res) => {

                         let items = res.items;
                         let firstItem = res.items[0]; //see item below
                         let productId = firstItem._id;
                         let productPrice = firstItem.productPrice;

                        multiply(quant, productPrice).then(product => {
                                console.log(product);
                                arrC.push({
                                     "value": product
                                });

                         // get all of the items
                         let sumTotal = 0; // declare sum
                         let values = arrC.items;

                                values.forEach(item => {
                                 // the amount is a string so convert
                                    sumTotal = sumTotal + Number(item.amount);
                                });
                            })
                            .catch(error => {
                                console.log(error);
                            });
                    })
                    .catch(error => {
                        console.log(error);
                    });
            }
        });
}

export function multiply(quant, productPrice) {
 return quant * productPrice;
}

The dataset fields are:

dataset = projectproducts

field ID = product  // matching ID in products dataset
field ID = productQuantity  // returns number

dataset = products

field ID = _id  // matching product field value in projectproducts dataset
field ID = productPrice  // returns number

I am trying to query the projectproducts dataset and retrieve the items from the product field (several hundred of them) and the quantity from the productQuantity field.

Then based on the product field (which is the ID of the item/row in the products dataset ) query the products dataset and retrieve the items from productPrice field.

Then I’d like to multiply the productPrice x productQuantity and add all the values together eventually for a final amount, then return the result to a text field.

I am getting the following error in the preview log:

multiply(...).then is not a function

populateDashboard.jsw
Line 280

Hi. It’s really hard to read it like that. Please get rid of the console.log()'s and fix the indentations.

Hi JD, thank you for looking into this, I’ve edited the original post

@spamushere Why wouldn’t you make the product field of the projectproducts a reference type field that refers to the products collection? This way you’ll get all the data with the first query (using .include() ) It’ll make everything much simpler.

@jonatandor35 I’ll need to export the DB to other formats for reference at a later stage and I need the IDs

@jonatandor35 Any idea?

Some observations:

  • The userStatsSpecificationValue() function does not need the async keyword as you are not using await anywhere in this function’s code.

  • The multiply() function does not return a Promise, so not only is there no need for a .then() function, but it is correctly flagged as an error since there is no .then() for this function.

  • Why even call the multiply() function? Why not just multiply those two fields inline in the code?
    product = quant * productPrice;

Hi Yisrael,

Thanks for responding. I initially had the multiplication in the code but was getting errors from the array values, when I moved it out to the multiply() function the errors stopped.

If you can think of a more streamlined way to assemble this function, I’d really appreciate it?

@spamushere I see. But I think that instead of running many data queries in loop, it’ll be better to get all of the query2 in a single query such as:

wixData.query('products')
.hasSome('_id',  arrA.map(e => e.product))
.find()

@jonatandor35 Thanks, when I tried this I got an error, hasSome failed, only works with String etc…

It was the first way I assembled this function. I have hasSome and hasAll running on other queries without issue, but for this one it’s bugging out

@spamushere but e . product is a string.

@jonatandor35 Exactly

  • you can instead, use afterQuery hook to get all you need from the other database (it’ll save you the explicit loop + it’ll all take place on the backend and therefore will be faster and clearer).

@jonatandor35 Thanks, I will give it a try. All this code is running in the backend - but I’ll integrate it.

for my & others reference: https://www.wix.com/velo/reference/wix-data/hooks/afterquery

@spamushere If it’s a becakend code then you’re missing the return .

  • You’re better chain the promises instead of nesting them.

Bad practice:

query1().then(r => {
    query2(r).then(r2 => 
        query3(r2).then(r3 => {
            return something;
        })
    })
})

Good practice:

return query1().then(r => {
    return query2(r);
})
.then(r => {
    return query3(r);
})
.then(r => {
    return something;
})