Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

JS functions giving inconsistent outputs in console

As someone who is still very new to JS i am struggling to understand why some of the functions and code i write give inconsistent outputs inside the console. For example the output of an array will contain 4 items on one refresh of the webpage, then contain 8 items on the next refresh. Why might this happen?

Example of this:

function biggestChanges(idsList) {
var listOfChanges = []
for (let i = 0; i < 16; i++) {
    fetch(`jsonFiles\\${idsList[i]}.json`)
    .then(response => response.json())
    .then(data => {
        //get data from JSON file
        var priceCurrentNEW = data.JSONdata[data.JSONdata.length - 1].prices[0]
        var priceDayBeforeNEW = data.JSONdata[data.JSONdata.length - 2].prices[0]
        var priceCurrentUSED = data.JSONdata[data.JSONdata.length - 1].prices[1]
        var priceDayBeforeUSED = data.JSONdata[data.JSONdata.length - 2].prices[1]

        var changeNEW = priceCurrentNEW / priceDayBeforeNEW * 100 -100 
        var changeUSED = priceCurrentUSED / priceDayBeforeUSED * 100 - 100
        var averageChange = (changeNEW + changeUSED) / 2
        averageChange = averageChange.toFixed(2)
    
        subList = [idsList[i], averageChange]
        listOfChanges.push(subList)

        //run on last iteration.
        if (i == 15) {
            var orderedList = []
            var originalLength = listOfChanges.length
            for (var x = 0; x < 16; x++) {
                var max = listOfChanges[0][1]
                var index = 0
                // -k on range as on each iteration the length of the list decreases by 1
                for (var k = 0; k < 16-k; k++) {                        
                    if (listOfChanges[k][1] > max) {
                        max = listOfChanges[k][1]
                        index = k
                    }        
                }
                orderedList.push(listOfChanges[index]) 
                listOfChanges.splice(index, 1) 
            }
                console.log(orderedList, "orderedlist")
                for (var l = 0; l < orderedList.length; l++){
                document.getElementById(`change-${orderedList[l][0]}`).innerHTML = "change: £" + orderedList[l][1]
                }
        }
    })  
}

}
function finalBiggestChanges() {
    fetch("JSONitemIDsList.json")
    .then(response => response.json())
    .then(data => {
        biggestChanges(data.ids)
    })
}

finalBiggestChanges()

Example output 1Example output 2

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You’ve got a race condition. //run on last iteration. actually runs during the callback of the last iteration to start the fetch(`jsonFiles\\${idsList[i]}.json`) call, but not necessarily when the last http response arrived.

You can mitigate this by doing if (listOfChanges.length == 16) (i.e. when the 16th response was added to the array) instead of if (i == 15), but really the proper solution is to use Promise.all instead:

function loadChange(id) {
    return fetch(`jsonFiles\\${idsList[i]}.json`)
    .then(response => response.json())
    .then(data => {
        //get data from JSON file
        var priceCurrentNEW = data.JSONdata[data.JSONdata.length - 1].prices[0]
        var priceDayBeforeNEW = data.JSONdata[data.JSONdata.length - 2].prices[0]
        var priceCurrentUSED = data.JSONdata[data.JSONdata.length - 1].prices[1]
        var priceDayBeforeUSED = data.JSONdata[data.JSONdata.length - 2].prices[1]

        var changeNEW = priceCurrentNEW / priceDayBeforeNEW * 100 -100 
        var changeUSED = priceCurrentUSED / priceDayBeforeUSED * 100 - 100
        var averageChange = (changeNEW + changeUSED) / 2
        averageChange = averageChange.toFixed(2)
    
        return [id, averageChange]
    });
}


function finalBiggestChanges() {
    return fetch("JSONitemIDsList.json")
    .then(response => response.json())
    .then(data => {
        return Promise.all(data.ids.slice(0, 16).map(loadChange));
    })
    .then(listOfChanges => {
        listOfChanges.sort((a, b) => b[1] - a[1]); // largest first
        console.log(listOfChanges, "orderedlist")
        for (const change of listOfChanges) {
            document.getElementById(`change-${change[0]}`).innerHTML = "change: £" + change[1]
        }
    });
}

finalBiggestChanges().catch(console.error);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading