Chris
Chris

Reputation: 3129

Async and Await function not working properly

I seem to be running into an issue with my async and await functions not working and I am relatively new to this...

When I call the CallToPopulateCustomerDropDown, I never get to the call for SetCustomerMultiColumnAfterAddingNewCustomerFromNewOrder ( I know this because I have break point here in it and it never gets hit). So I am figuring that I have written something wrong

Here is my code

async function CallToPopulateCustomerDropDown(ddlCustomer, selectedValue) {
        await CallPopulateCustomerDropDown(ddlCustomer, selectedValue);
        SetCustomerMultiColumnAfterAddingNewCustomerFromNewOrder();
}

function CallPopulateCustomerDropDown(ddlCustomer, selectedValue) {
    try {
        return new Promise((resolve, reject) => {
            LogCallStackToConsole('populateCustomerDropDown(ddlCustomer, selectedValue)');
            //#region Variable Declarations

            let orderField, grid, ds, foundCatalog, dd;

            //#endregion

            for (i = 0; i < CustomersList.length; i++) {
                if (CustomersList[i].Company.length == 0) {
                    CustomersList[i].Company = CustomersList[i].FirstName + " " + CustomersList[i].LastName
                }
            }

            $(ddlCustomer).empty();

            $(ddlCustomer).kendoMultiColumnComboBox({
                placeholder: "Select Customer...",
                dataTextField: "Company",
                dataValueField: "CustomerID",
                height: 300,
                columns: [
                    { field: "FirstName", title: "First", width: 200 },
                    { field: "LastName", title: "Last", width: 200 },
                    { field: "Company", title: "Company", width: 200 }
                ],
                footerTemplate: "#: instance.dataSource.total() # Customers Found",
                filter: "contains",
                filterFields: ["FirstName", "LastName", "Company"],
                dataSource: {
                    data: CustomersList,
                    sort: [
                        { field: "FirstName", dir: "asc" },
                        { field: "LastName", dir: "asc" },
                        { field: "Company", dir: "asc" }
                    ]
                },
                change: function () {

                },
                select: function (e) {
                    LogCallStackToConsole('populateCustomerDropDown(ddlCustomer, selectedValue).select');
                    orderField = $('#txtOrderName').val();
                    grid = $('#gridNewOrder').getKendoGrid();
                    ds = grid.dataSource.view();
                    foundCatalog;
                    for (let i = 0; i < ds.length; i++) {
                        if (ds[i].Catalog.length > 0) {
                            foundCatalog = true;
                            break;
                        }
                    }

                    if (orderField.length > 0 && foundCatalog) {
                        $('#btnOK').prop("disabled", false);
                    }
                }
            });
            if (selectedValue != null) {
                dd = $(ddlCustomer).data("kendoMultiColumnComboBox");
                dd.value(selectedValue);
            }
        });
        resolve();
    }
    catch (err) {
        reject();
    }
}

function SetCustomerMultiColumnAfterAddingNewCustomerFromNewOrder() {
    let customerMultiColumn = $('#ddlCustomer').data("kendoMultiColumnComboBox");
    customerMultiColumn.select(function (dataItem) {
        return dataItem.Company === g_CustomerEditorObject.companyName;
    });
    ResetGlobalObject(g_CustomerEditorObject);
}

Upvotes: 0

Views: 437

Answers (2)

Kevin Jantzer
Kevin Jantzer

Reputation: 9451

You're calling resolve outside of the promise

Also, it's sort of bad design to try catch a promise if the function is returning the promise. The code calling the function should try/catch the returned promise, like so:

async function CallToPopulateCustomerDropDown(ddlCustomer, selectedValue) {

    try{
        await CallPopulateCustomerDropDown(ddlCustomer, selectedValue);
        SetCustomerMultiColumnAfterAddingNewCustomerFromNewOrder();
    }catch(err){
        console.log(err)
    }
}

function CallPopulateCustomerDropDown(ddlCustomer, selectedValue) {
    return new Promise((resolve, reject) => {
        LogCallStackToConsole('populateCustomerDropDown(ddlCustomer, selectedValue)');
        // ....the rest of your code

        // if you code has a problem, you can choose to reject
        // return reject('the reason')

        resolve()
    });
}

Upvotes: 1

Andy Ray
Andy Ray

Reputation: 32066

Shortening your code, you're doing this:

return new Promise((resolve, reject) => {
    ...
});
resolve();

Note how you're calling resolve() outside of the Promise callback function block, meaning your code doesn't have access to it. You're also doing the same with catch(), you're using it outside of the function it's available in. If you want to learn more about this, you can research "Javascript scope."

You're probably trying to do this:

return new Promise((resolve, reject) => {
    try {
        LogCallStackToConsole('populateCustomerDropDown(ddlCustomer, selectedValue)');
        ...
        resolve();
    }
    catch (err) {
        reject();
    }
});

However, your code isn't actually doing anything asynchronous, so you don't need a promise here, at least not in this implementation. A promise is meant to handle a function that finishes "later", like a network call. Your function appears to execute synchronously like a regular Javascript function. There's no callback or operation you're waiting for.

Upvotes: 2

Related Questions