Function to parse a Javascript object and return a CSV

This function converts a Javascript Object into a CSV.

var dataFromAPI = [{"name":"first"},{"name":"sec,ond"},{"name":"third 'jibberish"},{"name":"fourth, jibberish"}]

var csvOutput = "";
Object.keys(objArray).forEach(function(key) {
if (csvOutput.length == 0) {
csvOutput = "Index,Field Value\n";
csvOutput = csvOutput + JSON.stringify(key) + "," + JSON.stringify(objArray[key]["name"]) + "\n";
} else {
csvOutput = csvOutput + JSON.stringify(key) + "," + JSON.stringify(objArray[key]["name"]) + "\n";
}
})
return csvOutput;
}

console.log(convertToCSVandDownload(dataFromAPI));

Description

It would appear that your current solution is a bit complicated. Using JSON.parse just to ensure that you escape , is overkill.

The overall solution can be drastically simplified as you will see in this post.

const before let and let before var

All variables should be declared by default with const. If a variable is going to be mutated then use let. Don't use var unless that is what you intended.

/// bad
var dataFromAPI = ...

/// good
const dataFromAPI = ...


note: pushing an element to a list will only mutate the array and not the variable, thus no error

Work with arrays and not with strings.

/// bad
csvOutput = "Index,Field Value\n";

/// good
const csvOutput = [
["Index", "Field", "Value"]
];


Function names should describe what they do.

The convertToCSVandDownload method only converts to CSV but doesn't download. Change the name to convertToCSV

Working Solution

const dataFromAPI = [{"name":"first"},{"name":"sec,ond"},{"name":"third 'jibberish"},{"name":"fourth, jibberish"}]

function convertToCSV(data, headers) {
return data
.reduce((a,{name},i)=>[...a, [i, "\${name}"]], [headers])
.map(row=>row.join(","))
.join("\n");
}

const res = convertToCSV(dataFromAPI, ["Index", "Field Value"]);

console.log(res)

I'd like to propose a solution using flatMap. Be aware that this is definitely not a cross-browser solution.

Let's create a function that given n arguments returns a CSV line:

const row = (...args) => args.map(JSON.stringify).join(',');

console.log(row('foo'));
console.log(row('foo', 'bar'));
console.log(row('foo', 'bar', 'baz'));

Then let's use flatMap to append (or prepend) stuff while we map over an array. e.g.:

const pair = arr => arr.flatMap(n => [n, n]);

console.log(pair([1]));
console.log(pair([1, 2]));
console.log(pair([1, 2, 3]));

As you can see we can use flatMap to "add" more items as we iterate. Let's use this to add the headers during the first iteration.

Complete solution

const dataFromAPI = [
{"name": "first"},
{"name": "sec,ond"},
{"name": "third 'jibberish"},
{"name": "fourth, jibberish"}];

const row = (...args) => args.map(JSON.stringify).join(',');

const csv =
dataFromAPI
.flatMap((obj, idx) =>
idx === 0 ?
[row('Index', 'Field Value'), row(idx, obj.name)] :
[row(idx, obj.name)])
.join('\n');

console.log(csv);

Skimming through your code I believe ya may not need that if/else check within the .forEach loop...

var dataFromAPI = [{"name":"first"},{"name":"sec,ond"},{"name":"third 'jibberish"},{"name":"fourth, jibberish"}]

var csvOutput = "Index,Field Value\n";
Object.keys(objArray).forEach(function(key) {
csvOutput = csvOutput + JSON.stringify(key) + "," + JSON.stringify(objArray[key]["name"]) + "\n";
})
return csvOutput;
}



... and one thing that might be an improvement may be allowing for converting other target_keys...

var dataFromAPI = [{"name":"first"},{"name":"sec,ond"},{"name":"third 'jibberish"},{"name":"fourth, jibberish"}]

var csvOutput = "Index,Field Value\n";
Object.keys(objArray).forEach(function(i) {
csvOutput += JSON.stringify(i) + "," + JSON.stringify(objArray[i][target_key]) + "\n";
})
return csvOutput;
}


... other than those two things I think you code is good, and the only other thing ya might want to consider is what ya want to do with data structures that have more layers than dataFromAPI
• The urbandictionary says something like "Term for "yes" used in Jamaica", but that is just something that I read online somewhere. Personally I use it for that as well as a less direct form of you, eg. "ya ya could do that', which when spoken would have a more uh like sound on the second ya. Jun 18 '19 at 18:43