-1

When my JavaScript is run it will call the getDoctorComplete function. When the AJAX request is completed, it will set a = chelsea. Otherwise, there will be a trigger change and will run $('#dropdown_hosp').change(.... In the $('#dropdown_hosp').change(..., it will call the getSpecialty function. When the AJAX request is completed with the getSpecialty function, I want to get the value of a. I console.log it, but it contains an empty string. How can I solve this problem?

var a = '';
$(document).ready(function () {
    app.getHospital({
        areaId: ''
    });

    app.getDoctorComplete({
        doctorId: doctorId,
        doctorel: $('#dropdown_doct')
    });

    $('#dropdown_hosp').change(function () {
        var dropdownspecialty = $('#dropdown_spec');
        app.getSpecialty({
            hospitalId: $('#dropdown_hosp').val(),
            apiUrl: 'api',
            special: dropdownSpec
        });
    });
});

app = function () {
    function getHospital({
        areaId
    }) {
        // ...
        $.ajax({
            // ...
            success: function (result) {
                // ...
            },
            // ...
        }).done(function () {
            $('#dropdown_hosp').select2();
        });
    };

    function getSpecialty({
        hospitalId,
        apiUrl,
        special
    }) {
        // ...
        $.ajax({
            // ...
        }).done(function () {
            // test here
            console.log(a);
        });
    };

    function getDoctorComplete({
        schdoctor_id,
        doctorel
    }) {
        // ...
        $.ajax({
            // ...
            success: function (result) {
                // ...
            },
            // ...
        }).done(function () {
            // ...
            a = 'chelsea';
            b = '..';
            $('#dropdown_hosp').val(b).trigger('change');
        });
    };
    return {
        getSpecialty: getSpecialty,
        getDoctorComplete: getDoctorComplete
    }
}();
moses toh
  • 12,344
  • 71
  • 243
  • 443
  • Possible duplicate of [Execute function after Ajax call is complete](https://stackoverflow.com/questions/23283276/execute-function-after-ajax-call-is-complete) – MauriceNino Sep 26 '19 at 08:12
  • 1
    You need to wrap your ajax functions in a `Promise`, resolve that Promise in the `done` method and call `.then()` after the call, like `app.getDoctorComplete( ... ).then(() => { Do something after the call here })`. – MauriceNino Sep 26 '19 at 08:13
  • try to add callback, maybe that can help – MoxGeek Sep 26 '19 at 10:37

1 Answers1

1

Your problem ist, that your ajax call is async and therefore a is not reassigned when being logged. Here would be a solution to your problem using Promise, to create an async function, resolve, to mark the return of that async function and .then() to do something after that async function:

var a = '';
$(document).ready(function () {
    app.getHospital({
        areaId: ''
    });

    app.getDoctorComplete({
        doctorId: doctorId,
        doctorel: $('#dropdown_doct')
    })
        .then(() => { // Add the .then() callback to do something after getDoctorComplete finished
            $('#dropdown_hosp').change(function () {
                var dropdownspecialty = $('#dropdown_spec');
                app.getSpecialty({
                    hospitalId: $('#dropdown_hosp').val(),
                    apiUrl: 'api',
                    special: dropdownSpec
                });
            });
        });
});

app = function () {
    function getHospital({
        areaId
    }) {
        return new Promise((resolve, reject) => {
            // ...
            $.ajax({
                // ...
                success: function (result) {
                    // ...
                },
                // ...
            }).done(function () {
                $('#dropdown_hosp').select2();

                resolve(); // Add resolve
            });
        });
    };

    function getSpecialty({
        hospitalId,
        apiUrl,
        special
    }) {
        return new Promise((resolve, reject) => {
            // ...
            $.ajax({
                // ...
            }).done(function () {
                // test here
                console.log(a);

                resolve(); // Add resolve
            });
        });
    };

    function getDoctorComplete({
        schdoctor_id,
        doctorel
    }) {
        return new Promise((resolve, reject) => {
            // ...
            $.ajax({
                // ...
                success: function (result) {
                    // ...
                },
                // ...
            }).done(function () {
                // ...
                a = 'chelsea';
                b = '..';
                $('#dropdown_hosp').val(b).trigger('change');

                resolve(); // Add resolve
            });
        });
    };
    return {
        getSpecialty: getSpecialty,
        getDoctorComplete: getDoctorComplete
    }
}();
MauriceNino
  • 6,214
  • 1
  • 23
  • 60
  • is there a simpler way? because my case is complex. I'm afraid it will impact others – moses toh Sep 26 '19 at 08:40
  • @SuccessMan -- You can theoretically pass a (callback)-function as a parameter to each function and call that inside the `done` block. Other than that, there is no safe solution that comes to my mind. That's how asynchronous code works and you should get used to it, because there is no way around it when dealing with Ajax requests (the word Ajax literally means "**asynchronous** JavaScript and XML" – MauriceNino Sep 26 '19 at 09:02
  • @SuccessMan if this solved your problem, please accept the answer and feel free to give an upvote. If not, please provide more info. – MauriceNino Sep 28 '19 at 12:04