0

I'm selecting values from my db in mysql and comparing them with values from JSON. I'm receiving the right results but since I'm using append the results shows up one by one, which looks like animation I would like to get them all at once and show some kind of loading icon while the loop is running, I've tried few different ways but nothing worked.

<?php $sql= "select a_id,b_id,res_a,res_b from betts_gr where u_id='".$u_id[0]."'";
$user_bets = mysqli_query($conn,$sql);

while($user_bets1 = mysqli_fetch_array($user_bets)){
?>
<script>
    $(document).ready(function() {
        var a_id = "<?php echo $user_bets1[0]?>";
        .....
        var car = [];
        $.getJSON('http://api.football-api.com/2.0/matches? 
            comp_id = 1204 & from_date = '+today+' & to_date = '+plusmonth+' & Authorization ', 
            function(data) {
                var html = "";
                console.log(data);
                $.each(data, function(index, value) {
                    var teama = value.localteam_name;
                    var teamb = value.visitorteam_name;
                    .......

                    function add(name, point) {
                        car.push({
                            teamb: teamb,
                            teama: teama,
                            form: form,
                            data: data,
                            teama_id: teama_id,
                            teamb_id: teamb_id,
                            a_res: a_res,
                            b_res: b_res
                        });
                    }

                    add(teama, teamb, data, form, teama_id, teamb_id, a_res, b_res);
                });

                for (var n = 0; n < car.length; n++) {
                    if (car[n].teama_id == a_id && car[n].teamb_id == b_id) {

                        html += "<tr><td><input type='hidden' name='aid" + n + "' 
                        value = '"+car[n].teama_id+"' > < input type = 'hidden'
                        name = 'bid"+n+"'                           
                        value = '"+car[n].teamb_id+"' > " +
                            car[n].data +
                            "</td><td> " + car[n].teama + "</td><td>" + car[n].a_res + "-" +
                            car[n].b_res + "</td><td> " +
                            car[n].teamb + '</td><td> you predicted ->' + pred_resa + ' - ' + pred_resb +
                            '</tr>';
                    }
                }

                $(".message").append(html);
            });
    });
</script>
<?php  }  ?>
  • I have not gone through the code, sorry, tl;dr, but if loading icon is what you are aiming for - then do this. Save a variable that already has the number of items, next, show the loading icon already, keep it there, now check if the loop has reached the end, if yes then remove the loading icon. – Deepak Kamat Oct 11 '18 at 13:31
  • That's where I'm struggle, I'm not sure how to check if the loop reach the end, I've tested the loop by echo some variable inside the php loop and it echo it straight away but the results from js where still showing one by one, it seems like it take time for json to return the values. – user2741313 Oct 11 '18 at 13:49
  • Does this help https://stackoverflow.com/questions/5223/length-of-a-javascript-object ? – Deepak Kamat Oct 11 '18 at 14:23
  • use Array.forEach or Array.map instead of for (var n = 0; n < car.length; n++), and Template literals instead of the plain string. and function add() is actually useless, just do the car.push(). and even better you create a demo page(like fiddle.js) to reproduce your problem with the mock data. – Pengcheng Oct 11 '18 at 14:30

3 Answers3

0

the example for using the Array.map and the template literals instead of the for loop and the plain string concat:

const isTargetTeam = item => item.teama_id == a_id && item.teamb_id == b_id;
const html = car.slice(0) // copy the array car
                 .filter(isTargetTeam)
                 .map((item, index) => 
                      `<tr>
                          <td>
                              <input type='hidden' name='aid${index}' value='${item.teama_id}'>
                              <input type='hidden' name='bid${index}' value='${item.teamb_id}'>
                              ${item.data}
                          </td>
                          <td>
                              ${item.a_res}-${item.b_res}
                          </td>
                          <td>
                              ${item.teamb}
                          </td>
                          <td> you predicted -> ${pred_resa} - ${pred_resb}
                      </tr>`
                     ).join('')
Pengcheng
  • 323
  • 1
  • 5
0

You should not mix PHP and Javascript like that. Currently this will result in X document.ready functions with X getJSON requests.

If you want to do the API requests from the local client, you should do ONE javascript function where you pass in the selected user_bets as an array. There are different possibilities to determine if all loadings have been finished: either counting up and checking after every callback if the max number is reached, or using Promises and Promise.all().

<script>
    var user_bets = <?php echo json_encode($user_bets);?>;
    $(document).ready(function () {
        Promise.all(user_bets.map(function (id) {
            return fetchFromApi(id);
        })).then(function(array){
            var html = "";
            for(var i = 0; i < array.length; i++){
                html += processData(array[i]);
            }
            $(".message").append(html);
        });
    });

    function fetchFromApi(user_id) {
        return new Promise(function (resolve, reject) {
            $.getJSON()
                .done(function (data) {
                    resolve(data);
                })
                .fail(function (error) {
                    reject(error);
                });
        });
    }

    function processData(data){
        var html = '';
        // do your html processing of a single api call here
        return html;
    }
</script>

Alternatively you can use CURL to do the API requests server-side already.

Danmoreng
  • 2,367
  • 1
  • 19
  • 32
0

Thanks for advise I just realize I should get data with one request. I've passed the whole array to js and since I'm not sure how promise.all is working I did two for loops nested and is working fine, the only thing I still can't figure out how to check if the loops are finished so I could add loading icon while loop is running.

function add(name, point) {
car.push({ teamb : teamb, teama : teama, form:form, data:data, teama_id:teama_id, 
teamb_id:teamb_id, a_res:a_res, b_res:b_res});
}

add(teama,teamb,data,form,teama_id,teamb_id,a_res,b_res);
});



for(var n=0;n<car.length;n++){
var taba = [<?php echo json_encode($at1)?>];
var tchild = taba[0];
      for(var u=0;u<tchild.length;u++){
            if(car[n].teama_id == tchild[u].localteam_id 
            && car[n].teamb_id == tchild[u].visitorteam_id){
                   html +=   "<tr><td><input type='hidden' name='aid"+n+"'
                   value='"+car[n].teama_id+"'> 
                   <input type='hidden' name='bid"+n+"' 
                   value='"+car[n].teamb_id+"'>"
                   +car[n].data  
                      +"</td><td> "+car[n].teama + "</td><td>"+ car[n].a_res 
                      + "-"+  car[n].b_res  + "</td><td> "
                      + car[n].teamb + '</td><td> you predicted - 
                      >'+tchild[u].localteam_score +' - '+tchild[u].visitorteam_score +
                     '</td></tr>';

}
}
}

$(".message").append(html);