Data Hook on Insert

I have a list of n items that need to be inserted into my database. When an item is inserted I have to give it the next boxNumber available by adding 1 to the previously saved result. The problem is that Wix does not seem to be completing the write before resolving the promise or await as I often get the same boxnumber result for the next insert. My code is below

To insert item, I loop through them and run

result = await wixData.insert('Items', item);
return result;

My insert hook is as follows:


export function Items_beforeInsert(item, context) {
 let nextNum;    
 return wixData.query("Items")
        .limit(1)
        .descending('boxNumber')
        .find()     
        .then((results) => {            
 if (results.length === 0) {
 let initialBoxNumber = 5000;
                item.boxNumber = initialBoxNumber; //Start if collectionn empty
                item.title = initialBoxNumber.toString();
            } 
 else {
 const lastItemInCollection = results.items[0];
                nextNum = lastItemInCollection.boxNumber + 1;
                item.boxNumber = nextNum;
                item.title = nextNum.toString();
            }
            console.log(item.boxNumber);
 return item;
        })
        .catch(errorHandler);
}

#hooks #async #wixData

The problem is probably in the looping or the async function that you haven’t posted here.

Anyway you can use a bulkInsert instead of many single inserts.
to do that you can add to your itemsToSave array a key tempIndx which its value is equal to it’s array index +1;
then run a bulk insert and on the backend:

export function Items_beforeInsert(item, context) {
 return wixData.query("Items")
            .descending("boxNumber")
            .limit(1)
            .find()
            .then((results) => {
if(typeof item.tempIndx === "undefined"){
    item.boxNumber = results.items[0].boxNumber + 1;
     }else {
 item.boxNumber = results.items[0].boxNumber + item.tempIndx;
 delete item.tempIndx;
                }
 return item;
            })
}

P.S.
bulkInsert : https://www.wix.com/corvid/reference/wix-data.html#bulkInsert

ahh… like that idea… will give it a go now and report back.

For some reason I get the same boxnumber in each row. Here is the updated code.

JSW File

export async function createOrUpdateOrder(orderState) {
let bulkItemstoInsert = [];
 for (let i = 0; i < items.length; i++) {
            items[i].product = items[i].productID;
            items[i].member = order_result.member;
            bulkItemstoInsert.push(items[i]);
    }
 await wixData.bulkInsert("Items", bulkItemstoInsert);
 return order_result;
}

Data.JS
Added code to assign initial boxNumber of 5000 since DB will be empty to start.

export function Items_beforeInsert(item, context) {
 return wixData.query("Items")
        .descending("boxNumber")
        .limit(1)
        .find()
        .then((results) => {
 if (typeof item.tempIndx === "undefined") {
                item.boxNumber = 5000;
                item.title = item.boxNumber.toString();
            } else {
                item.boxNumber = results.items[0].boxNumber + item.tempIndx;
                item.title = item.boxNumber.toString();
 delete item.tempIndx;
             }
 return item;
        })

Your front-end needs to be amended:
in the loop add (before the push function):

items[i].tempIndx = i +1;

Also, you have a small mistake on the back-end.
the

if (typeof item.tempIndx === "undefined")

is for cases you want to add an item for other places without a bulkInsert.
for case your data is empty, you should use the

if (results.items.length === 0){item.boxNumber = 5000 + item.tempIndx; delete item.tempIndx;}

[updated]

works perfectly … Thanks!

You’re welcome.
If you’re going to use insert in other cases without a bulkInsert (and then you won’t have tempIndx), then make sure to use the condition as I put above (+write code to support cases for empty databases in both cases: bulk and non bulk inserts).

Makes sense. I’m still not certain why it wasn’t working in my for loop, but I can that this should be more performant anyhow.