parse line-separated json objects in html table - javascript

I can't change json format. The data store in new line.
json file:
{"ProgMode":"on","wait_h":"5","wait_m":"5","output":"1"}
{"ProgMode":"off","wait_h":"10","wait_m":"10","output":"2"}
I using below code but without bracket ([]) in json file, it doesn't work.
var ReqJson = new XMLHttpRequest();
function response(){
if(this.readyState == 4 && this.status == 200){
var myObj = JSON.parse(this.responseText);
const dbParam = JSON.stringify({table:"ProgramView",limit:20});
let text = "<table class='table my-0'>"
for (let x in myObj) {
text += '<tr><td>' + myObj[x].wait_h + ':' + myObj[x].wait_m + ':' + myObj[x].output + '</td></tr>';
}
text += "</table>"
document.getElementById("dynamic_table").innerHTML = text;
}
}
function ProccessConfig(){
ReqJson.open("POST", "Programs.json", true);
ReqJson.onreadystatechange = response;
ReqJson.send()
}
ProccessConfig();
So how can I parse json that is stored with new lines and without comma and brackets?

You can split the input text in rows and then 'JSON.parse' the single row.
let myObj = this.responseText.split('\n')
.filter(line => line !== "")
.map(JSON.parse);
Example based on your string:
let text = `{"ProgMode":"on","wait_h":"5","wait_m":"5","output":"1"}
{"ProgMode":"off","wait_h":"10","wait_m":"10","output":"2"}
`
let myObj = text.split('\n')
.filter(line => line !== "")
.map(JSON.parse);
console.log(myObj)

you don't need to split and map, it is to heavy for this case, try this
var myObj = JSON.parse(`[${this.responseText.replaceAll("}\n","},")}]`);
this is a little more complicated, but much more reliable,since it is not using any special symbols
var myObj = JSON.parse(`[{${this.responseText.substring(1).replaceAll("{",",{")}]`);

Related

I am getting error while Regex replace javascript

