Promise returns 'undefined' value

I am working for a client developing a form that a user fills out and submits it so that a dynamic page is created with their filled out information. Upon hitting the submit button I would like the page to redirect to the newly created dynamic page and send out an email to the user. So in Velo I have written the following on the front end of the page:

import wixLocation from 'wix-location';
import wixData from 'wix-data';
import { updateCollectionVault } from 'backend/email';

import { sendEmail } from 'backend/email';

let baseURL = wixLocation.baseUrl;

$w.onReady(async function () {
    $w('#dataset1').onReady(async function() {
        $w('#dataset1').onAfterSave(async function(beforeItem, afterItem) {
          
            $w('#stripTimer').hide();
            console.log("the item just saved is: ", afterItem);
            let vaultNumber = await updateCollectionVault(afterItem._id, afterItem.databaseName);
            console.log('the vaultNumber is: ', vaultNumber);
          let newURL = afterItem['link-storytime-all'] + vaultNumber;	        wixLocation.to(newURL);
        })
    })
});

So vaultNumber should be receiving a uniquely created number that is assigned to the dynamic page’s url. But I keep getting ‘undefined’ on the console.log statement.
Here is the backend code:

export async function updateCollectionVault(id, collection) {
      let newVault = 0;
    console.log("inside the backend update with id and collection: ", id, collection);
    let query = await wixData.query("test")
        .descending("vaultNumber")
        .limit(1)
        .find()
        .then(r => {
            let vault = r.items[0];
            console.log("the item we found in test is: ", vault);
            let vaultn = vault.vaultNumber + 1;
            newVault = vaultn;
            console.log("the new vault number is: ", vaultn);
            let toInsert = {
                "vaultNumber": newVault,
                "pageId": id,
                "collectionName": collection //For each dynamic page and form,
                //this has to be changed
            };

            //this creates the new vaultnumber in test database
            wixData.insert("test", toInsert).then((results) => {
                    let item = results; //see item below
                    //add the new vault number to the page itself
                    console.log("inserted a new item to test: ", item);
                    wixData.query(item.collectionName)
                        .eq('_id', item.pageId)
                        .find()
                        .then((result) => {
                            console.log("found the new entry in the collection: ", result);
                            result.items[0].title = item.vaultNumber.toString();
                            wixData.update(item.collectionName, result.items[0])
                                .then((other) => {
                                    console.log("added the vault number to the page's properties: ", other.title);
                                    return other.title;
                                })
                                .catch(error => {
                                    console.log("Save error 1", error);
                                });
                        })

                })
                .catch((err) => {
                    let errorMsg = err;
                });

        });

}

This console.log("added the vault number to the page’s properties: ", other.title); prints out the new number “233” for example. But when it gets to the return other.title, on the front end I am receiving an undefined.

Could anybody help me figure out why?

Developer Tools Console


Wix logs

The problem is that in between the insert and the query, the Wix CDN has not yet distributed the new values yet across the network, there is some lag. The solution is a simple one. In between the insert and query, wait for 250 ms. That should be enough.

But like I said the console.log statement displays other.title’s value correctly, it is not undefined. You can see that in the logs where it says “add the vault number to the page’s properties:”, “321”. This 321 is the newly inserted number. So when it gets to the “return other.title” why does the front end receive undefined?

Exactly what I said: you get the return value from a different node on the network than the result of the query, so you have to give it a bit of time to update Just try, you’ll see.

I can’t wrap my head around that but ok. I will add a delay in the code.

This is what I added and still no success:

await wixData.insert("test", toInsert).then(async function (results) {
                    let item = results; //see item below
                    //add the new vault number to the page itself
                    console.log("inserted a new item to test: ", item);

                    //wait half a second
                    var start = new Date().getTime();
                    var end = start;
                    while (end < start + 500) {
                        end = new Date().getTime();
                    }

                    
                    await wixData.query(item.collectionName)
                        .eq('_id', item.pageId)
                        .find()
                        .then(async function (result) {
                            console.log("found the new entry in the collection: ", result);
                            result.items[0].title = item.vaultNumber.toString();
                            await wixData.update(item.collectionName, result.items[0])
                                .then(async function (other) {
                                    console.log("added the vault number to the page's properties: ", other.title);
                                    return other.title;
                                })
                                .catch(error => {
                                    console.log("Save error 1", error);
                                });
                        })

                })
                .catch((err) => {
                    let errorMsg = err;
                });

I am still getting undefined after waiting for half a second

@gercamjr-dev Try this one:

function fnDoze(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

And call it with fnDoze(250).

@giri-zano Used your code but I am still getting undefined.

@giri-zano I even tried waiting for 1 sec, and 2 seconds but to no avail. Same undefined result

@gercamjr-dev I think I see the error. You return " return other . title ;" too late (or: too early if you look at it from execution sequence). Because you wait for the promise to resolve in the above then, the program jumps to the next line, which is the return, but is value-less yet.
You must either move up the return to “return await …” or (not trying to be cruel), clean up your program, because the whole mix of sync and async functions (async await/.then) makes it extremely hard to read and predict.

Example. Change this:

export async function updateCollectionVault(id, collection) {
      let newVault = 0;
    console.log("inside the backend update with id and collection: ", id, collection);
    let query = await wixData.query("test")
        .descending("vaultNumber")
        .limit(1)
        .find()
        .then(r => {
            let vault = r.items[0];
            console.log("the item we found in test is: ", vault);
            let vaultn = vault.vaultNumber + 1;
            newVault = vaultn;
            console.log("the new vault number is: ", vaultn);
            let toInsert = {
                "vaultNumber": newVault,
                "pageId": id,
                "collectionName": collection //For each dynamic page and form,
                //this has to be changed
            };

into something like this (getting rid of .then and the r):

export async function updateCollectionVault(id, collection) {
      let newVault = 0;
    console.log("inside the backend update with id and collection: ", id, collection);
    let query = await wixData.query("test")
        .descending("vaultNumber")
        .limit(1)
        .find()
            let vault = query .items[0];
            console.log("the item we found in test is: ", vault);
            let vaultn = vault.vaultNumber + 1;
            newVault = vaultn;
            console.log("the new vault number is: ", vaultn);
            let toInsert = {
                "vaultNumber": newVault,
                "pageId": id,
                "collectionName": collection //For each dynamic page and form,
                //this has to be changed
            };

and this piece:

await wixData.query(item.collectionName)
                        .eq('_id', item.pageId)
                        .find()
                        .then(async function (result) {
                            console.log("found the new entry in the collection: ", result);
                            result.items[0].title = item.vaultNumber.toString();
                            await wixData.update(item.collectionName, result.items[0])
                                .then(async function (other) {
                                    console.log("added the vault number to the page's properties: ", other.title);
                                    return other.title;
                                })
                                .catch(error => {
                                    console.log("Save error 1", error);
                                });
                        })

into

const result = await wixData.query(item.collectionName)
                        .eq('_id', item.pageId)
                        .find()
                            console.log("found the new entry in the collection: ", JSON.stringify(result));
                            result.items[0].title = item.vaultNumber.toString();
                            const other = await wixData.update(item.collectionName, result.items[0]);
                                    console.log("added the vault number to the page's properties: ", JSON.stringify(other.title));
                                    return other.title;
                                });

Now, you can return after the await.
I might have missed a bracket here and there, you will have to check.

P.S. My remark about the delay still stands, but looking at your code, I do not know if “test” and .collectionname were the same collection.
P.P.S Did not test the code, but you should get the idea.

@gercamjr-dev I replied above.

I replied above. For some reason, answers get moved around out of sequence.