I don't wish to use JQuery, just to put that upfront.
I have a template for data. This template will be used for rendering fields of data (or not as the case may be). I've sorted out the matching part of the objects. The problem I have is when it comes to iterating over the array of objects, and matching said objects to the template. The results I get all have the same value as the last object in the incoming array.
//template
//actual template/incoming data is much more than this, but im keeping it a simple example
const template = {"firstname":null, "lastname":null, "dob":null}
//incoming (from a fileupload, but i will put it here an example)
const incoming = [{"firstname":"John", "dob":"1996-04-03"},
{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"}]
function readFile() { // function read the files from upload
const fileIn = document.querySelector('#file-input'); //finds the input area in the form
var reader = new FileReader();
reader.onload = onReaderLoad;
reader.readAsText(filein.files[0]); //gets the uploaded json file
};
function onReaderLoad(event) {
const obj = JSON.parse(event.target.result); //parse the uploaded file
const matched = []; //empty array to push matched objects to
obj.forEach(el => {
//i left this function out of this example because it works as expected, returns 1 object
matched.push(cleanData(el)); //call the function that matches the template and incoming
});
console.log(matched)
};
document.getElementById('file-input).addEventListener('change', onChange);
when I this, the result puts out a 2-item array with all results matching the data of the "Jill" object.
[{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"},
{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"}]
what I am expecting is:
[{"firstname":"John", "lastname":null, "dob":"1996-04-03"},
{"firstname":"Jill", "lastname":"Smith", "dob":"1986-09-17"}]
My expectation, is that in the forEach
call, it should push a new object with matched fields to the empty matched
array, however, it doesn't appear to be working that way. Am I misunderstanding something? I come from a python background, so javascript isn't my first language and I tend to think with a python brain.
this is the cleanData()
function:
function cleanData(d1, d2=template) {
let _copy = Object.assign({}, d2) //makes a copy
const commonKeys = getKeys(d1, _copy) //returns a list of keys found in both
commonKeys.forEach(element => {
//is it an object, but not array?
if((d1[element] instanceof Object) && (Array.isArray(d1[element]))){
const subKeys = getKeys(d1[element], _copy[element]);
subKeys.forEach(el => {
_copy[element][el] = d1[element][el];});
}else if(Array.isArray(d1[element])){ //is it an array?
var objList = [];
for(var i=0; i<d1[element].length; ++i){
if((d1[element] instanceof Object) && (Array.isArray(d1[element]))){
const temp=d1[element][i];
//array in _copy will always be length 0
const temp_fix = cleanData(temp, _copy[element][0])
objList.push(temp_fix);
_copy[element] = objList;
}else { _copy[element] = d1[element]}
}
} else { //if not array or obj
_copy[element] = d1[element]
}
});
return _copy;
}