Search code examples
javascriptarraysincludefetch

include() function works randomly when comparing values in array


I wrote this JS code yesterday for a school project, and everything was okay(ish). The site showed the key/value I wanted to add to the object. Although today, when I reloaded the server and the site, all the values were undefined or "muggle". I refreshed the page many times, and sometimes it works, but the next time it's undefined again.

So the code should be do something like this:

1.Fetch two JSON files, one is a list of students and the other is just family names

2.Create two arrays from the data

3.Check every single student's last name if it's on the list or not

4.Decide that the student is pure, half or muggle

5.Add the value to the student object

6.Show on the website

I know that it's something to do with the call order of the functions and something is wrong where I use the include() method two check the names. But unfortunately, I couldn't find out what. Here is the JS code:

//LINKS
const link = "http://petlatkea.dk/2019/hogwarts/students.json";
const bloodLink = "http://petlatkea.dk/2019/hogwarts/families.json";

//ARRAYS
let allStudents = new Array();
let halfBloods = new Array();
let pureBloods = new Array();
window.addEventListener("DOMContentLoaded", init());

function init() {
  loadJSON();
}

function loadJSON() {
  fetch(link)
    .then(res => res.json())
    .then(jsonData => {
      prepareObjects(jsonData);
      showStudents();
    });
  fetch(bloodLink)
    .then(res => res.json())
    .then(jsonBloodData => {
      makeArrays(jsonBloodData);
    });
}

// CREATE STUDENT OBJECT WITH DATA
function prepareObjects(jsonData) {
  jsonData.forEach(jsonObject => {
    //create new object
    let student = Object.create(jsonObject);
    //split name into parts
    let nameParts = jsonObject.fullname.split(" ");
    //assign parts to the student object
    student.firstname = nameParts[0];
    student.lastname = nameParts[nameParts.length - 1];
    student.house = student.house;
    student.imageSource =
      student.lastname.toLowerCase() +
      "_" +
      student.firstname.slice(0, 1).toLowerCase() +
      ".png";
    student.id = uuidv4();
    student.fullname = student.fullname;
    allStudents.push(student);
  });
  setTimeout(function(){
     checkTheBlood();

     }, 300);
}


// CREATE BLOOD CLASS ARRAYS
function makeArrays(data) {

  for (let i = 0; i < data.half.length; i++) {
    halfBloods.push(data.half[i]);
  }
  for (let j = 0; j < data.pure.length; j++) {
    pureBloods.push(data.pure[j]);
  }

}
// CHECK FOR BLOODTYPE AND ADD KEYVALUE
function checkTheBlood() {
  allStudents.forEach(obj => {
    if (halfBloods.includes(obj.lastname)) {
      obj.bloodtype = "half";
    } else if (pureBloods.includes(obj.lastname)) {
      obj.bloodtype = "pure"
    } else {
      obj.bloodtype = "muggle"
    };
  })
}

Here is the whole code: https://jsfiddle.net/bus5ef6p/1/


Solution

  • change your loadJSON function to

    function loadJSON() {
      fetch(link)
        .then(res => res.json())
        .then(jsonData => {
    
          fetch(bloodLink)
          .then(res1 => res1.json())
          .then(jsonBloodData => {
            makeArrays(jsonBloodData);
            prepareObjects(jsonData);
            showStudents();
          });
        });
    }
    

    and remove timeout from prepareObjects function.