2

Here is my problem. I have external file include.html which i load with $.ajax and append to the body. Content of include.html:

<p id="descriptionText">My description</p>

I want to get value of p#descriptionText after ajax completed, but as the result i see "undefined"

<!DOCTYPE html>
<html lang="en">
<head>    
<meta charset="UTF-8">
    <title>AJAX</title>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"
            integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
    <script>
        $(document).ready(function () {
            $.ajax({
                url: "include.html",
                dataType: "html",
            }).done(function (response) {
                $('body').html(response);
            });

            console.log($('#descriptionText').val());
        });
    </script>
</head>
<body>

</body>
</html>

Result are the same even if i try to use closure. Example below.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>AJAX</title>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"
            integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
    <script>
        function func() {
            $.ajax({
                url: "include.html",
                dataType: "html",
            }).done(function (response) {
                $('body').html(response);
            });

            return function() {
                console.log($('#descriptionText').val());
            }
        }

        func()();
    </script>
</head>
<body>

</body>
</html>

If i use async: false parameter in $.ajax it works, but i need asynchronous exactly. What is my problem? Thank you!

Grey13
  • 58
  • 7
  • You don't wait for $.ajax to finish the call. You can try having a custom callback. – Adam Azad Aug 03 '16 at 21:06
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Heretic Monkey Aug 03 '16 at 21:18
  • Or http://stackoverflow.com/questions/9466241/selecting-dom-elements-after-html-was-inserted-in-a-page-with-ajax – Heretic Monkey Aug 03 '16 at 21:19

4 Answers4

3

In a nutshell: Move console.log($('#descriptionText').val()); into the .done() callback of the $.ajax()

like:

.done(function (response) {
    $('body').html(response);
    console.log($('#descriptionText').val());
});

Explanation:

.done() is the success callback when the promise is resolved. A promise in the async land means that the code will be executed at a point later than the current tick of clock. Your console.log is executed at this moment and so will always be undefined since, the promise hasn't been resolved yet.

So, soln is to take care that your console.log is executed after the promise has been resolved. Do this in many possible ways, one simple being like I mentioned earlier: Moving the statement inside the .done() after you have performed the .html() DOM Manipulation.

Iceman
  • 6,035
  • 2
  • 23
  • 34
1

You messing up with async flow. Move the output into async callback. Like this:

$(document).ready(function () {
    $.ajax({
        url: "include.html",
        dataType: "html",
    }).done(function (response) {
        $('body').html(response);
        console.log($('#descriptionText').val());
    });
});
Oleg Imanilov
  • 2,591
  • 1
  • 13
  • 26
1

The issue is indeed related to asynchronous code execution. This line:

        console.log($('#descriptionText').val());

... executes before this executes:

            $('body').html(response);

That is because the callback function you provide to .done is executed asynchronously, when the Ajax response has been received, and JavaScript is reading the event queue to see what next it has to execute. But this will only happen when the currently executing code has completed (i.e. call stack is emptied).

So... to solve this, you have to move your code inside the done callback:

        }).done(function (response) {
            $('body').html(response);
            console.log($('#descriptionText').val());
        });
trincot
  • 317,000
  • 35
  • 244
  • 286
1

so the callback where you append the response to the body is the only section of your code that waits for the request to complete. hence the function being defined with .done(...).

if you add your code to this function like this it will work.

.done(function (response) {
    $('body').html(response);
    console.log($('#descriptionText').val());
});
thedarklord47
  • 3,183
  • 3
  • 26
  • 55