I try to load contents of the CSV file into the array of JavaScript objects. Unfortunately, structure of data is not flat, so to mitigate that, I use dot-separated property names as column headers in CSV file. Example CSV file looks as follows:
codes.code1,codes.code2,codes.code3,codes.code4,info.description.text,info.description.language
49074202,64,1443,1416,Test description: 49074202 64 1443 1416,EN
81905948,10,9721,5411,Test description: 81905948 10 9721 5411,EN
87262350,86,7050,4775,Test description: 87262350 86 7050 4775,EN
The object structure I would like to end up with looks like
{
codes: {
code1: "49074202",
code2: "64",
code3: "1443",
code4: "1416"
},
info: {
description: {
text: "Test description: 49074202 64 1443 1416",
language: "EN"
}
}
}
Following code can be used to recreate the problem (using CSV file with contents posted above).
<html>
<body>
<form>
<input type="file" id="files" onchange="loadFromFile()" />
<script>
function loadFromFile() {
var selectedFile = document.getElementById('files').files[0];
var reader = new FileReader();
reader.onload = loadRowsFromFile;
reader.readAsText(selectedFile);
};
function loadRowsFromFile(e) {
var rows = e.target.result.split("\n");
if (!rows || rows.length === 0) {
return;
}
var headers = rows[0].split(",");
var loadedData = [];
for (var i = 1; i < rows.length; i++) {
var columns = rows[i].split(",");
var rowData = {};
for (var j = 0; j < headers.length; j++) {
placeElementInHierarchy(rowData, headers[j], columns[j]);
}
loadedData.push(rowData);
}
console.log(loadedData);
}
function placeElementInHierarchy(rowData, propertyPath, value) {
var path = propertyPath.split(".");
var obj = rowData;
for (var i = 0; i < path.length; i++) {
if (i === path.length - 1) {
obj[path[i]] = value;
} else {
if (!obj[path[i]]) {
obj[path[i]] = {};
}
obj = obj[path[i]];
}
}
}
</script>
</form>
</body>
</html>
File parsing works properly, data is loaded correctly into the structure. However, for some reason the last processed property name is quoted. Structure of all rows I obtain looks like that:
{
codes: {
code1: "49074202",
code2: "64",
code3: "1443",
code4: "1416"
},
info: {
description:{
text: "Test description: 49074202 64 1443 1416",
"language": "EN"
}
}
}
The only lead I have right now is that if I remove the 'language' column from CSV file, then 'text' is being quoted instead - so the last processed property is for some reason quoted. Thanks in advance!
EDIT: Fixed mistakes in the expected structure.
EDIT2: What is interesting, following code (skipping file upload part), doesn't show such symptoms
<html>
<body>
<form>
<script>
(function() {
var csvData = 'codes.code1,codes.code2,codes.code3,codes.code4,info.description.text,info.description.language\n' +
'49074202,64,1443,1416,Test description: 49074202 64 1443 1416,EN\n' +
'81905948,10,9721,5411,Test description: 81905948 10 9721 5411,EN\n' +
'87262350,86,7050,4775,Test description: 87262350 86 7050 4775,EN';
loadRowsFromFile(csvData);
})();
function loadRowsFromFile(csvData) {
var rows = csvData.split("\n");
if (!rows || rows.length === 0) {
return;
}
var headers = rows[0].split(",");
var loadedData = [];
for (var i = 1; i < rows.length; i++) {
var columns = rows[i].split(",");
var rowData = {};
for (var j = 0; j < headers.length; j++) {
placeElementInHierarchy(rowData, headers[j], columns[j]);
}
loadedData.push(rowData);
}
console.log(loadedData);
}
function placeElementInHierarchy(rowData, propertyPath, value) {
var path = propertyPath.split(".");
var obj = rowData;
for (var i = 0; i < path.length; i++) {
if (i === path.length - 1) {
obj[path[i]] = value;
} else {
if (!obj[path[i]]) {
obj[path[i]] = {};
}
obj = obj[path[i]];
}
}
}
</script>
</form>
</body>
</html>