1

I have a leaflet map that takes in data from multiple sources via the LeafLet Ajax plugin.

I want to execute certain functions only after ALL the data has been loaded, not just one layer.

The data loading part of my code is fairly simple and looks like this:

data_layer1=L.geoJSON.ajax(data1.geojson,{options});
data_layer2=L.geoJSON.ajax(data2.geojson,{options});
data_layer3=L.geoJSON.ajax(data3.geojson,{options});

Now if I want to execute a function after data_layer1 is loaded, I will have to

data_layer1.on("data:loaded",function(){
      //function body
});

But what I want to do is execute a function after data_layer1, data_layer2, and data_layer3 is loaded. How would I do that?

I am fairly new to AJAX, so the Asynchronous part of this is a bit disorientating.

2 Answers 2

3

According to the docs there is a function L.Util.ajax that returns a promise. So this should work (is untested)

data_layer1=L.Util.ajax(data1.geojson,{options});
data_layer2=L.Util.ajax(data2.geojson,{options});
data_layer3=L.Util.ajax(data3.geojson,{options});

Promise.all([data_layer1, data_layer2, data_layer3]).then(loadedLayers => {
    // The variable loadedLayers is an array with the three loaded layers
})

Edit: The above code assumes a modern browser. Since IE don't support Promise a polyfill have to be added to make it work in IE

<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script>

And if the arrow-syntax isn't supported it should be replaced with old-school function syntax

Promise.all([data_layer1, data_layer2, data_layer3]).then(function(loadedLayers) {
    // The variable loadedLayers is an array with the three loaded layers
})
4
  • 1
    Promise is not supported in any version of Internet Explorer.
    – TomazicM
    Commented Feb 24, 2019 at 10:07
  • 1
    That is a good point. In case IE-support is important you would need to use a Promise polyfill. You can do that by adding <script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script> in the head of your document
    – Dataform
    Commented Feb 24, 2019 at 11:14
  • You should include this in your answer. There is also question of => syntax.
    – TomazicM
    Commented Feb 24, 2019 at 13:04
  • 1
    Thanks. I am new to Stackoverflow. I have tried to clarify my answer
    – Dataform
    Commented Feb 24, 2019 at 13:54
2

One possibility would be to use setTimeout function to check when all three layers are loaded, something like this:

var layer1Loaded = false;
var layer2Loaded = false;
var layer3Loaded = false;

function checkAllLoaded() {
  if (layer1Loaded && layer2Loaded && layer3Loaded) {
    // process loaded layers
    }
  else {
    setTimeout(checkAllLoaded, 100);
  }
}

data_layer1.on("data:loaded",function(){
  layer1Loaded = true;
});
data_layer2.on("data:loaded",function(){
  layer2Loaded = true;
});
data_layer3.on("data:loaded",function(){
  layer3Loaded = true;
});

checkAllLoaded();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.