El Guapo
El Guapo

Reputation: 597

Javascript variable scope inside ajax function

i know this is probably a stupid question and i know js scope questions are extremely common on SO, but could you possibly be kind enough to help me with this one anyway.

Here is my function:

function checkOpen(storeData) {
if (storeData.menu === 'true') {

    var offerImgPath = '/wcsstore/ConsumerDirectStorefrontAssetStore/images/colors/color'+ Brand.styleColour + '/v3/',
        offer1,
        offer2;

    cafeTabContent = '<p>Cafe/Restaurant facilities are available in this store.</p>';
    cafeTabContent += '<p class="menu_link"><a href="/store_menus/menu.pdf" target="_blank">Click here to download a menu</a></p>';

    if (Brand.storeLocatorSettings.cafeOffersOn === true) {

        $.ajax({
            url : Arcadia.Brand.storeLocatorSettings.offersPageURL,
            success : function(data) {
                var offerContainer = $(data).find('#basic_story_content');
                offer1 = offerContainer.children(':first-child').attr('src');
                offer2 = offerContainer.children(':last-child').attr('src');
            }
        });

        console.log(offer1);

        cafeTabContent += '<p>Current offers:</p>';
        cafeTabContent += '<p class="offer_graphic"><img src="' + offer1+ '" alt="Offer 1" /></p>';
        cafeTabContent += '<p class="offer_graphic"><img src="' + offer2+ '" alt="Offer 2" /></p>';
    }

    return cafeTabContent;
} else {
    return false;
}
};

The problem that i am having is that despite the fact that offer1 & offer2 are defined outside the ajax success function, the values applied within this function are not being maintained outside hence console.log(offer1) returns undefined instead of the image path. I know this is a scope question, and it is really bugging me. Any help would be greatly appreciated.

Upvotes: 0

Views: 4371

Answers (3)

rfunduk
rfunduk

Reputation: 30442

This isn't a scope problem. The problem is that by the time the ajax request completes and the callback gets called (setting offer1 and offer2), the console.log(...) stuff is already long done.

Try it by putting another console.log('ajax complete'); inside the callback, and notice that it gets called last.

You can fix it by simply putting the rest of the function inside the callback, most probably.

Upvotes: 1

Platinum Azure
Platinum Azure

Reputation: 46193

You're dealing with a different (though vaguely related) issue: the asynchronous nature of AJAX.

When your code invokes $.ajax(), that request is executed asynchronously and the code returns immediately when the request is sent. Thus offer1 and offer2 are still undefined.

The correct thing to do is to put any code that depends on the AJAX result into your success callback function (or a function called from said callback).

Upvotes: 1

Ajinkya
Ajinkya

Reputation: 22710

In Ajax A means Asynchronous.
So console statement is executed before actual data is returned. It means after successful return value is assigned to offer1 and offer2 but you have printed it on console before that.
Try this

  $.ajax({
            url : Arcadia.Brand.storeLocatorSettings.offersPageURL,
            success : function(data) {
                var offerContainer = $(data).find('#basic_story_content');
                offer1 = offerContainer.children(':first-child').attr('src');
                offer2 = offerContainer.children(':last-child').attr('src');
        console.log(offer1);
        console.log(offer2);
            }
        });

Upvotes: 1

Related Questions