Search code examples
javascriptjqueryajaxloadinglit-element

Show the loaded element first in javascript


I would like to know how to sort the loaded things first using javascript.

As shown, I have array of elements, which am passing to a function and making ajax call, till it completes success data, am showing a loader(.gif). I want to show loaded elements first, if loading element is top, always move to last of stack,

so I have a element undefined, once loading completes, turning to 1 to know its loaded, but its not working, i would like to know any possible ways to do in javascript

var elements=["trans", "fund", "service"];
setTimeout(()=>{elements.map(e=>this.getData(e));}, 1000);

function getData(id){
    var loader = this.shadowRoot.getElementById("overlay-"+id);
    $(loader).css("display", "block");
        $.ajax({
      url: url,
      method: 'get',
      global: false,
      async: true,
      dataType: "json",
      data: {
         element: id
      },
      success: function (data) {
        self.getNewData(data);  
      },
      complete: function(){
        $(loader).css("display", "none");
       },
    }).responseText;
}

//success data will be like below

data=[{
 "id": "trans",
 "load": "undefined",
 "option": "bank",
 "cost": "100"
},{
  "id": "fund",
 "load": "undefined",
 "option": "credit",
"cost": "300"
},{
 "id": "service",
 "load": "undefined",
 "option": "bank",
 "cost": 200"
}]

function getNewData(newdata){
  newData.map(e=>({ ...e, load: 1 }));
  var list =[];
  list = newData.sort(function(a,b){
   return a.cost - b.cost && a.load - b.load;  
 })
}
render(){
 <style>
              .overlay{
                background-color: #e9e9e9;
                opacity: 0.7;
                position: absolute;
                left: 0px;
                top: 0px;
                z-index: 100;
                height: 100%;
                width: 100%;
                overflow: hidden;
                background-image: url('../images/loader.svg');
                background-position: center;
                background-repeat: no-repeat;
              }
              .loadingimg{
                background: url(../images/loader-img.svg) center center no-epeat;
                height: 100%;
                z-index: 20;
              }
</style>

 list.map(e=>{
  return html`
            <div class="overlay" id="overlay-${e.id}">
              <div class="loadingimg" id="loading-${e.id}"></div>
            </div>
          <p>Welcome to ${e.id}</p>
  `;
 }) 
}

Solution

  • If it's multiple calls, this method may give you greater control: https://css-tricks.com/multiple-simultaneous-ajax-requests-one-callback-jquery/ ...or set a variable, e.g. var step = 0 and update it within your success with step++, then in complete if (step === elements.length) doSomething()

    You can also do something along these lines:

    var elements = ["trans", "fund", "service"];
    var step = 0;
    
    function recursiveDataFetch(arr) {
      var data = arr.shift();
      if (data === undefined) return;
      step++;
      $.get(url, function(response) {
        if (step < elements.length) return recursiveDataFetch(arr);
        return doSomethingWhenAllIsReady();
      });
    }
    

    If I misread the questions and it's a single call, then you're just waiting for data to be present before removing the loader, then just use a callback or take a look at something I wrote up here: https://jsfiddle.net/darcher/4hqo57wv/ (NOTE: It's vanilla js, but should help.)