var newInput = '{"id":"1","value":"Admin","prefix":"#"} asdas {"id":"24","value":"Ibiere Banigo","prefix":"#"}';
var gettingJson = newInput.match(/\{\"(.*?)\"\}/g);
var finalString = '';
$.each(gettingJson, function (index, value) {
var data = JSON.parse(value);
finalString = newInput.replace(/\{\"(.*?)\"\}/g, '#[' + data.id + ']');
});
console.log(finalString);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
This is my code I am trying to replace this the parenthesis with #[id] it is replacing it but for all like I want my output to be
#[1] someone new #[2]
but instead I am getting
#[2] someone new #[2]
Problem
The problem with your approach is the replace method replaces all matching occurrences.
Solution
Use replace method callback
replace(regexp, replacerFunction)
var newInput = '{"id":"1","value":"Admin","prefix":"#"} asdas {"id":"24","value":"Ibiere Banigo","prefix":"#"}';
var finalString = newInput.replace(/\{\"(.*?)\"\}/g, match => {
var data = JSON.parse(match);
return '#[' + data.id + ']'
})
console.log(finalString);

Issue with converting a function from ES6 to vanilla JavaScript to work in Internet Explorer

I created a Directory Search using regex to match the input to the data. I followed a tutorial for half of it and added to it on my own. It is working in Chrome, but not Internet Explorer.
I figured out this is due to ES6 incompatibilities in Internet Explorer and now I am having trouble figuring out how to correctly convert my displayMatches function to vanilla javascript or jQuery with no ES6.
So far most of it is working except that I can't figure how to remove the commas in in my html for the list of matches even though I tried using .join('')
Screenshot #1
Screenshot #2 - see the commas in between?
This is the working code on Chrome:
function displayMatches() {
// console.log(this.value);
$('.suggestions').show();
var matchArray = findMatches(this.value, employees);
console.log(matchArray);
var html = matchArray.slice(0,10).map(person => {
var regex = new RegExp(this.value, 'gi');
var firstName = person.GivenName.replace(regex, `<span class="hl">${this.value}</span>`);
var lastName = person.Surname.replace(regex, `<span class="hl">${this.value}</span>`);
var extension;
if (person.Phone_Ext1 !== null){
extension = person.Phone_Ext1;
} else {extension = "N/A"}
return `
<li class="search-item" data-id=${person.EmployeeID}>
<span class="person">${firstName} ${lastName}</span>
<span class="phone-ext">Ext. ${extension}</span>
</li>
`
}).join('');
if ($('#search-box').val() == ""){
suggestions.innerHTML = "";
} else {
suggestions.innerHTML = html;
}
}
And this is my attempt to convert:
function displayMatches() {
// console.log(this.value);
$('.suggestions').show();
var matchArray = findMatches(this.value, employees);
console.log(matchArray);
var html = [];
var person;
var list;
for(var i=0; i < matchArray.slice(0,10).length; i++){
person = matchArray.slice(0,10)[i];
var regex = new RegExp(this.value, 'gi');
var hilight = '<span class="hl">' + this.value + '</span>';
var firstName = person.GivenName.replace(regex, hilight);
var lastName = person.Surname.replace(regex, hilight);
var extension;
if (person.Phone_Ext1 !== null){
extension = person.Phone_Ext1;
} else {
extension = "N/A"
}
list =
'<li class="search-item" data-id=' + person.EmployeeID +'>' +
'<span class="person">' + firstName + ' ' + lastName + '</span>' +
'<span class="phone-ext">Ext. ' + extension + '</span>' +
'</li>';
html.push(list);
}
html.join('');
console.log(html);
if ($('#search-box').val() == ""){
suggestions.innerHTML = "";
} else {
suggestions.innerHTML = html;
}
}
html.join('') returns a new string. It doesn't transmogrify the array to a string, it doesn't assign a new value to the html variable. You would need to do
html = html.join('');
or even better use two separate variables, one of the array and one for the string.
Btw, you don't even need to construct and fill the array yourself in a loop, you can use the ES5 Array map method since IE9. As #H.B. remarked in the comments, you only need to use a function expression instead of the arrow syntax.

Passing an object by it's name through HTML to javascript

It's a pretty simple question and I'm going insane over here googling this all around and getting all these insanely non related answers.
here is the code:
function Banana(boja, duzina) {
this.boja = boja;
this.duzina = duzina;
}
var zut = new Banana("zuta", 12);
function fja(obj) {
var rez = "";
for (var key in obj)
var rez += key + " = "
obj.key + "<br/>";
document.getElementById('div1').innerHTML = rez;
}
<button onclick="fja();">klikni</button>
<div id='div1'>xd</div>
Is it possible to pass an instance of an object "zut" to this function through HTML? If yes,how,if not,how am I supposed to do it through JS?
I want div1 html to be turned into:
boja = zuta
duzina = 12
thanks for answers
function Banana(boja, duzina) {
this.boja = boja;
this.duzina = duzina;
}
var zut = new Banana("zuta", 12);
function fja(obj) {
var rez = "";
for (var key in obj)
rez += key + " = "+ obj[key] + "<br/>";
document.getElementById('div1').innerHTML = rez;
}
<button onclick="fja(zut);">klikni</button>
<div id='div1'>xd</div>
You certainly can, although why your code doesn't work is because
1) - You're re declaring the variable rezand assigning to it using += which is no valid.
2) - obj.key is not valid, because there no such property called key, To access it you need to use brackets obj[key] nowkey will be considered as a variable and it's value will be used to get the property's value.
3) - You missed a + in this line var rez += key + " = " (HERE) obj.key + "<br/>";
4) - Your call to the method in the html is missing the argument.
you can either use onclick="fja(new Banana('zuta', 12));
Or declare the object inline in the HTML, or declare it in the js and pass it name
//in the Js
var zut = new Banana("zuta", 12);
//in the HTML
onclick="fja(zut);
Example one
function Banana(boja, duzina) {
this.boja = boja;
this.duzina = duzina;
}
function fja(obj) {
var rez = "";
for (var key in obj)
rez += key + " = " + obj[key] + "<br/>";
document.getElementById('div1').innerHTML = rez;
}
<button onclick="fja(new Banana('zuta', 12));">klikni</button>
<div id='div1'>xd</div>
Example Two
function Banana(boja, duzina) {
this.boja = boja;
this.duzina = duzina;
}
var zut = new Banana("zuta", 12);
function fja(obj) {
var rez = "";
for (var key in obj)
rez += key + " = " + obj[key] + "<br/>";
document.getElementById('div1').innerHTML = rez;
}
<button onclick="fja(zut);">klikni</button>
<div id='div1'>xd</div>

