0

I would like to read a text file and get its content to a variable and use that variable everywhere.

var latest_date = "";
$.get('/data/latest_data.txt', function(data) {
  latest_date = data; // eg "20180102"
}, 'text');

// and lots of similar functions like this
$(function() {
  $.getJSON('../data/' + latest_date + '/overview.json', function(data){
    $('#overview').DataTable(data);
  });
});

However, other functions will run before latest_date variable gets its correct value. How can I make sure the $.get function runs before anything else?

It's similar to this question How should I call 3 functions in order to execute them one after the other? But I have loads of functions. I can't put all of them as the callback of the initial function. I'm also reluctant to add timeOut to all my functions. Is there a better way?

jf328
  • 6,841
  • 10
  • 58
  • 82
  • Do the other functions really need to execute at `document.ready` or can they be run at a later point? – Tiramonium Mar 03 '18 at 12:54
  • 1
    Also, why don't you encapsulate the second function within the first? From the logic you presented, it makes no sense why they needed to be separated. – Tiramonium Mar 03 '18 at 12:56
  • @Tiramonium, I think so, as long as they are run. I'm new to web dev, those functions are just copied from package tutorials. – jf328 Mar 03 '18 at 13:02
  • @Tiramonium, I'm just treating the first function as part of variable definition. That global variable is then used as package shared variable used everywhere. – jf328 Mar 03 '18 at 13:04
  • Sounds like javascript promises are what you're after https://scotch.io/tutorials/javascript-promises-for-dummies – Boardy Mar 03 '18 at 14:27
  • try a callback function https://developer.mozilla.org/en-US/docs/Glossary/Callback_function – Tom O. Mar 03 '18 at 14:37
  • @jf328 if any of these functions will be run after a event happens, like a button or link click for example, they don't need to be executed as soon as the page is loaded, they should be called when said button or link is clicked instead. – Tiramonium Mar 04 '18 at 16:01
  • @jf328 Also, from what I'm surmising, I don't understand why your `overview` DataTable would have different DataTable plugin settings in each date. What exactly are you trying to achieve with that logic? Maybe we can help with that more effectively if we knew what you actually need help with. – Tiramonium Mar 04 '18 at 16:06
  • @Tiramonium, Thanks. The settings are all the same, but data are different for each day. Every day I calculate a json file, the page is to have a date selector to view tables of any calculated day's table, but when the page loads, I want it to have the current day's table loaded automatically – jf328 Mar 04 '18 at 16:36

2 Answers2

3

You can use a Promise object on the jqXHR returned by the get method. For example:

var promise = $.get('/data/latest_data.txt', 'text').promise();

promise.then(function (latest_date) {
    $.getJSON('../data/' + latest_date + '/overview.json', function (data) {
        $('#overview').DataTable(data);
    });
});
Ippei Tanaka
  • 149
  • 1
  • Agree....the best solution and what it's born for is the deferred object.. –  Mar 03 '18 at 14:29
0

You could use an event and then attach multiple listeners to call the functions you need to call once the file has loaded:

Dispatch event on the window object when the first request completes:

var latest_date = "";
$.get('/data/latest_data.txt', function(data) {
  latest_date = data; // eg "20180102"
   window.dispatchEvent(new Event('content:loaded'))
}, 'text');

Listen for the event to call the other gets.

window.addEventListener('content:loaded', function() {
   $.getJSON('../data/' + latest_date + '/overview.json', function(data){
      $('#overview').DataTable(data);
   });
});

You could also send the latest_date variable in the event if you want to avoid using global variables:

window.dispatchEvent(new CustomEvent('content:loaded', {
    detail: {
        latest_date: 'date',
    }
}));

window.addEventListener('content:loaded', function(e) {
    console.log(e.detail.latest_date); // = 'date'
});

Read more about Events here

Sinan Guclu
  • 1,075
  • 6
  • 16