0

I am a newbie JQuery/JavaScript user having a problem and cannot understand why my div data attribute is empty after saving/retrieving the DOM data. I need a little help if possible with examples to explaining what I am doing wrong. I have spent a few hours on this with no light in sight.

    // HTML
    <div id="outer">
        <div id="mydiv" data-myval=""></div>
    </div>

    // JS file body

    function getSomeData(){
        var url = "http://ip-api.com/json";
        $.ajax({
            url: url,
            dataType: "json",
            cache: false,
        }).done(function(data) {
            //var myjson = data;
            var myjson = JSON.stringify(data);
            $("#mydiv").attr("myval", data);  // setter
        }, "json");
    }


    $(document).ready(function()
    { 
        getSomeData();

        // get json data from attr data-myval
        //var object = JSON.parse(myjson);
        var myjson = $("#mydiv").data();  //getter

        alert(myjson);  

        if(typeof object === 'undefined') 
        {
          alert('No data found!');

        }
        else
        {
            // do something
            var lat = object.lat;
            var lng = object.lon;

            // more codes
        }
    }
Carl Barrett
  • 209
  • 5
  • 16
  • 2
    Ajax is asynchronous. The data element will not be set by the time you perform the getter – Taplar Feb 04 '19 at 18:18
  • 3
    Your getting the value before it's set by the AJAX request, secondly when the AJAX request is finished you're setting a plain attribute on your element to house the returned json response, not setting a data attribute, so $("mydiv").data() wouldn't return the correct value anyway. – zfrisch Feb 04 '19 at 18:21
  • What is the best work-around for this situation? Do I need to separate codes by putting the function getSomeData in a different file? – Carl Barrett Feb 04 '19 at 18:25
  • Use the promises to do your work – Taplar Feb 04 '19 at 18:35

1 Answers1

0

First, it is important to understand that AJAX requests run asynchronously. This means that JavaScript will continue execution of your code while your browser is waiting for the response. To visualize:

JS execution  
|
|            getSomeData() runs, sends AJAX request to -------> server
|                  |                                               |
|                  V                                               |
|            var myjson = $("#mydiv").data(); //not yet set        |
|                                                                  |
|                                                                  |
|                                                                  |
|                                                                  |
|                                                                  V
|           .done(function(data) {}); //executes upon response <--response
V

So if you want to retrieve the data in your data-myval, you can only do so after your AJAX call has finished. There is no point in getting this data immediately after you call getSomeData(). You could for instance get the data after the user clicks on something.

Second, you have to set the data attribute with the .data() function, not the .attr() function.

Example solution:

// HTML
    <div id="outer">
        <div id="mydiv" data-myval=""></div>
    </div>
    <button id="clicker">Click me!</button>
// JS file body

    function getSomeData(){
        var url = "http://ip-api.com/json";
        $.ajax({
            url: url,
            dataType: "json",
            cache: false,
        }).done(function(data) {
            $("#mydiv").data("myval", data);  // setter
        }, "json");
    }


    $(document).ready(function()
    { 
    getSomeData();


    $("#clicker").click(function(e) {
        var data = $("#mydiv").data("myval");  //getter
        alert(data.exampleItem);
    });
nucleaR
  • 325
  • 2
  • 11