Cant load this JSON into my table

I 've got a simple thing:
There's a JSON with books objects,every book has a title,author and year.
I would like to choose one option from the list and display chosen property in a table.I've used an example from W3 but right now i'm stuck and nothing works as it should...
Link's here
function change_myselect(sel) {
var obj, dbParam, xmlhttp, myObj, x, txt = "";
obj = { "table":sel, "limit":20 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
txt += "<table border='1'>"
for (x in myObj) {
txt += "<tr><td>" + myObj[x].name + "</td></tr>";
}
txt += "</table>"
document.getElementById("demo").innerHTML = txt;
}
};
xmlhttp.open("GET", "generated.json", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
}
The problem is quite easy to spot with a debugger line
console.log(myObj)
It is an object and you are trying to loop over it. You want to be looping over the key in the object that holds the array.
console.log(myObj.books);
You are iterating over a single property books in an object instead of iterating over the array that property contains.
Instead of this:
for (x in myObj) {
txt += "<tr><td>" + myObj[x].name + "</td></tr>";
}
try something like this:
myObj.books.forEach((book) => {
txt += "<tr><td>" + book[sel.toLowerCase()] + "</td></tr>";
});

Using javascript to download file as a.csv file

I am trying to export a file as .csv file so that when the user clicks on the download button, the browser would automatically download the file as .csv.
I also want to be able to set a name for the .csv file to be exported
I am using javascript to do this
The code is below:
function ConvertToCSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';
for (var i = 0; i < array.length; i++) {
var line = '';
for (var index in array[i]) {
if (line != '') line += ','
line += array[i][index];
}
str += line + '\r\n';
}
return str;
}
// Example
$(document).ready(function () {
// Create Object
var items = [
{ "name": "Item 1", "color": "Green", "size": "X-Large" },
{ "name": "Item 2", "color": "Green", "size": "X-Large" },
{ "name": "Item 3", "color": "Green", "size": "X-Large" }];
// Convert Object to JSON
var jsonObject = JSON.stringify(items);
// Display JSON
$('#json').text(jsonObject);
// Convert JSON to CSV & Display CSV
$('#csv').text(ConvertToCSV(jsonObject));
$("#download").click(function() {
alert("2");
var csv = ConvertToCSV(jsonObject);
window.open("data:text/csv;charset=utf-8," + escape(csv))
///////
});
});
I have written a solution in this thread: How to set a file name using window.open
This is the simple solution:
$("#download_1").click(function() {
var json_pre = '[{"Id":1,"UserName":"Sam Smith"},{"Id":2,"UserName":"Fred Frankly"},{"Id":1,"UserName":"Zachary Zupers"}]';
var json = $.parseJSON(json_pre);
var csv = JSON2CSV(json);
var downloadLink = document.createElement("a");
var blob = new Blob(["\ufeff", csv]);
var url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.download = "data.csv";
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
});
JSON2CSV function:
function JSON2CSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';
var line = '';
if ($("#labels").is(':checked')) {
var head = array[0];
if ($("#quote").is(':checked')) {
for (var index in array[0]) {
var value = index + "";
line += '"' + value.replace(/"/g, '""') + '",';
}
} else {
for (var index in array[0]) {
line += index + ',';
}
}
line = line.slice(0, -1);
str += line + '\r\n';
}
for (var i = 0; i < array.length; i++) {
var line = '';
if ($("#quote").is(':checked')) {
for (var index in array[i]) {
var value = array[i][index] + "";
line += '"' + value.replace(/"/g, '""') + '",';
}
} else {
for (var index in array[i]) {
line += array[i][index] + ',';
}
}
line = line.slice(0, -1);
str += line + '\r\n';
}
return str;
}
in modern browsers there is a new attribute in anchors.
download
http://caniuse.com/download
so instead of using
window.open("data:text/csv;charset=utf-8," + escape(csv))
create a download link:
download
another solution is to use php
EDIT
i don't use jQuery, but you need to edit your code to add the download link
with something like that in your function.
var csv=ConvertToCSV(jsonObject),
a=document.createElement('a');
a.textContent='download';
a.download="myFileName.csv";
a.href='data:text/csv;charset=utf-8,'+escape(csv);
document.body.appendChild(a);
Try these Examples:
Example 1:
JsonArray = [{
"AccountNumber": "1234",
"AccountName": "abc",
"port": "All",
"source": "sg-a78c04f8"
}, {
"Account Number": "1234",
"Account Name": "abc",
"port": 22,
"source": "0.0.0.0/0",
}]
JsonFields = ["Account Number","Account Name","port","source"]
function JsonToCSV(){
var csvStr = JsonFields.join(",") + "\n";
JsonArray.forEach(element => {
AccountNumber = element.AccountNumber;
AccountName = element.AccountName;
port = element.port
source = element.source
csvStr += AccountNumber + ',' + AccountName + ',' + port + ',' + source + "\n";
})
return csvStr;
}
You can download the csv file using the following code :
function downloadCSV(csvStr) {
var hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvStr);
hiddenElement.target = '_blank';
hiddenElement.download = 'output.csv';
hiddenElement.click();
}
I just wanted to add some code here for people in the future since I was trying to export JSON to a CSV document and download it.
I use $.getJSON to pull json data from an external page, but if you have a basic array, you can just use that.
This uses Christian Landgren's code to create the csv data.
$(document).ready(function() {
var JSONData = $.getJSON("GetJsonData.php", function(data) {
var items = data;
const replacer = (key, value) => value === null ? '' : value; // specify how you want to handle null values here
const header = Object.keys(items[0]);
let csv = items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','));
csv.unshift(header.join(','));
csv = csv.join('\r\n');
//Download the file as CSV
var downloadLink = document.createElement("a");
var blob = new Blob(["\ufeff", csv]);
var url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.download = "DataDump.csv"; //Name the file here
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
});
});
Edit: It's worth noting that JSON.stringify will escape quotes in quotes by adding \". If you view the CSV in excel, it doesn't like that as an escape character.
You can add .replace(/\\"/g, '""') to the end of JSON.stringify(row[fieldName], replacer) to display this properly in excel (this will replace \" with "" which is what excel prefers).
Full Line: JSON.stringify(row[fieldName], replacer).replace(/\\"/g, '""')
One-liner function for simple JSON with static titles
Assuming arr is JSON array, you can also replace the first string with comma separated titles end with \n
arr.reduce((acc, curr) => (`${acc}${Object.values(curr).join(",")}\n`), "")
Or with the window.open function mentioned before
window.open(`data:text/csv;charset=utf-8,${arr.reduce((acc, curr) => (`${acc}${Object.values(curr).join(",")}\n`), "")}`)
You should also consider escape the strings or replace the , to avoid extra cells
If your data comes from a SQL Database, all your lines should have the same structure, but if coming from a NoSQL Database you could have trouble using standard answers. I elaborated on above JSON2CSV for such a scenario.
Json data example
[ {"meal":2387,"food":"beaf"},
{"meal":2387,"food":"apple","peeled":"yes", "speed":"fast" },
{"meal":2387,"food":"pear", "speed":"slow", "peeled":"yes" } ]
Answer
"meal","food","peeled","speed"
"2387","beaf","",""
"2387","apple","yes","fast"
"2387","pear","yes","slow"
Code for headers and double quotes for simplicity.
function JSON2CSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';
var line = '';
// get all distinct keys
let titles = [];
for (var i = 0; i < array.length; i++) {
let obj = array[i];
Object.entries(obj).forEach(([key,value])=>{
//console.log('key=', key, " val=", value );
if (titles.includes(key) ) {
// console.log (key , 'exists');
null;
}
else {
titles.push(key);
}
})
}
let htext = '"' + titles.join('","') + '"';
console.log('header:', htext);
// add to str
str += htext + '\r\n';
//
// lines
for (var i = 0; i < array.length; i++) {
var line = '';
// get values by header order
for (var j = 0; j < titles.length; j++) {
// match keys with current header
let obj = array[i];
let keyfound = 0;
// each key/value pair
Object.entries(obj).forEach(([key,value])=>{
if (key == titles[j]) {
// console.log('equal tit=', titles[j] , ' e key ', key ); // matched key with header
line += ',"' + value + '"';
keyfound = 1;
return false;
}
})
if (keyfound == 0) {
line += ',"' + '"'; // add null value for this key
} // end loop of header values
}
str += line.slice(1) + '\r\n';
}
return str;
}

Categories

Resources