Parsing a string with different separators - javascript

I am creating a parser that has mostly similar lines of data but not entirely the same.
This is javascript code I am writing for those asking.
For instance this line:
[16/Nov/2022:12:00:36.523 -0800] BIND RESULT threadID=8 conn=641870 op=11958 msgID=11959 version="3" dn="cn=Directory Manager" authType="SIMPLE" resultCode=0 resultCodeName="Success" qtime=0 etime=0.185 authDN="cn=LDAP Root,cn=Root DNs,cn=config" clientConnectionPolicy="default"
I originally thought spliting the string based on the " " as a separater worked up until I go to the authDN=... section of the string. It is separating the LDAP from Root and creating 2 entries.
Does anyone know how I can create a parser method to successfully separate these key=value pairs when some of the have ' ' in the value section.
Thank you for anyone help.
My code:
data=str.split(" ");
for (x in data){
switch (x){
case 0:
TimeStamp=data\[x\] + " " + data\[x+1\];
break;
case 1:
break;
case 2:
entryType=data\[x\] + " " + data\[x+1\];
break;
case 3:
break;
default:
entry.setAttribute(data\[x\].toString().split('=')\[0\],data\[x\].toString().split('=')\[1\]);
break;
}
}
When I get to authDN="cn=Directory Manager,cn=Root DNs,cn=config" I am getting 'authDN="cn=Directory' and then 'Manager,cn=Root' and finally 'DNs'

This code should work:
function parseBindResult(line) {
var isInQuote = false;
var quote = "";
var quoteKey = ""
var result = {};
for (let i = 0; i < line.length; i++) {
if (isInQuote) {
if (line[i] == '"') {
isInQuote = false
result[quoteKey] = quote.replace('"', '')
quote = "";
continue;
}
quote += line[i];
continue;
}
// if the letter is an "=", everything from a \s to the "=" is the key, and everything from the "=" to the next \s is the value.
if (line[i] === "=") {
// the key is everything from the last \s to the "="
var key = line.substring(line.lastIndexOf(" ", i) !== -1 ? line.lastIndexOf(" ", i) : 0, i).trim()
// the value is everything from the "=" to the next \s
var value = line.substring(i + 1, line.indexOf(" ", i) !== -1 ? line.indexOf(" ", i) : line.length).trim();
// if the value is in quotes, it's a nested object
if (line[i + 1] === '"') {
i++;
isInQuote = true;
quoteKey = key;
continue;
}
result[key] = value;
}
}
return result;
}
{
threadID: '8',
conn: '641870',
op: '11958',
msgID: '11959',
version: '3',
dn: 'cn=Directory Manager',
authType: 'SIMPLE',
resultCode: '0',
resultCodeName: 'Success',
qtime: '0',
etime: '0.185',
authDN: 'cn=LDAP Root,cn=Root DNs,cn=config',
clientConnectionPolicy: 'default'
}
If you want to use sub-objects, then this code will work:
function parseBindResult(line, seperator = " ") {
var isInQuote = false;
var quote = "";
var quoteKey = ""
var result = {};
for (let i = 0; i < line.length; i++) {
if (isInQuote) {
if (line[i] == '"') {
isInQuote = false
result[quoteKey] = parseBindResult(quote.replace('"', ''), ",");
quote = "";
continue;
}
quote += line[i];
continue;
}
// if the letter is an "=", everything from a \s to the "=" is the key, and everything from the "=" to the next \s is the value.
if (line[i] === "=") {
// the key is everything from the last \s to the "="
var key = line.substring(line.lastIndexOf(seperator, i) !== -1 ? line.lastIndexOf(seperator, i) : 0, i).replace(new RegExp(`${seperator}*$`), '').replace(new RegExp(`^${seperator}*`), '')
// the value is everything from the "=" to the next \s
var value = line.substring(i + 1, line.indexOf(seperator, i) !== -1 ? line.indexOf(seperator, i) : line.length).replace(new RegExp(`${seperator}*$`), '').replace(new RegExp(`^${seperator}*`), '')
// if the value is in quotes, it's a nested object
if (line[i + 1] === '"') {
i++;
isInQuote = true;
quoteKey = key;
continue;
}
result[key] = value;
}
}
return result;
}
{
threadID: '8',
conn: '641870',
op: '11958',
msgID: '11959',
version: {},
dn: { cn: 'Directory Manager' },
authType: {},
resultCode: '0',
resultCodeName: {},
qtime: '0',
etime: '0.185',
authDN: { cn: 'config' }, // It will overwrite anything with multiple instances of the same key
clientConnectionPolicy: {}
}

Related

How to output json prettry formt as html using javascript? [duplicate]

How can I display JSON in an easy-to-read (for human readers) format? I'm looking primarily for indentation and whitespace, with perhaps even colors / font-styles / etc.
Pretty-printing is implemented natively in JSON.stringify(). The third argument enables pretty printing and sets the spacing to use:
var str = JSON.stringify(obj, null, 2); // spacing level = 2
If you need syntax highlighting, you might use some regex magic like so:
function syntaxHighlight(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, 2);
}
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
See in action here: jsfiddle
Or a full snippet provided below:
function output(inp) {
document.body.appendChild(document.createElement('pre')).innerHTML = inp;
}
function syntaxHighlight(json) {
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
var obj = {a:1, 'b':'foo', c:[false,'false',null, 'null', {d:{e:1.3e5,f:'1.3e5'}}]};
var str = JSON.stringify(obj, undefined, 4);
output(str);
output(syntaxHighlight(str));
pre {outline: 1px solid #ccc; padding: 5px; margin: 5px; }
.string { color: green; }
.number { color: darkorange; }
.boolean { color: blue; }
.null { color: magenta; }
.key { color: red; }
User Pumbaa80's answer is great if you have an object you want pretty printed. If you're starting from a valid JSON string that you want to pretty printed, you need to convert it to an object first:
var jsonString = '{"some":"json"}';
var jsonPretty = JSON.stringify(JSON.parse(jsonString),null,2);
This builds a JSON object from the string, and then converts it back to a string using JSON stringify's pretty print.
Better way.
Prettify JSON Array in Javascript
JSON.stringify(jsonobj,null,'\t')
var jsonObj = {"streetLabel": "Avenue Anatole France", "city": "Paris 07", "postalCode": "75007", "countryCode": "FRA", "countryLabel": "France" };
document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj);
In case of displaying in HTML, you should to add a balise <pre></pre>
document.getElementById("result-after").innerHTML = "<pre>"+JSON.stringify(jsonObj,undefined, 2) +"</pre>"
Example:
var jsonObj = {"streetLabel": "Avenue Anatole France", "city": "Paris 07", "postalCode": "75007", "countryCode": "FRA", "countryLabel": "France" };
document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj);
document.getElementById("result-after").innerHTML = "<pre>"+JSON.stringify(jsonObj,undefined, 2) +"</pre>"
div { float:left; clear:both; margin: 1em 0; }
<div id="result-before"></div>
<div id="result-after"></div>
Based on Pumbaa80's answer I have modified the code to use the console.log colours (working on Chrome for sure) and not HTML. Output can be seen inside console. You can edit the _variables inside the function adding some more styling.
function JSONstringify(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, '\t');
}
var
arr = [],
_string = 'color:green',
_number = 'color:darkorange',
_boolean = 'color:blue',
_null = 'color:magenta',
_key = 'color:red';
json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var style = _number;
if (/^"/.test(match)) {
if (/:$/.test(match)) {
style = _key;
} else {
style = _string;
}
} else if (/true|false/.test(match)) {
style = _boolean;
} else if (/null/.test(match)) {
style = _null;
}
arr.push(style);
arr.push('');
return '%c' + match + '%c';
});
arr.unshift(json);
console.log.apply(console, arr);
}
Here is a bookmarklet you can use:
javascript:function JSONstringify(json) {if (typeof json != 'string') {json = JSON.stringify(json, undefined, '\t');}var arr = [],_string = 'color:green',_number = 'color:darkorange',_boolean = 'color:blue',_null = 'color:magenta',_key = 'color:red';json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {var style = _number;if (/^"/.test(match)) {if (/:$/.test(match)) {style = _key;} else {style = _string;}} else if (/true|false/.test(match)) {style = _boolean;} else if (/null/.test(match)) {style = _null;}arr.push(style);arr.push('');return '%c' + match + '%c';});arr.unshift(json);console.log.apply(console, arr);};void(0);
Usage:
var obj = {a:1, 'b':'foo', c:[false,null, {d:{e:1.3e5}}]};
JSONstringify(obj);
Edit: I just tried to escape the % symbol with this line, after the variables declaration:
json = json.replace(/%/g, '%%');
But I find out that Chrome is not supporting % escaping in the console. Strange... Maybe this will work in the future.
Cheers!
I think you're looking for something like this :
JSON.stringify(obj, null, '\t');
This "pretty-prints" your JSON string, using a tab for indentation.
If you prefer to use spaces instead of tabs, you could also use a number for the number of spaces you'd like :
JSON.stringify(obj, null, 2);
You can use console.dir(), which is a shortcut for console.log(util.inspect()).
(The only difference is that it bypasses any custom inspect() function defined on an object.)
It uses syntax-highlighting, smart indentation, removes quotes from keys and just makes the output as pretty as it gets.
const object = JSON.parse(jsonString)
console.dir(object, {depth: null, colors: true})
and for the command line:
cat package.json | node -e "process.stdin.pipe(new stream.Writable({write: chunk => console.dir(JSON.parse(chunk), {depth: null, colors: true})}))"
I use the JSONView Chrome extension (it is as pretty as it gets :):
Edit: added jsonreport.js
I've also released an online stand-alone JSON pretty print viewer, jsonreport.js, that provides a human readable HTML5 report you can use to view any JSON data.
You can read more about the format in New JavaScript HTML5 Report Format.
If you are using ES5, simply call JSON.stringify with:
2nd arg: replacer; set to null,
3rd arg: space; use tab.
JSON.stringify(anObject, null, '\t');
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
Here's user123444555621's awesome HTML one adapted for terminals. Handy for debugging Node scripts:
function prettyJ(json) {
if (typeof json !== 'string') {
json = JSON.stringify(json, undefined, 2);
}
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
function (match) {
let cls = "\x1b[36m";
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = "\x1b[34m";
} else {
cls = "\x1b[32m";
}
} else if (/true|false/.test(match)) {
cls = "\x1b[35m";
} else if (/null/.test(match)) {
cls = "\x1b[31m";
}
return cls + match + "\x1b[0m";
}
);
}
Usage:
// thing = any json OR string of json
prettyJ(thing);
For debugging purpose I use:
console.debug("%o", data);
https://getfirebug.com/wiki/index.php/Console_API
https://developer.mozilla.org/en-US/docs/DOM/console
You can use JSON.stringify(your object, null, 2)
The second parameter can be used as a replacer function which takes key and Val as parameters.This can be used in case you want to modify something within your JSON object.
more reference : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
Unsatisfied with other pretty printers for Ruby, I wrote my own (NeatJSON) and then ported it to JavaScript including a free online formatter. The code is free under MIT license (quite permissive).
Features (all optional):
Set a line width and wrap in a way that keeps objects and arrays on the same line when they fit, wrapping one value per line when they don't.
Sort object keys if you like.
Align object keys (line up the colons).
Format floating point numbers to specific number of decimals, without messing up the integers.
'Short' wrapping mode puts opening and closing brackets/braces on the same line as values, providing a format that some prefer.
Granular control over spacing for arrays and objects, between brackets, before/after colons and commas.
Function is made available to both web browsers and Node.js.
I'll copy the source code here so that this is not just a link to a library, but I encourage you to go to the GitHub project page, as that will be kept up-to-date and the code below will not.
(function(exports){
exports.neatJSON = neatJSON;
function neatJSON(value,opts){
opts = opts || {}
if (!('wrap' in opts)) opts.wrap = 80;
if (opts.wrap==true) opts.wrap = -1;
if (!('indent' in opts)) opts.indent = ' ';
if (!('arrayPadding' in opts)) opts.arrayPadding = ('padding' in opts) ? opts.padding : 0;
if (!('objectPadding' in opts)) opts.objectPadding = ('padding' in opts) ? opts.padding : 0;
if (!('afterComma' in opts)) opts.afterComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
if (!('beforeComma' in opts)) opts.beforeComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
if (!('afterColon' in opts)) opts.afterColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
if (!('beforeColon' in opts)) opts.beforeColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
var apad = repeat(' ',opts.arrayPadding),
opad = repeat(' ',opts.objectPadding),
comma = repeat(' ',opts.beforeComma)+','+repeat(' ',opts.afterComma),
colon = repeat(' ',opts.beforeColon)+':'+repeat(' ',opts.afterColon);
return build(value,'');
function build(o,indent){
if (o===null || o===undefined) return indent+'null';
else{
switch(o.constructor){
case Number:
var isFloat = (o === +o && o !== (o|0));
return indent + ((isFloat && ('decimals' in opts)) ? o.toFixed(opts.decimals) : (o+''));
case Array:
var pieces = o.map(function(v){ return build(v,'') });
var oneLine = indent+'['+apad+pieces.join(comma)+apad+']';
if (opts.wrap===false || oneLine.length<=opts.wrap) return oneLine;
if (opts.short){
var indent2 = indent+' '+apad;
pieces = o.map(function(v){ return build(v,indent2) });
pieces[0] = pieces[0].replace(indent2,indent+'['+apad);
pieces[pieces.length-1] = pieces[pieces.length-1]+apad+']';
return pieces.join(',\n');
}else{
var indent2 = indent+opts.indent;
return indent+'[\n'+o.map(function(v){ return build(v,indent2) }).join(',\n')+'\n'+indent+']';
}
case Object:
var keyvals=[],i=0;
for (var k in o) keyvals[i++] = [JSON.stringify(k), build(o[k],'')];
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
keyvals = keyvals.map(function(kv){ return kv.join(colon) }).join(comma);
var oneLine = indent+"{"+opad+keyvals+opad+"}";
if (opts.wrap===false || oneLine.length<opts.wrap) return oneLine;
if (opts.short){
var keyvals=[],i=0;
for (var k in o) keyvals[i++] = [indent+' '+opad+JSON.stringify(k),o[k]];
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
keyvals[0][0] = keyvals[0][0].replace(indent+' ',indent+'{');
if (opts.aligned){
var longest = 0;
for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
var padding = repeat(' ',longest);
for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
}
for (var i=keyvals.length;i--;){
var k=keyvals[i][0], v=keyvals[i][1];
var indent2 = repeat(' ',(k+colon).length);
var oneLine = k+colon+build(v,'');
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
}
return keyvals.join(',\n') + opad + '}';
}else{
var keyvals=[],i=0;
for (var k in o) keyvals[i++] = [indent+opts.indent+JSON.stringify(k),o[k]];
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
if (opts.aligned){
var longest = 0;
for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
var padding = repeat(' ',longest);
for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
}
var indent2 = indent+opts.indent;
for (var i=keyvals.length;i--;){
var k=keyvals[i][0], v=keyvals[i][1];
var oneLine = k+colon+build(v,'');
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
}
return indent+'{\n'+keyvals.join(',\n')+'\n'+indent+'}'
}
default:
return indent+JSON.stringify(o);
}
}
}
function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017
var result = '';
while(true){
if (times & 1) result += str;
times >>= 1;
if (times) str += str;
else break;
}
return result;
}
function padRight(pad, str){
return (str + pad).substring(0, pad.length);
}
}
neatJSON.version = "0.5";
})(typeof exports === 'undefined' ? this : exports);
Thanks a lot #all!
Based on the previous answers, here is another variant method providing custom replacement rules as parameter:
renderJSON : function(json, rr, code, pre){
if (typeof json !== 'string') {
json = JSON.stringify(json, undefined, '\t');
}
var rules = {
def : 'color:black;',
defKey : function(match){
return '<strong>' + match + '</strong>';
},
types : [
{
name : 'True',
regex : /true/,
type : 'boolean',
style : 'color:lightgreen;'
},
{
name : 'False',
regex : /false/,
type : 'boolean',
style : 'color:lightred;'
},
{
name : 'Unicode',
regex : /"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?/,
type : 'string',
style : 'color:green;'
},
{
name : 'Null',
regex : /null/,
type : 'nil',
style : 'color:magenta;'
},
{
name : 'Number',
regex : /-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/,
type : 'number',
style : 'color:darkorange;'
},
{
name : 'Whitespace',
regex : /\s+/,
type : 'whitespace',
style : function(match){
return '&nbsp';
}
}
],
keys : [
{
name : 'Testkey',
regex : /("testkey")/,
type : 'key',
style : function(match){
return '<h1>' + match + '</h1>';
}
}
],
punctuation : {
name : 'Punctuation',
regex : /([\,\.\}\{\[\]])/,
type : 'punctuation',
style : function(match){
return '<p>________</p>';
}
}
};
if('undefined' !== typeof jQuery){
rules = $.extend(rules, ('object' === typeof rr) ? rr : {});
}else{
for(var k in rr ){
rules[k] = rr[k];
}
}
var str = json.replace(/([\,\.\}\{\[\]]|"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var i = 0, p;
if (rules.punctuation.regex.test(match)) {
if('string' === typeof rules.punctuation.style){
return '<span style="'+ rules.punctuation.style + '">' + match + '</span>';
}else if('function' === typeof rules.punctuation.style){
return rules.punctuation.style(match);
} else{
return match;
}
}
if (/^"/.test(match)) {
if (/:$/.test(match)) {
for(i=0;i<rules.keys.length;i++){
p = rules.keys[i];
if (p.regex.test(match)) {
if('string' === typeof p.style){
return '<span style="'+ p.style + '">' + match + '</span>';
}else if('function' === typeof p.style){
return p.style(match);
} else{
return match;
}
}
}
return ('function'===typeof rules.defKey) ? rules.defKey(match) : '<span style="'+ rules.defKey + '">' + match + '</span>';
} else {
return ('function'===typeof rules.def) ? rules.def(match) : '<span style="'+ rules.def + '">' + match + '</span>';
}
} else {
for(i=0;i<rules.types.length;i++){
p = rules.types[i];
if (p.regex.test(match)) {
if('string' === typeof p.style){
return '<span style="'+ p.style + '">' + match + '</span>';
}else if('function' === typeof p.style){
return p.style(match);
} else{
return match;
}
}
}
}
});
if(true === pre)str = '<pre>' + str + '</pre>';
if(true === code)str = '<code>' + str + '</code>';
return str;
}
It works well:
console.table()
Read more here: https://developer.mozilla.org/pt-BR/docs/Web/API/Console/table
Here is a simple JSON format/color component written in React:
const HighlightedJSON = ({ json }: Object) => {
const highlightedJSON = jsonObj =>
Object.keys(jsonObj).map(key => {
const value = jsonObj[key];
let valueType = typeof value;
const isSimpleValue =
["string", "number", "boolean"].includes(valueType) || !value;
if (isSimpleValue && valueType === "object") {
valueType = "null";
}
return (
<div key={key} className="line">
<span className="key">{key}:</span>
{isSimpleValue ? (
<span className={valueType}>{`${value}`}</span>
) : (
highlightedJSON(value)
)}
</div>
);
});
return <div className="json">{highlightedJSON(json)}</div>;
};
See it working in this CodePen:
https://codepen.io/benshope/pen/BxVpjo
Hope that helps!
Couldn't find any solution that had good syntax highlighting for the console, so here's my 2p
Install & Add cli-highlight dependency
npm install cli-highlight --save
Define logjson globally
const highlight = require('cli-highlight').highlight
console.logjson = (obj) => console.log(
highlight( JSON.stringify(obj, null, 4),
{ language: 'json', ignoreIllegals: true } ));
Use
console.logjson({foo: "bar", someArray: ["string1", "string2"]});
I'd like to show my jsonAnalyze method here, it does a pretty print of the JSON structure only, but in some cases can be more usefull that printing the whole JSON.
Say you have a complex JSON like this:
let theJson = {
'username': 'elen',
'email': 'elen#test.com',
'state': 'married',
'profiles': [
{'name': 'elenLove', 'job': 'actor' },
{'name': 'elenDoe', 'job': 'spy'}
],
'hobbies': ['run', 'movies'],
'status': {
'home': {
'ownsHome': true,
'addresses': [
{'town': 'Mexico', 'address': '123 mexicoStr'},
{'town': 'Atlanta', 'address': '4B atlanta 45-48'},
]
},
'car': {
'ownsCar': true,
'cars': [
{'brand': 'Nissan', 'plate': 'TOKY-114', 'prevOwnersIDs': ['4532354531', '3454655344', '5566753422']},
{'brand': 'Benz', 'plate': 'ELEN-1225', 'prevOwnersIDs': ['4531124531', '97864655344', '887666753422']}
]
}
},
'active': true,
'employed': false,
};
Then the method will return the structure like this:
username
email
state
profiles[]
profiles[].name
profiles[].job
hobbies[]
status{}
status{}.home{}
status{}.home{}.ownsHome
status{}.home{}.addresses[]
status{}.home{}.addresses[].town
status{}.home{}.addresses[].address
status{}.car{}
status{}.car{}.ownsCar
status{}.car{}.cars[]
status{}.car{}.cars[].brand
status{}.car{}.cars[].plate
status{}.car{}.cars[].prevOwnersIDs[]
active
employed
So this is the jsonAnalyze() code:
function jsonAnalyze(obj) {
let arr = [];
analyzeJson(obj, null, arr);
return logBeautifiedDotNotation(arr);
function analyzeJson(obj, parentStr, outArr) {
let opt;
if (!outArr) {
return "no output array given"
}
for (let prop in obj) {
opt = parentStr ? parentStr + '.' + prop : prop;
if (Array.isArray(obj[prop]) && obj[prop] !== null) {
let arr = obj[prop];
if ((Array.isArray(arr[0]) || typeof arr[0] == "object") && arr[0] != null) {
outArr.push(opt + '[]');
analyzeJson(arr[0], opt + '[]', outArr);
} else {
outArr.push(opt + '[]');
}
} else if (typeof obj[prop] == "object" && obj[prop] !== null) {
outArr.push(opt + '{}');
analyzeJson(obj[prop], opt + '{}', outArr);
} else {
if (obj.hasOwnProperty(prop) && typeof obj[prop] != 'function') {
outArr.push(opt);
}
}
}
}
function logBeautifiedDotNotation(arr) {
retStr = '';
arr.map(function (item) {
let dotsAmount = item.split(".").length - 1;
let dotsString = Array(dotsAmount + 1).join(' ');
retStr += dotsString + item + '\n';
console.log(dotsString + item)
});
return retStr;
}
}
jsonAnalyze(theJson);
Douglas Crockford's JSON in JavaScript library will pretty print JSON via the stringify method.
You may also find the answers to this older question useful: How can I pretty-print JSON in (unix) shell script?
I ran into an issue today with #Pumbaa80's code. I'm trying to apply JSON syntax highlighting to data that I'm rendering in a Mithril view, so I need to create DOM nodes for everything in the JSON.stringify output.
I split the really long regex into its component parts as well.
render_json = (data) ->
# wraps JSON data in span elements so that syntax highlighting may be
# applied. Should be placed in a `whitespace: pre` context
if typeof(data) isnt 'string'
data = JSON.stringify(data, undefined, 2)
unicode = /"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?/
keyword = /\b(true|false|null)\b/
whitespace = /\s+/
punctuation = /[,.}{\[\]]/
number = /-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/
syntax = '(' + [unicode, keyword, whitespace,
punctuation, number].map((r) -> r.source).join('|') + ')'
parser = new RegExp(syntax, 'g')
nodes = data.match(parser) ? []
select_class = (node) ->
if punctuation.test(node)
return 'punctuation'
if /^\s+$/.test(node)
return 'whitespace'
if /^\"/.test(node)
if /:$/.test(node)
return 'key'
return 'string'
if /true|false/.test(node)
return 'boolean'
if /null/.test(node)
return 'null'
return 'number'
return nodes.map (node) ->
cls = select_class(node)
return Mithril('span', {class: cls}, node)
Code in context on Github here
If you're looking for a nice library to prettify json on a web page...
Prism.js is pretty good.
http://prismjs.com/
I found using JSON.stringify(obj, undefined, 2) to get the indentation, and then using prism to add a theme was a good approach.
If you're loading in JSON via an ajax call, then you can run one of Prism's utility methods to prettify
For example:
Prism.highlightAll()
Quick pretty human-readable JSON output in 1 line code (without colors):
document.documentElement.innerHTML='<pre>'+JSON.stringify(obj, null, 2)+'</pre>';
If you need this to work in a textarea the accepted solution will not work.
<textarea id='textarea'></textarea>
$("#textarea").append(formatJSON(JSON.stringify(jsonobject),true));
function formatJSON(json,textarea) {
var nl;
if(textarea) {
nl = "
";
} else {
nl = "<br>";
}
var tab = "    ";
var ret = "";
var numquotes = 0;
var betweenquotes = false;
var firstquote = false;
for (var i = 0; i < json.length; i++) {
var c = json[i];
if(c == '"') {
numquotes ++;
if((numquotes + 2) % 2 == 1) {
betweenquotes = true;
} else {
betweenquotes = false;
}
if((numquotes + 3) % 4 == 0) {
firstquote = true;
} else {
firstquote = false;
}
}
if(c == '[' && !betweenquotes) {
ret += c;
ret += nl;
continue;
}
if(c == '{' && !betweenquotes) {
ret += tab;
ret += c;
ret += nl;
continue;
}
if(c == '"' && firstquote) {
ret += tab + tab;
ret += c;
continue;
} else if (c == '"' && !firstquote) {
ret += c;
continue;
}
if(c == ',' && !betweenquotes) {
ret += c;
ret += nl;
continue;
}
if(c == '}' && !betweenquotes) {
ret += nl;
ret += tab;
ret += c;
continue;
}
if(c == ']' && !betweenquotes) {
ret += nl;
ret += c;
continue;
}
ret += c;
} // i loop
return ret;
}
This is nice:
https://github.com/mafintosh/json-markup from mafintosh
const jsonMarkup = require('json-markup')
const html = jsonMarkup({hello:'world'})
document.querySelector('#myElem').innerHTML = html
HTML
<link ref="stylesheet" href="style.css">
<div id="myElem></div>
Example stylesheet can be found here
https://raw.githubusercontent.com/mafintosh/json-markup/master/style.css
To highlight and beautify it in HTML using Bootstrap:
function prettifyJson(json, prettify) {
if (typeof json !== 'string') {
if (prettify) {
json = JSON.stringify(json, undefined, 4);
} else {
json = JSON.stringify(json);
}
}
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
function(match) {
let cls = "<span>";
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = "<span class='text-danger'>";
} else {
cls = "<span>";
}
} else if (/true|false/.test(match)) {
cls = "<span class='text-primary'>";
} else if (/null/.test(match)) {
cls = "<span class='text-info'>";
}
return cls + match + "</span>";
}
);
}
based on #user123444555621, just slightly more modern.
const clsMap = [
[/^".*:$/, "key"],
[/^"/, "string"],
[/true|false/, "boolean"],
[/null/, "key"],
[/.*/, "number"],
]
const syntaxHighlight = obj => JSON.stringify(obj, null, 4)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, match => `<span class="${clsMap.find(([regex]) => regex.test(match))[1]}">${match}</span>`);
you can also specify the colors inside js (no CSS needed)
const clsMap = [
[/^".*:$/, "red"],
[/^"/, "green"],
[/true|false/, "blue"],
[/null/, "magenta"],
[/.*/, "darkorange"],
]
const syntaxHighlight = obj => JSON.stringify(obj, null, 4)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, match => `<span style="color:${clsMap.find(([regex]) => regex.test(match))[1]}">${match}</span>`);
and a version with less regex
const clsMap = [
[match => match.startsWith('"') && match.endsWith(':'), "red"],
[match => match.startsWith('"'), "green"],
[match => match === "true" || match === "false" , "blue"],
[match => match === "null", "magenta"],
[() => true, "darkorange"],
];
const syntaxHighlight = obj => JSON.stringify(obj, null, 4)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, match => `<span style="color:${clsMap.find(([fn]) => fn(match))[1]}">${match}</span>`);
it's for Laravel, Codeigniter
Html:
<pre class="jsonPre"> </pre>
Controller: Return the JSON value from the controller as like as
return json_encode($data, JSON_PRETTY_PRINT);
In script:
<script> $('.jsonPre').html(result); </script>
result will be
Here is how you can print without using native function.
function pretty(ob, lvl = 0) {
let temp = [];
if(typeof ob === "object"){
for(let x in ob) {
if(ob.hasOwnProperty(x)) {
temp.push( getTabs(lvl+1) + x + ":" + pretty(ob[x], lvl+1) );
}
}
return "{\n"+ temp.join(",\n") +"\n" + getTabs(lvl) + "}";
}
else {
return ob;
}
}
function getTabs(n) {
let c = 0, res = "";
while(c++ < n)
res+="\t";
return res;
}
let obj = {a: {b: 2}, x: {y: 3}};
console.log(pretty(obj));
/*
{
a: {
b: 2
},
x: {
y: 3
}
}
*/
The simplest way to display an object for debugging purposes:
console.log("data",data) // lets you unfold the object manually
If you want to display the object in the DOM, you should consider that it could contain strings that would be interpreted as HTML. Therefore, you need to do some escaping...
var s = JSON.stringify(data,null,2) // format
var e = new Option(s).innerHTML // escape
document.body.insertAdjacentHTML('beforeend','<pre>'+e+'</pre>') // display
<!-- here is a complete example pretty print with more space between lines-->
<!-- be sure to pass a json string not a json object -->
<!-- use line-height to increase or decrease spacing between json lines -->
<style type="text/css">
.preJsonTxt{
font-size: 18px;
text-overflow: ellipsis;
overflow: hidden;
line-height: 200%;
}
.boxedIn{
border: 1px solid black;
margin: 20px;
padding: 20px;
}
</style>
<div class="boxedIn">
<h3>Configuration Parameters</h3>
<pre id="jsonCfgParams" class="preJsonTxt">{{ cfgParams }}</pre>
</div>
<script language="JavaScript">
$( document ).ready(function()
{
$(formatJson);
<!-- this will do a pretty print on the json cfg params -->
function formatJson() {
var element = $("#jsonCfgParams");
var obj = JSON.parse(element.text());
element.html(JSON.stringify(obj, undefined, 2));
}
});
</script>

Making JSON output "pretty" with CSS [duplicate]

How can I display JSON in an easy-to-read (for human readers) format? I'm looking primarily for indentation and whitespace, with perhaps even colors / font-styles / etc.
Pretty-printing is implemented natively in JSON.stringify(). The third argument enables pretty printing and sets the spacing to use:
var str = JSON.stringify(obj, null, 2); // spacing level = 2
If you need syntax highlighting, you might use some regex magic like so:
function syntaxHighlight(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, 2);
}
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
See in action here: jsfiddle
Or a full snippet provided below:
function output(inp) {
document.body.appendChild(document.createElement('pre')).innerHTML = inp;
}
function syntaxHighlight(json) {
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
var obj = {a:1, 'b':'foo', c:[false,'false',null, 'null', {d:{e:1.3e5,f:'1.3e5'}}]};
var str = JSON.stringify(obj, undefined, 4);
output(str);
output(syntaxHighlight(str));
pre {outline: 1px solid #ccc; padding: 5px; margin: 5px; }
.string { color: green; }
.number { color: darkorange; }
.boolean { color: blue; }
.null { color: magenta; }
.key { color: red; }
User Pumbaa80's answer is great if you have an object you want pretty printed. If you're starting from a valid JSON string that you want to pretty printed, you need to convert it to an object first:
var jsonString = '{"some":"json"}';
var jsonPretty = JSON.stringify(JSON.parse(jsonString),null,2);
This builds a JSON object from the string, and then converts it back to a string using JSON stringify's pretty print.
Better way.
Prettify JSON Array in Javascript
JSON.stringify(jsonobj,null,'\t')
var jsonObj = {"streetLabel": "Avenue Anatole France", "city": "Paris 07", "postalCode": "75007", "countryCode": "FRA", "countryLabel": "France" };
document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj);
In case of displaying in HTML, you should to add a balise <pre></pre>
document.getElementById("result-after").innerHTML = "<pre>"+JSON.stringify(jsonObj,undefined, 2) +"</pre>"
Example:
var jsonObj = {"streetLabel": "Avenue Anatole France", "city": "Paris 07", "postalCode": "75007", "countryCode": "FRA", "countryLabel": "France" };
document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj);
document.getElementById("result-after").innerHTML = "<pre>"+JSON.stringify(jsonObj,undefined, 2) +"</pre>"
div { float:left; clear:both; margin: 1em 0; }
<div id="result-before"></div>
<div id="result-after"></div>
Based on Pumbaa80's answer I have modified the code to use the console.log colours (working on Chrome for sure) and not HTML. Output can be seen inside console. You can edit the _variables inside the function adding some more styling.
function JSONstringify(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, '\t');
}
var
arr = [],
_string = 'color:green',
_number = 'color:darkorange',
_boolean = 'color:blue',
_null = 'color:magenta',
_key = 'color:red';
json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var style = _number;
if (/^"/.test(match)) {
if (/:$/.test(match)) {
style = _key;
} else {
style = _string;
}
} else if (/true|false/.test(match)) {
style = _boolean;
} else if (/null/.test(match)) {
style = _null;
}
arr.push(style);
arr.push('');
return '%c' + match + '%c';
});
arr.unshift(json);
console.log.apply(console, arr);
}
Here is a bookmarklet you can use:
javascript:function JSONstringify(json) {if (typeof json != 'string') {json = JSON.stringify(json, undefined, '\t');}var arr = [],_string = 'color:green',_number = 'color:darkorange',_boolean = 'color:blue',_null = 'color:magenta',_key = 'color:red';json = json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {var style = _number;if (/^"/.test(match)) {if (/:$/.test(match)) {style = _key;} else {style = _string;}} else if (/true|false/.test(match)) {style = _boolean;} else if (/null/.test(match)) {style = _null;}arr.push(style);arr.push('');return '%c' + match + '%c';});arr.unshift(json);console.log.apply(console, arr);};void(0);
Usage:
var obj = {a:1, 'b':'foo', c:[false,null, {d:{e:1.3e5}}]};
JSONstringify(obj);
Edit: I just tried to escape the % symbol with this line, after the variables declaration:
json = json.replace(/%/g, '%%');
But I find out that Chrome is not supporting % escaping in the console. Strange... Maybe this will work in the future.
Cheers!
I think you're looking for something like this :
JSON.stringify(obj, null, '\t');
This "pretty-prints" your JSON string, using a tab for indentation.
If you prefer to use spaces instead of tabs, you could also use a number for the number of spaces you'd like :
JSON.stringify(obj, null, 2);
You can use console.dir(), which is a shortcut for console.log(util.inspect()).
(The only difference is that it bypasses any custom inspect() function defined on an object.)
It uses syntax-highlighting, smart indentation, removes quotes from keys and just makes the output as pretty as it gets.
const object = JSON.parse(jsonString)
console.dir(object, {depth: null, colors: true})
and for the command line:
cat package.json | node -e "process.stdin.pipe(new stream.Writable({write: chunk => console.dir(JSON.parse(chunk), {depth: null, colors: true})}))"
I use the JSONView Chrome extension (it is as pretty as it gets :):
Edit: added jsonreport.js
I've also released an online stand-alone JSON pretty print viewer, jsonreport.js, that provides a human readable HTML5 report you can use to view any JSON data.
You can read more about the format in New JavaScript HTML5 Report Format.
If you are using ES5, simply call JSON.stringify with:
2nd arg: replacer; set to null,
3rd arg: space; use tab.
JSON.stringify(anObject, null, '\t');
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
Here's user123444555621's awesome HTML one adapted for terminals. Handy for debugging Node scripts:
function prettyJ(json) {
if (typeof json !== 'string') {
json = JSON.stringify(json, undefined, 2);
}
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
function (match) {
let cls = "\x1b[36m";
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = "\x1b[34m";
} else {
cls = "\x1b[32m";
}
} else if (/true|false/.test(match)) {
cls = "\x1b[35m";
} else if (/null/.test(match)) {
cls = "\x1b[31m";
}
return cls + match + "\x1b[0m";
}
);
}
Usage:
// thing = any json OR string of json
prettyJ(thing);
For debugging purpose I use:
console.debug("%o", data);
https://getfirebug.com/wiki/index.php/Console_API
https://developer.mozilla.org/en-US/docs/DOM/console
You can use JSON.stringify(your object, null, 2)
The second parameter can be used as a replacer function which takes key and Val as parameters.This can be used in case you want to modify something within your JSON object.
more reference : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
Unsatisfied with other pretty printers for Ruby, I wrote my own (NeatJSON) and then ported it to JavaScript including a free online formatter. The code is free under MIT license (quite permissive).
Features (all optional):
Set a line width and wrap in a way that keeps objects and arrays on the same line when they fit, wrapping one value per line when they don't.
Sort object keys if you like.
Align object keys (line up the colons).
Format floating point numbers to specific number of decimals, without messing up the integers.
'Short' wrapping mode puts opening and closing brackets/braces on the same line as values, providing a format that some prefer.
Granular control over spacing for arrays and objects, between brackets, before/after colons and commas.
Function is made available to both web browsers and Node.js.
I'll copy the source code here so that this is not just a link to a library, but I encourage you to go to the GitHub project page, as that will be kept up-to-date and the code below will not.
(function(exports){
exports.neatJSON = neatJSON;
function neatJSON(value,opts){
opts = opts || {}
if (!('wrap' in opts)) opts.wrap = 80;
if (opts.wrap==true) opts.wrap = -1;
if (!('indent' in opts)) opts.indent = ' ';
if (!('arrayPadding' in opts)) opts.arrayPadding = ('padding' in opts) ? opts.padding : 0;
if (!('objectPadding' in opts)) opts.objectPadding = ('padding' in opts) ? opts.padding : 0;
if (!('afterComma' in opts)) opts.afterComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
if (!('beforeComma' in opts)) opts.beforeComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
if (!('afterColon' in opts)) opts.afterColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
if (!('beforeColon' in opts)) opts.beforeColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
var apad = repeat(' ',opts.arrayPadding),
opad = repeat(' ',opts.objectPadding),
comma = repeat(' ',opts.beforeComma)+','+repeat(' ',opts.afterComma),
colon = repeat(' ',opts.beforeColon)+':'+repeat(' ',opts.afterColon);
return build(value,'');
function build(o,indent){
if (o===null || o===undefined) return indent+'null';
else{
switch(o.constructor){
case Number:
var isFloat = (o === +o && o !== (o|0));
return indent + ((isFloat && ('decimals' in opts)) ? o.toFixed(opts.decimals) : (o+''));
case Array:
var pieces = o.map(function(v){ return build(v,'') });
var oneLine = indent+'['+apad+pieces.join(comma)+apad+']';
if (opts.wrap===false || oneLine.length<=opts.wrap) return oneLine;
if (opts.short){
var indent2 = indent+' '+apad;
pieces = o.map(function(v){ return build(v,indent2) });
pieces[0] = pieces[0].replace(indent2,indent+'['+apad);
pieces[pieces.length-1] = pieces[pieces.length-1]+apad+']';
return pieces.join(',\n');
}else{
var indent2 = indent+opts.indent;
return indent+'[\n'+o.map(function(v){ return build(v,indent2) }).join(',\n')+'\n'+indent+']';
}
case Object:
var keyvals=[],i=0;
for (var k in o) keyvals[i++] = [JSON.stringify(k), build(o[k],'')];
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
keyvals = keyvals.map(function(kv){ return kv.join(colon) }).join(comma);
var oneLine = indent+"{"+opad+keyvals+opad+"}";
if (opts.wrap===false || oneLine.length<opts.wrap) return oneLine;
if (opts.short){
var keyvals=[],i=0;
for (var k in o) keyvals[i++] = [indent+' '+opad+JSON.stringify(k),o[k]];
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
keyvals[0][0] = keyvals[0][0].replace(indent+' ',indent+'{');
if (opts.aligned){
var longest = 0;
for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
var padding = repeat(' ',longest);
for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
}
for (var i=keyvals.length;i--;){
var k=keyvals[i][0], v=keyvals[i][1];
var indent2 = repeat(' ',(k+colon).length);
var oneLine = k+colon+build(v,'');
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
}
return keyvals.join(',\n') + opad + '}';
}else{
var keyvals=[],i=0;
for (var k in o) keyvals[i++] = [indent+opts.indent+JSON.stringify(k),o[k]];
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
if (opts.aligned){
var longest = 0;
for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
var padding = repeat(' ',longest);
for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
}
var indent2 = indent+opts.indent;
for (var i=keyvals.length;i--;){
var k=keyvals[i][0], v=keyvals[i][1];
var oneLine = k+colon+build(v,'');
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
}
return indent+'{\n'+keyvals.join(',\n')+'\n'+indent+'}'
}
default:
return indent+JSON.stringify(o);
}
}
}
function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017
var result = '';
while(true){
if (times & 1) result += str;
times >>= 1;
if (times) str += str;
else break;
}
return result;
}
function padRight(pad, str){
return (str + pad).substring(0, pad.length);
}
}
neatJSON.version = "0.5";
})(typeof exports === 'undefined' ? this : exports);
Thanks a lot #all!
Based on the previous answers, here is another variant method providing custom replacement rules as parameter:
renderJSON : function(json, rr, code, pre){
if (typeof json !== 'string') {
json = JSON.stringify(json, undefined, '\t');
}
var rules = {
def : 'color:black;',
defKey : function(match){
return '<strong>' + match + '</strong>';
},
types : [
{
name : 'True',
regex : /true/,
type : 'boolean',
style : 'color:lightgreen;'
},
{
name : 'False',
regex : /false/,
type : 'boolean',
style : 'color:lightred;'
},
{
name : 'Unicode',
regex : /"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?/,
type : 'string',
style : 'color:green;'
},
{
name : 'Null',
regex : /null/,
type : 'nil',
style : 'color:magenta;'
},
{
name : 'Number',
regex : /-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/,
type : 'number',
style : 'color:darkorange;'
},
{
name : 'Whitespace',
regex : /\s+/,
type : 'whitespace',
style : function(match){
return '&nbsp';
}
}
],
keys : [
{
name : 'Testkey',
regex : /("testkey")/,
type : 'key',
style : function(match){
return '<h1>' + match + '</h1>';
}
}
],
punctuation : {
name : 'Punctuation',
regex : /([\,\.\}\{\[\]])/,
type : 'punctuation',
style : function(match){
return '<p>________</p>';
}
}
};
if('undefined' !== typeof jQuery){
rules = $.extend(rules, ('object' === typeof rr) ? rr : {});
}else{
for(var k in rr ){
rules[k] = rr[k];
}
}
var str = json.replace(/([\,\.\}\{\[\]]|"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var i = 0, p;
if (rules.punctuation.regex.test(match)) {
if('string' === typeof rules.punctuation.style){
return '<span style="'+ rules.punctuation.style + '">' + match + '</span>';
}else if('function' === typeof rules.punctuation.style){
return rules.punctuation.style(match);
} else{
return match;
}
}
if (/^"/.test(match)) {
if (/:$/.test(match)) {
for(i=0;i<rules.keys.length;i++){
p = rules.keys[i];
if (p.regex.test(match)) {
if('string' === typeof p.style){
return '<span style="'+ p.style + '">' + match + '</span>';
}else if('function' === typeof p.style){
return p.style(match);
} else{
return match;
}
}
}
return ('function'===typeof rules.defKey) ? rules.defKey(match) : '<span style="'+ rules.defKey + '">' + match + '</span>';
} else {
return ('function'===typeof rules.def) ? rules.def(match) : '<span style="'+ rules.def + '">' + match + '</span>';
}
} else {
for(i=0;i<rules.types.length;i++){
p = rules.types[i];
if (p.regex.test(match)) {
if('string' === typeof p.style){
return '<span style="'+ p.style + '">' + match + '</span>';
}else if('function' === typeof p.style){
return p.style(match);
} else{
return match;
}
}
}
}
});
if(true === pre)str = '<pre>' + str + '</pre>';
if(true === code)str = '<code>' + str + '</code>';
return str;
}
It works well:
console.table()
Read more here: https://developer.mozilla.org/pt-BR/docs/Web/API/Console/table
Here is a simple JSON format/color component written in React:
const HighlightedJSON = ({ json }: Object) => {
const highlightedJSON = jsonObj =>
Object.keys(jsonObj).map(key => {
const value = jsonObj[key];
let valueType = typeof value;
const isSimpleValue =
["string", "number", "boolean"].includes(valueType) || !value;
if (isSimpleValue && valueType === "object") {
valueType = "null";
}
return (
<div key={key} className="line">
<span className="key">{key}:</span>
{isSimpleValue ? (
<span className={valueType}>{`${value}`}</span>
) : (
highlightedJSON(value)
)}
</div>
);
});
return <div className="json">{highlightedJSON(json)}</div>;
};
See it working in this CodePen:
https://codepen.io/benshope/pen/BxVpjo
Hope that helps!
Couldn't find any solution that had good syntax highlighting for the console, so here's my 2p
Install & Add cli-highlight dependency
npm install cli-highlight --save
Define logjson globally
const highlight = require('cli-highlight').highlight
console.logjson = (obj) => console.log(
highlight( JSON.stringify(obj, null, 4),
{ language: 'json', ignoreIllegals: true } ));
Use
console.logjson({foo: "bar", someArray: ["string1", "string2"]});
I'd like to show my jsonAnalyze method here, it does a pretty print of the JSON structure only, but in some cases can be more usefull that printing the whole JSON.
Say you have a complex JSON like this:
let theJson = {
'username': 'elen',
'email': 'elen#test.com',
'state': 'married',
'profiles': [
{'name': 'elenLove', 'job': 'actor' },
{'name': 'elenDoe', 'job': 'spy'}
],
'hobbies': ['run', 'movies'],
'status': {
'home': {
'ownsHome': true,
'addresses': [
{'town': 'Mexico', 'address': '123 mexicoStr'},
{'town': 'Atlanta', 'address': '4B atlanta 45-48'},
]
},
'car': {
'ownsCar': true,
'cars': [
{'brand': 'Nissan', 'plate': 'TOKY-114', 'prevOwnersIDs': ['4532354531', '3454655344', '5566753422']},
{'brand': 'Benz', 'plate': 'ELEN-1225', 'prevOwnersIDs': ['4531124531', '97864655344', '887666753422']}
]
}
},
'active': true,
'employed': false,
};
Then the method will return the structure like this:
username
email
state
profiles[]
profiles[].name
profiles[].job
hobbies[]
status{}
status{}.home{}
status{}.home{}.ownsHome
status{}.home{}.addresses[]
status{}.home{}.addresses[].town
status{}.home{}.addresses[].address
status{}.car{}
status{}.car{}.ownsCar
status{}.car{}.cars[]
status{}.car{}.cars[].brand
status{}.car{}.cars[].plate
status{}.car{}.cars[].prevOwnersIDs[]
active
employed
So this is the jsonAnalyze() code:
function jsonAnalyze(obj) {
let arr = [];
analyzeJson(obj, null, arr);
return logBeautifiedDotNotation(arr);
function analyzeJson(obj, parentStr, outArr) {
let opt;
if (!outArr) {
return "no output array given"
}
for (let prop in obj) {
opt = parentStr ? parentStr + '.' + prop : prop;
if (Array.isArray(obj[prop]) && obj[prop] !== null) {
let arr = obj[prop];
if ((Array.isArray(arr[0]) || typeof arr[0] == "object") && arr[0] != null) {
outArr.push(opt + '[]');
analyzeJson(arr[0], opt + '[]', outArr);
} else {
outArr.push(opt + '[]');
}
} else if (typeof obj[prop] == "object" && obj[prop] !== null) {
outArr.push(opt + '{}');
analyzeJson(obj[prop], opt + '{}', outArr);
} else {
if (obj.hasOwnProperty(prop) && typeof obj[prop] != 'function') {
outArr.push(opt);
}
}
}
}
function logBeautifiedDotNotation(arr) {
retStr = '';
arr.map(function (item) {
let dotsAmount = item.split(".").length - 1;
let dotsString = Array(dotsAmount + 1).join(' ');
retStr += dotsString + item + '\n';
console.log(dotsString + item)
});
return retStr;
}
}
jsonAnalyze(theJson);
Douglas Crockford's JSON in JavaScript library will pretty print JSON via the stringify method.
You may also find the answers to this older question useful: How can I pretty-print JSON in (unix) shell script?
I ran into an issue today with #Pumbaa80's code. I'm trying to apply JSON syntax highlighting to data that I'm rendering in a Mithril view, so I need to create DOM nodes for everything in the JSON.stringify output.
I split the really long regex into its component parts as well.
render_json = (data) ->
# wraps JSON data in span elements so that syntax highlighting may be
# applied. Should be placed in a `whitespace: pre` context
if typeof(data) isnt 'string'
data = JSON.stringify(data, undefined, 2)
unicode = /"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?/
keyword = /\b(true|false|null)\b/
whitespace = /\s+/
punctuation = /[,.}{\[\]]/
number = /-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/
syntax = '(' + [unicode, keyword, whitespace,
punctuation, number].map((r) -> r.source).join('|') + ')'
parser = new RegExp(syntax, 'g')
nodes = data.match(parser) ? []
select_class = (node) ->
if punctuation.test(node)
return 'punctuation'
if /^\s+$/.test(node)
return 'whitespace'
if /^\"/.test(node)
if /:$/.test(node)
return 'key'
return 'string'
if /true|false/.test(node)
return 'boolean'
if /null/.test(node)
return 'null'
return 'number'
return nodes.map (node) ->
cls = select_class(node)
return Mithril('span', {class: cls}, node)
Code in context on Github here
If you're looking for a nice library to prettify json on a web page...
Prism.js is pretty good.
http://prismjs.com/
I found using JSON.stringify(obj, undefined, 2) to get the indentation, and then using prism to add a theme was a good approach.
If you're loading in JSON via an ajax call, then you can run one of Prism's utility methods to prettify
For example:
Prism.highlightAll()
Quick pretty human-readable JSON output in 1 line code (without colors):
document.documentElement.innerHTML='<pre>'+JSON.stringify(obj, null, 2)+'</pre>';
If you need this to work in a textarea the accepted solution will not work.
<textarea id='textarea'></textarea>
$("#textarea").append(formatJSON(JSON.stringify(jsonobject),true));
function formatJSON(json,textarea) {
var nl;
if(textarea) {
nl = "
";
} else {
nl = "<br>";
}
var tab = "    ";
var ret = "";
var numquotes = 0;
var betweenquotes = false;
var firstquote = false;
for (var i = 0; i < json.length; i++) {
var c = json[i];
if(c == '"') {
numquotes ++;
if((numquotes + 2) % 2 == 1) {
betweenquotes = true;
} else {
betweenquotes = false;
}
if((numquotes + 3) % 4 == 0) {
firstquote = true;
} else {
firstquote = false;
}
}
if(c == '[' && !betweenquotes) {
ret += c;
ret += nl;
continue;
}
if(c == '{' && !betweenquotes) {
ret += tab;
ret += c;
ret += nl;
continue;
}
if(c == '"' && firstquote) {
ret += tab + tab;
ret += c;
continue;
} else if (c == '"' && !firstquote) {
ret += c;
continue;
}
if(c == ',' && !betweenquotes) {
ret += c;
ret += nl;
continue;
}
if(c == '}' && !betweenquotes) {
ret += nl;
ret += tab;
ret += c;
continue;
}
if(c == ']' && !betweenquotes) {
ret += nl;
ret += c;
continue;
}
ret += c;
} // i loop
return ret;
}
This is nice:
https://github.com/mafintosh/json-markup from mafintosh
const jsonMarkup = require('json-markup')
const html = jsonMarkup({hello:'world'})
document.querySelector('#myElem').innerHTML = html
HTML
<link ref="stylesheet" href="style.css">
<div id="myElem></div>
Example stylesheet can be found here
https://raw.githubusercontent.com/mafintosh/json-markup/master/style.css
To highlight and beautify it in HTML using Bootstrap:
function prettifyJson(json, prettify) {
if (typeof json !== 'string') {
if (prettify) {
json = JSON.stringify(json, undefined, 4);
} else {
json = JSON.stringify(json);
}
}
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
function(match) {
let cls = "<span>";
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = "<span class='text-danger'>";
} else {
cls = "<span>";
}
} else if (/true|false/.test(match)) {
cls = "<span class='text-primary'>";
} else if (/null/.test(match)) {
cls = "<span class='text-info'>";
}
return cls + match + "</span>";
}
);
}
based on #user123444555621, just slightly more modern.
const clsMap = [
[/^".*:$/, "key"],
[/^"/, "string"],
[/true|false/, "boolean"],
[/null/, "key"],
[/.*/, "number"],
]
const syntaxHighlight = obj => JSON.stringify(obj, null, 4)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, match => `<span class="${clsMap.find(([regex]) => regex.test(match))[1]}">${match}</span>`);
you can also specify the colors inside js (no CSS needed)
const clsMap = [
[/^".*:$/, "red"],
[/^"/, "green"],
[/true|false/, "blue"],
[/null/, "magenta"],
[/.*/, "darkorange"],
]
const syntaxHighlight = obj => JSON.stringify(obj, null, 4)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, match => `<span style="color:${clsMap.find(([regex]) => regex.test(match))[1]}">${match}</span>`);
and a version with less regex
const clsMap = [
[match => match.startsWith('"') && match.endsWith(':'), "red"],
[match => match.startsWith('"'), "green"],
[match => match === "true" || match === "false" , "blue"],
[match => match === "null", "magenta"],
[() => true, "darkorange"],
];
const syntaxHighlight = obj => JSON.stringify(obj, null, 4)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, match => `<span style="color:${clsMap.find(([fn]) => fn(match))[1]}">${match}</span>`);
it's for Laravel, Codeigniter
Html:
<pre class="jsonPre"> </pre>
Controller: Return the JSON value from the controller as like as
return json_encode($data, JSON_PRETTY_PRINT);
In script:
<script> $('.jsonPre').html(result); </script>
result will be
Here is how you can print without using native function.
function pretty(ob, lvl = 0) {
let temp = [];
if(typeof ob === "object"){
for(let x in ob) {
if(ob.hasOwnProperty(x)) {
temp.push( getTabs(lvl+1) + x + ":" + pretty(ob[x], lvl+1) );
}
}
return "{\n"+ temp.join(",\n") +"\n" + getTabs(lvl) + "}";
}
else {
return ob;
}
}
function getTabs(n) {
let c = 0, res = "";
while(c++ < n)
res+="\t";
return res;
}
let obj = {a: {b: 2}, x: {y: 3}};
console.log(pretty(obj));
/*
{
a: {
b: 2
},
x: {
y: 3
}
}
*/
The simplest way to display an object for debugging purposes:
console.log("data",data) // lets you unfold the object manually
If you want to display the object in the DOM, you should consider that it could contain strings that would be interpreted as HTML. Therefore, you need to do some escaping...
var s = JSON.stringify(data,null,2) // format
var e = new Option(s).innerHTML // escape
document.body.insertAdjacentHTML('beforeend','<pre>'+e+'</pre>') // display
<!-- here is a complete example pretty print with more space between lines-->
<!-- be sure to pass a json string not a json object -->
<!-- use line-height to increase or decrease spacing between json lines -->
<style type="text/css">
.preJsonTxt{
font-size: 18px;
text-overflow: ellipsis;
overflow: hidden;
line-height: 200%;
}
.boxedIn{
border: 1px solid black;
margin: 20px;
padding: 20px;
}
</style>
<div class="boxedIn">
<h3>Configuration Parameters</h3>
<pre id="jsonCfgParams" class="preJsonTxt">{{ cfgParams }}</pre>
</div>
<script language="JavaScript">
$( document ).ready(function()
{
$(formatJson);
<!-- this will do a pretty print on the json cfg params -->
function formatJson() {
var element = $("#jsonCfgParams");
var obj = JSON.parse(element.text());
element.html(JSON.stringify(obj, undefined, 2));
}
});
</script>

Is there any native function to convert json to url parameters?

I need convert json object to url form like: "parameter=12&asd=1"
I done with this:
var data = {
'action':'actualiza_resultado',
'postID': 1,
'gl': 2,
'gl2' : 3
};
var string_=JSON.stringify(data);
string_=string_.replace(/{/g, "");
string_=string_.replace(/}/g, "");
string_=string_.replace(/:/g, "=")
string_=string_.replace(/,/g, "&");
string_=string_.replace(/"/g, "");
But i wonder if there any function in javascript or in JSON object to do this?
Use the URLSearchParams interface, which is built into browsers and Node.js starting with version 10, released in 2018.
const myParams = {'foo': 'hi there', 'bar': '???'};
const u = new URLSearchParams(myParams).toString();
console.log(u);
Old answer: jQuery provides param that does exactly that. If you don't use jquery, take at look at the source.
Basically, it goes like this:
url = Object.keys(data).map(function(k) {
return encodeURIComponent(k) + '=' + encodeURIComponent(data[k])
}).join('&')
Using ES6 syntax:
var data = {
'action':'actualiza_resultado',
'postID': 1,
'gl': 2,
'gl2' : 3
};
let urlParameters = Object.entries(data).map(e => e.join('=')).join('&');
console.log(urlParameters);
I made an implementation that support nested objects and arrays i.e.
var data = {
users: [
{
"name": "jeff",
"tasks": [
"Do one thing",
"Do second thing"
]
},
{
"name": "rick",
"tasks": [
"Never gonna give you up",
"Never gonna let you down"
]
}
]
}
Will be:
users[0][name]=jeff&users[0][tasks][0]=Do%20one%20thing&users[0][tasks][1]=Do%20second%20thing&users[1][name]=rick&users[1][tasks][0]=Never%20gonna%20give%20you%20up&users[1][tasks][1]=Never%20gonna%20let%20you%20down
So, here's the implementation:
var isObj = function(a) {
if ((!!a) && (a.constructor === Object)) {
return true;
}
return false;
};
var _st = function(z, g) {
return "" + (g != "" ? "[" : "") + z + (g != "" ? "]" : "");
};
var fromObject = function(params, skipobjects, prefix) {
if (skipobjects === void 0) {
skipobjects = false;
}
if (prefix === void 0) {
prefix = "";
}
var result = "";
if (typeof(params) != "object") {
return prefix + "=" + encodeURIComponent(params) + "&";
}
for (var param in params) {
var c = "" + prefix + _st(param, prefix);
if (isObj(params[param]) && !skipobjects) {
result += fromObject(params[param], false, "" + c);
} else if (Array.isArray(params[param]) && !skipobjects) {
params[param].forEach(function(item, ind) {
result += fromObject(item, false, c + "[" + ind + "]");
});
} else {
result += c + "=" + encodeURIComponent(params[param]) + "&";
}
}
return result;
};
var data = {
users: [{
"name": "jeff",
"tasks": [
"Do one thing",
"Do second thing"
]
},
{
"name": "rick",
"tasks": [
"Never gonna give you up",
"Never gonna let you down"
]
}
]
}
document.write(fromObject(data));
You don't need to serialize this object literal.
Better approach is something like:
function getAsUriParameters(data) {
var url = '';
for (var prop in data) {
url += encodeURIComponent(prop) + '=' +
encodeURIComponent(data[prop]) + '&';
}
return url.substring(0, url.length - 1)
}
getAsUriParameters(data); //"action=actualiza_resultado&postID=1&gl=2&gl2=3"
Something I find nicely looking in ES6:
function urlfy(obj) {
return Object
.keys(obj)
.map(k => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`)
.join('&');
}
Later update (same thing, maybe a bit cleaner):
const urlfy = obj => Object
.keys(obj)
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]))
.join('&');
Like #georg said, you can use JQuery.param for flat objects.
If you need to process complex objects, you can use JsonUri, a python package that does just that. There is JavaScript library for it as well
Disclaimer: I am the author of JSONURI
Edit: I learned much later that you can also just base64 encode your payload - most languages as support for base64 encoding/decoding
Example
x = {name: 'Petter', age: 47, places: ['Mozambique', 'Zimbabwe']}
stringRep = JSON.stringify(x)
encoded = window.btoa(stringRep)
Gives you eyJuYW1lIjoiUGV0dGVyIiwiYWdlIjo0NywicGxhY2VzIjpbIk1vemFtYmlxdWUiLCJaaW1iYWJ3ZSJdfQ==, which you can use as a uri parameter
decoded = window.atob(encoded)
originalX = JSON.parse(decoded)
Needless to say, it comes with its own caveats
But i wonder if there any function in javascript
Nothing prewritten in the core.
or json to do this?
JSON is a data format. It doesn't have functions at all.
This is a relatively trivial problem to solve though, at least for flat data structures.
Don't encode the objects as JSON, then:
function obj_to_query(obj) {
var parts = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
}
}
return "?" + parts.join('&');
}
alert(obj_to_query({
'action': 'actualiza_resultado',
'postID': 1,
'gl': 2,
'gl2': 3
}));
There isn't a standard way to encode complex data structures (e.g. with nested objects or arrays). It wouldn't be difficult to extend this to emulate the PHP method (of having square brackets in field names) or similar though.
This one processes arrays with by changing the nameinto mutiple name[]
function getAsUriParameters (data) {
return Object.keys(data).map(function (k) {
if (_.isArray(data[k])) {
var keyE = encodeURIComponent(k + '[]');
return data[k].map(function (subData) {
return keyE + '=' + encodeURIComponent(subData);
}).join('&');
} else {
return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]);
}
}).join('&');
};
Best solution for Vanilla JavaScript:
var params = Object.keys(data)
.filter(function (key) {
return data[key] ? true : false
})
.map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(data[key])
})
.join('&');
PS: The filter is used here to remove null or undefined parameters. It makes the url look cleaner.
The custom code above only handles flat data. And JQuery is not available in react native. So here is a js solution that does work with multi-level objects and arrays in react native.
function formurlencoded(data) {
const opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
let sorted = Boolean(opts.sorted),
skipIndex = Boolean(opts.skipIndex),
ignorenull = Boolean(opts.ignorenull),
encode = function encode(value) {
return String(value).replace(/(?:[\0-\x1F"-&\+-\}\x7F-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g, encodeURIComponent).replace(/ /g, '+').replace(/[!'()~\*]/g, function (ch) {
return '%' + ch.charCodeAt().toString(16).slice(-2).toUpperCase();
});
},
keys = function keys(obj) {
const keyarr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Object.keys(obj);
return sorted ? keyarr.sort() : keyarr;
},
filterjoin = function filterjoin(arr) {
return arr.filter(function (e) {
return e;
}).join('&');
},
objnest = function objnest(name, obj) {
return filterjoin(keys(obj).map(function (key) {
return nest(name + '[' + key + ']', obj[key]);
}));
},
arrnest = function arrnest(name, arr) {
return arr.length ? filterjoin(arr.map(function (elem, index) {
return skipIndex ? nest(name + '[]', elem) : nest(name + '[' + index + ']', elem);
})) : encode(name + '[]');
},
nest = function nest(name, value) {
const type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : typeof value === 'undefined' ? 'undefined' : typeof(value);
let f = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
if (value === f) f = ignorenull ? f : encode(name) + '=' + f; else if (/string|number|boolean/.test(type)) f = encode(name) + '=' + encode(value); else if (Array.isArray(value)) f = arrnest(name, value); else if (type === 'object') f = objnest(name, value);
return f;
};
return data && filterjoin(keys(data).map(function (key) {
return nest(key, data[key]);
}));
}
The conversion from a JSON string to a URL query string can be done in a single line:
const json = '{"action":"actualiza_resultado","postID":1,"gl":2,"gl2":3}';
const queryString = new URLSearchParams(JSON.parse(json)).toString();
queryString would then be set to "action=actualiza_resultado&postID=1&gl=2&gl2=3".
Based on georg's answer, but also adding ? before the string and using ES6:
const query = !params ? '': Object.keys(params).map((k, idx) => {
let prefix = '';
if (idx === 0) {
prefix = '?';
}
return prefix + encodeURIComponent(k) + '=' + encodeURIComponent(params[k]);
}).join('&');
As most of the answers only convert flat objects to query parameters, I would like to share mine.
This function can handle flat objects, as well as nested arrays/objects while only using plain JS.
function incapsulateInBrackets(key)
{
return '[' + key + ']';
}
function encode(object, isSubEncode=false, prefix = '')
{
let parts = Object.keys(object).map( (key) => {
let encodedParts = [];
if(Array.isArray(object[key]))
{
object[key].map(function(innerKey, index){
encodedParts.push( encode(object[key][index], true, prefix + key + incapsulateInBrackets(index)));
});
}
else if(object[key] instanceof Object)
{
Object.keys(object[key]).map( (innerKey) => {
if(Array.isArray(object[key][innerKey]))
{
encodedParts.push( encode(object[key][index], true, prefix + incapsulateInBrackets(key) + incapsulateInBrackets(innerKey)) );
}
else
{
encodedParts.push( prefix + incapsulateInBrackets(key) + incapsulateInBrackets(innerKey) + '=' + object[key][innerKey] );
}
});
}
else
{
if(isSubEncode)
{
encodedParts.push( prefix + incapsulateInBrackets(key) + '=' + object[key] );
}
else
{
encodedParts.push( key + '=' + object[key] );
}
}
return encodedParts.join('&');
});
return parts.join('&');
}
Make a utility if you have nodejs
const querystring = require('querystring')
export function makeQueryString(params): string {
return querystring.stringify(params)
}
import example
import { makeQueryString } from '~/utils'
example of use
makeQueryString({
...query,
page
})
Read the latest documentation here.

Toggle query string variables

I've been banging my head over this.
Using jquery or javascript, how can I toggle variables & values and then rebuild the query string? For example, my starting URL is:
http://example.com?color=red&size=small,medium,large&shape=round
Then, if the user clicks a button labeled "red", I want to end up with:
http://example.com?size=small,medium,large&shape=round //color is removed
Then, if the user clicks "red" again, I want to end up with:
http://example.com?size=small,medium,large&shape=round&color=red //color is added back
Then, if the user clicks a button labeled "medium", I want to end up with:
http://example.com?size=small,large&shape=round&color=red //medium is removed from list
Then, if the user clicks the labeled "medium" again, I want to end up with:
http://example.com?size=small,large,medium&shape=round&color=red //medium added back
It doesn't really matter what order the variable are in; I've just been tacking them to the end.
function toggle(url, key, val) {
var out = [],
upd = '',
rm = "([&?])" + key + "=([^&]*?,)?" + val + "(,.*?)?(&.*?)?$",
ad = key + "=",
rmrplr = function(url, p1, p2, p3, p4) {
if (p2) {
if (p3) out.push(p1, key, '=', p2, p3.substr(1));
else out.push(p1, key, '=', p2.substr(0, p2.length - 1));
} else {
if (p3) out.push(p1, key, '=', p3.substr(1));
else out.push(p1);
}
if (p4) out.push(p4);
return out.join('').replace(/([&?])&/, '$1').replace(/[&?]$/, ''); //<!2
},
adrplr = function(s) {
return s + val + ',';
};
if ((upd = url.replace(new RegExp(rm), rmrplr)) != url) return upd;
if ((upd = url.replace(new RegExp(ad), adrplr)) != url) return upd;
return url + (/\?.+/.test(url) ? '&' : '?') + key + '=' + val; //<!1
}
params self described enough, hope this help.
!1: changed from ...? '&' : '' to ... ? '&' : '?'
!2: changed from .replace('?&','?')... to .replace(/([&?]&)/,'$1')...
http://jsfiddle.net/ycw7788/Abxj8/
I have written a function, which efficiently results in the expected behaviour, without use of any libraries or frameworks. A dynamic demo can be found at this fiddle: http://jsfiddle.net/w8D2G/1/
Documentation
Definitions:
The shown example values will be used at the Usage section, below
  -   Haystack - The string to search in (default = query string. e.g: ?size=small,medium)
  -   Needle - The key to search for. Example: size
  -   Value - The value to replace/add. Example: medium.
Usage (Example: input > output):
qs_replace(needle, value)
If value exists, remove: ?size=small,medium > ?size=small
If value not exists, add: ?size=small > size=small,medium
qs_replace(needle, options)     Object options. Recognised options:
findString. Returns true if the value exists, false otherwise.
add, remove or toggleString. Add/remove the given value to/from needle. If remove is used, and the value was the only value, needle is also removed. A value won't be added if it already exists.
ignorecaseIgnore case while looking for the search terms (needle, add, remove or find).
separatorSpecify a separator to separate values of needle. Default to comma (,).
Note :   A different value for String haystack can also be defined, by adding it as a first argument: qs_replace(haystack, needle, value) or qs_replace(haystack, needle, options)
Code (examples at bottom). Fiddle: http://jsfiddle.net/w8D2G/1/:
function qs_replace(haystack, needle, options) {
if(!haystack || !needle) return ""; // Without a haystack or needle.. Bye
else if(typeof needle == "object") {
options = needle;
needle = haystack;
haystack = location.search;
} else if(typeof options == "undefined") {
options = needle;
needle = haystack;
haystack = location.search;
}
if(typeof options == "string" && options != "") {
options = {remove: options};
var toggle = true;
} else if(typeof options != "object" || options === null) {
return haystack;
} else {
var toggle = !!options.toggle;
if (toggle) {
options.remove = options.toggle;
options.toggle = void 0;
}
}
var find = options.find,
add = options.add,
remove = options.remove || options.del, //declare remove
sep = options.sep || options.separator || ",", //Commas, by default
flags = (options.ignorecase ? "i" :"");
needle = encodeURIComponent(needle); //URL-encoding
var pattern = regexp_special_chars(needle);
pattern = "([?&])(" + pattern + ")(=|&|$)([^&]*)(&|$)";
pattern = new RegExp(pattern, flags);
var subquery_match = haystack.match(pattern);
var before = /\?/.test(haystack) ? "&" : "?"; //Use ? if not existent, otherwise &
var re_sep = regexp_special_chars(sep);
if (!add || find) { //add is not defined, or find is used
var original_remove = remove;
if (subquery_match) {
remove = encodeURIComponent(remove);
remove = regexp_special_chars(remove);
remove = "(^|" + re_sep + ")(" + remove + ")(" + re_sep + "|$)";
remove = new RegExp(remove, flags);
var fail = subquery_match[4].match(remove);
} else {
var fail = false;
}
if (!add && !fail && toggle) add = original_remove;
}
if(find) return !!subquery_match || fail;
if (add) { //add is a string, defined previously
add = encodeURIComponent(add);
if(subquery_match) {
var re_add = regexp_special_chars(add);
re_add = "(^|" + re_sep + ")(" + re_add + ")(?=" + re_sep + "|$)";
re_add = new RegExp(re_add, flags);
if (subquery_match && re_add.test(subquery_match[4])) {
return haystack;
}
if (subquery_match[3] != "=") {
subquery_match = "$1$2=" + add + "$4$5";
} else {
subquery_match = "$1$2=$4" + sep + add + "$5";
}
return haystack.replace(pattern, subquery_match);
} else {
return haystack + before + needle + "=" + add;
}
} else if(subquery_match){ // Remove part. We can only remove if a needle exist
if(subquery_match[3] != "="){
return haystack;
} else {
return haystack.replace(pattern, function(match, prefix, key, separator, value, trailing_sep){
// The whole match, example: &foo=bar,doo
// will be replaced by the return value of this function
var newValue = value.replace(remove, function(m, pre, bye, post){
return pre == sep && post == sep ? sep : pre == "?" ? "?" : "";
});
if(newValue) { //If the value has any content
return prefix + key + separator + newValue + trailing_sep;
} else {
return prefix == "?" ? "?" : trailing_sep; //No value, also remove needle
}
}); //End of haystack.replace
} //End of else if
} else {
return haystack;
}
// Convert string to RegExp-safe string
function regexp_special_chars(s){
return s.replace(/([[^$.|?*+(){}\\])/g, '\\$1');
}
}
Examples (Fiddle: http://jsfiddle.net/w8D2G/1/):
qs_replace('color', 'red'); //Toggle color=red
qs_replace('size', {add: 'medium'}); //Add `medium` if not exist to size
var starting_url = 'http://example.com?color=red&size=small,medium,large&shape=round'
starting_url = qs_replace(starting_url, 'color', 'red'); //Toggle red, thus remove
starting_url = qs_replace(starting_url, 'color', 'red'); //Toggle red, so add it
alert(starting_url);
This is the solution for your task: http://jsfiddle.net/mikhailov/QpjZ3/12/
var url = 'http://example.com?size=small,medium,large&shape=round';
var params = $.deparam.querystring(url);
var paramsResult = {};
var click1 = { size: 'small' };
var click2 = { size: 'xlarge' };
var click3 = { shape: 'round' };
var click4 = { shape: 'square' };
var clickNow = click4;
for (i in params) {
var clickKey = _.keys(clickNow)[0];
var clickVal = _.values(clickNow)[0];
if (i == clickKey) {
var ar = params[i].split(',');
if (_.include(ar, clickVal)) {
var newAr = _.difference(ar, [clickVal]);
} else {
var newAr = ar;
newAr.push(clickVal);
}
paramsResult[i] = newAr.join(',');
} else {
paramsResult[i] = params[i];
}
}
alert($.param(paramsResult)) // results see below
Init params string
{ size="small, medium,large", shape="round"} // size=small,medium,large&shape=round
Results
{ size="small"} => { size="medium,large", shape="round"} //size=medium%2Clarge&shape=round
{ size="xlarge"} => { size="small,medium,large,xlarge", shape="round"} // size=small%2Cmedium%2Clarge%2Cxlarge&shape=round
{ shape="round"} => { size="small,medium,large", shape=""} //size=small%2Cmedium%2Clarge&shape=
{ shape="square"} => { size="small,medium,large", shape="round,square"} //size=small%2Cmedium%2Clarge&shape=round%2Csquare
productOptions is the only thing you need to modify here to list all the available options and their default state. You only need to use the public API function toggleOption() to toggle an option.
(function(){
//Just keep an object with all the options with flags if they are enabled or disabled:
var productOptions = {
color: {
"red": true,
"blue": true,
"green": false
},
size: {
"small": true,
"medium": true,
"large": true
},
shape: {
"round": true
}
};
//After this constructing query becomes pretty simple even without framework functions:
function constructQuery(){
var key, opts, qs = [], enc = encodeURIComponent, opt,
optAr, i;
for( key in productOptions ) {
opts = productOptions[key];
optAr = [];
for( i in opts ) {
if( opts[i] ) {
optAr.push( i );
}
}
if( !optAr.length ) {
continue;
}
qs.push( enc( key ) + "=" + enc( optAr.join( "," ) ) );
}
return "?"+qs.join( "&" );
};
//To toggle a value and construct the new query, pass what you want to toggle to this function:
function toggleOption( optionType, option ) {
if( optionType in productOptions && option in productOptions[optionType] ) {
productOptions[optionType][option] = !productOptions[optionType][option];
}
return constructQuery();
}
window.toggleOption = toggleOption;
})()
Example use:
// "%2C" = url encoded version of ","
toggleOption(); //Default query returned:
"?color=red%2Cblue&size=small%2Cmedium%2Clarge&shape=round"
toggleOption( "color", "red" ); //Red color removed:
"?color=blue&size=small%2Cmedium%2Clarge&shape=round"
toggleOption( "color", "blue" ); //Blue color removed, no color options so color doesn't show up at all:
"?size=small%2Cmedium%2Clarge&shape=round"
toggleOption( "color", "blue" ); //Blue color enabled again:
"?color=blue&size=small%2Cmedium%2Clarge&shape=round"
toggleOption( "shape", "round" ); //The only shape option removed
"?color=blue&size=small%2Cmedium%2Clarge"
I have tried this and this may give the desire result
<script>
var url='http://example.com?color=red&size=small,medium,large&shape=round';
var mySplitResult = url.split("?");
var domain=mySplitResult[0];
var qstring=mySplitResult[1];
var proparr=new Array();
var valarr=new Array();
var mySplitArr = qstring.split("&");
for (i=0;i<mySplitArr.length;i++){
var temp = mySplitArr[i].split("=");
proparr[i]=temp[0];
valarr[i]=temp[1].split(",");
}
function toggle(property,value)
{
var index;
var yes=0;
for (i=0;i<proparr.length;i++){
if(proparr[i]==property)
index=i;
}
if(index==undefined){
proparr[i]=property;
index=i;
valarr[index]=new Array();
}
for (i=0;i<valarr[index].length;i++){
if(valarr[index][i]==value){
valarr[index].splice(i,1);
yes=1;
}
}
if(!yes)
{
valarr[index][i]=value;
}
var furl=domain +'?';
var test=new Array();
for(i=0;i<proparr.length;i++)
{
if(valarr[i].length)
{
test[i]=valarr[i].join(",");
furl +=proparr[i]+"="+test[i]+"&";
}
}
furl=furl.substr(0,furl.length-1)
alert(furl);
}
</script>
<div>
<input id="color" type="button" value="Toggle Red" onclick="toggle('color','red')"/>
<input id="shape" type="button" value="Toggle shape" onclick="toggle('shape','round')"/>
<input id="size" type="button" value="Toggle Small" onclick="toggle('size','small')"/>
<input id="size" type="button" value="Toggle large" onclick="toggle('size','large')"/>
<input id="size" type="button" value="Toggle medium" onclick="toggle('size','medium')"/>
<input id="size" type="button" value="Toggle new" onclick="toggle('new','yes')"/>
</div>

What is the JavaScript equivalent of var_dump or print_r in PHP? [duplicate]

This question already has answers here:
Is there an equivalent for var_dump (PHP) in Javascript?
(20 answers)
Closed 5 years ago.
I would like to see the structure of object in JavaScript (for debugging). Is there anything similar to var_dump in PHP?
Most modern browsers have a console in their developer tools, useful for this sort of debugging.
console.log(myvar);
Then you will get a nicely mapped out interface of the object/whatever in the console.
Check out the console documentation for more details.
Most common way:
console.log(object);
However I must mention JSON.stringify which is useful to dump variables in non-browser scripts:
console.log( JSON.stringify(object) );
The JSON.stringify function also supports built-in prettification as pointed out by Simon Zyx.
Example:
var obj = {x: 1, y: 2, z: 3};
console.log( JSON.stringify(obj, null, 2) ); // spacing level = 2
The above snippet will print:
{
"x": 1,
"y": 2,
"z": 3
}
On caniuse.com you can view the browsers that support natively the JSON.stringify function: http://caniuse.com/json
You can also use the Douglas Crockford library to add JSON.stringify support on old browsers: https://github.com/douglascrockford/JSON-js
Docs for JSON.stringify: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
I hope this helps :-)
I wrote this JS function dump() to work like PHP's var_dump().
To show the contents of the variable in an alert window: dump(variable)
To show the contents of the variable in the web page: dump(variable, 'body')
To just get a string of the variable: dump(variable, 'none')
/* repeatString() returns a string which has been repeated a set number of times */
function repeatString(str, num) {
out = '';
for (var i = 0; i < num; i++) {
out += str;
}
return out;
}
/*
dump() displays the contents of a variable like var_dump() does in PHP. dump() is
better than typeof, because it can distinguish between array, null and object.
Parameters:
v: The variable
howDisplay: "none", "body", "alert" (default)
recursionLevel: Number of times the function has recursed when entering nested
objects or arrays. Each level of recursion adds extra space to the
output to indicate level. Set to 0 by default.
Return Value:
A string of the variable's contents
Limitations:
Can't pass an undefined variable to dump().
dump() can't distinguish between int and float.
dump() can't tell the original variable type of a member variable of an object.
These limitations can't be fixed because these are *features* of JS. However, dump()
*/
function dump(v, howDisplay, recursionLevel) {
howDisplay = (typeof howDisplay === 'undefined') ? "alert" : howDisplay;
recursionLevel = (typeof recursionLevel !== 'number') ? 0 : recursionLevel;
var vType = typeof v;
var out = vType;
switch (vType) {
case "number":
/* there is absolutely no way in JS to distinguish 2 from 2.0
so 'number' is the best that you can do. The following doesn't work:
var er = /^[0-9]+$/;
if (!isNaN(v) && v % 1 === 0 && er.test(3.0)) {
out = 'int';
}
*/
break;
case "boolean":
out += ": " + v;
break;
case "string":
out += "(" + v.length + '): "' + v + '"';
break;
case "object":
//check if null
if (v === null) {
out = "null";
}
//If using jQuery: if ($.isArray(v))
//If using IE: if (isArray(v))
//this should work for all browsers according to the ECMAScript standard:
else if (Object.prototype.toString.call(v) === '[object Array]') {
out = 'array(' + v.length + '): {\n';
for (var i = 0; i < v.length; i++) {
out += repeatString(' ', recursionLevel) + " [" + i + "]: " +
dump(v[i], "none", recursionLevel + 1) + "\n";
}
out += repeatString(' ', recursionLevel) + "}";
}
else {
//if object
let sContents = "{\n";
let cnt = 0;
for (var member in v) {
//No way to know the original data type of member, since JS
//always converts it to a string and no other way to parse objects.
sContents += repeatString(' ', recursionLevel) + " " + member +
": " + dump(v[member], "none", recursionLevel + 1) + "\n";
cnt++;
}
sContents += repeatString(' ', recursionLevel) + "}";
out += "(" + cnt + "): " + sContents;
}
break;
default:
out = v;
break;
}
if (howDisplay == 'body') {
var pre = document.createElement('pre');
pre.innerHTML = out;
document.body.appendChild(pre);
}
else if (howDisplay == 'alert') {
alert(out);
}
return out;
}
The var_dump equivalent in JavaScript? Simply, there isn't one.
But, that doesn't mean you're left helpless. Like some have suggested, use Firebug (or equivalent in other browsers), but unlike what others suggested, don't use console.log when you have a (slightly) better tool console.dir:
console.dir(object)
Prints an interactive listing of all properties of the object. This
looks identical to the view that you would see in the DOM tab.
As others have already mentioned, the best way to debug your variables is to use a modern browser's developer console (e.g. Chrome Developer Tools, Firefox+Firebug, Opera Dragonfly (which now disappeared in the new Chromium-based (Blink) Opera, but as developers say, "Dragonfly is not dead though we cannot give you more information yet").
But in case you need another approach, there's a really useful site called
php.js:
http://phpjs.org/
which provides "JavaScript alternatives to PHP functions" - so you can use them the similar way as you would in PHP. I will copy-paste the appropriate functions to you here, BUT be aware that these codes can get updated on the original site in case some bugs are detected, so I suggest you visiting the phpjs.org site! (Btw. I'm NOT affiliated with the site, but I find it extremely useful.)
var_dump() in JavaScript
Here is the code of the JS-alternative of var_dump():
http://phpjs.org/functions/var_dump/
it depends on the echo() function: http://phpjs.org/functions/echo/
function var_dump() {
// discuss at: http://phpjs.org/functions/var_dump/
// original by: Brett Zamir (http://brett-zamir.me)
// improved by: Zahlii
// improved by: Brett Zamir (http://brett-zamir.me)
// depends on: echo
// note: For returning a string, use var_export() with the second argument set to true
// test: skip
// example 1: var_dump(1);
// returns 1: 'int(1)'
var output = '',
pad_char = ' ',
pad_val = 4,
lgth = 0,
i = 0;
var _getFuncName = function(fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/)
.exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
};
var _repeat_char = function(len, pad_char) {
var str = '';
for (var i = 0; i < len; i++) {
str += pad_char;
}
return str;
};
var _getInnerVal = function(val, thick_pad) {
var ret = '';
if (val === null) {
ret = 'NULL';
} else if (typeof val === 'boolean') {
ret = 'bool(' + val + ')';
} else if (typeof val === 'string') {
ret = 'string(' + val.length + ') "' + val + '"';
} else if (typeof val === 'number') {
if (parseFloat(val) == parseInt(val, 10)) {
ret = 'int(' + val + ')';
} else {
ret = 'float(' + val + ')';
}
}
// The remaining are not PHP behavior because these values only exist in this exact form in JavaScript
else if (typeof val === 'undefined') {
ret = 'undefined';
} else if (typeof val === 'function') {
var funcLines = val.toString()
.split('\n');
ret = '';
for (var i = 0, fll = funcLines.length; i < fll; i++) {
ret += (i !== 0 ? '\n' + thick_pad : '') + funcLines[i];
}
} else if (val instanceof Date) {
ret = 'Date(' + val + ')';
} else if (val instanceof RegExp) {
ret = 'RegExp(' + val + ')';
} else if (val.nodeName) {
// Different than PHP's DOMElement
switch (val.nodeType) {
case 1:
if (typeof val.namespaceURI === 'undefined' || val.namespaceURI === 'http://www.w3.org/1999/xhtml') {
// Undefined namespace could be plain XML, but namespaceURI not widely supported
ret = 'HTMLElement("' + val.nodeName + '")';
} else {
ret = 'XML Element("' + val.nodeName + '")';
}
break;
case 2:
ret = 'ATTRIBUTE_NODE(' + val.nodeName + ')';
break;
case 3:
ret = 'TEXT_NODE(' + val.nodeValue + ')';
break;
case 4:
ret = 'CDATA_SECTION_NODE(' + val.nodeValue + ')';
break;
case 5:
ret = 'ENTITY_REFERENCE_NODE';
break;
case 6:
ret = 'ENTITY_NODE';
break;
case 7:
ret = 'PROCESSING_INSTRUCTION_NODE(' + val.nodeName + ':' + val.nodeValue + ')';
break;
case 8:
ret = 'COMMENT_NODE(' + val.nodeValue + ')';
break;
case 9:
ret = 'DOCUMENT_NODE';
break;
case 10:
ret = 'DOCUMENT_TYPE_NODE';
break;
case 11:
ret = 'DOCUMENT_FRAGMENT_NODE';
break;
case 12:
ret = 'NOTATION_NODE';
break;
}
}
return ret;
};
var _formatArray = function(obj, cur_depth, pad_val, pad_char) {
var someProp = '';
if (cur_depth > 0) {
cur_depth++;
}
var base_pad = _repeat_char(pad_val * (cur_depth - 1), pad_char);
var thick_pad = _repeat_char(pad_val * (cur_depth + 1), pad_char);
var str = '';
var val = '';
if (typeof obj === 'object' && obj !== null) {
if (obj.constructor && _getFuncName(obj.constructor) === 'PHPJS_Resource') {
return obj.var_dump();
}
lgth = 0;
for (someProp in obj) {
lgth++;
}
str += 'array(' + lgth + ') {\n';
for (var key in obj) {
var objVal = obj[key];
if (typeof objVal === 'object' && objVal !== null && !(objVal instanceof Date) && !(objVal instanceof RegExp) &&
!
objVal.nodeName) {
str += thick_pad + '[' + key + '] =>\n' + thick_pad + _formatArray(objVal, cur_depth + 1, pad_val,
pad_char);
} else {
val = _getInnerVal(objVal, thick_pad);
str += thick_pad + '[' + key + '] =>\n' + thick_pad + val + '\n';
}
}
str += base_pad + '}\n';
} else {
str = _getInnerVal(obj, thick_pad);
}
return str;
};
output = _formatArray(arguments[0], 0, pad_val, pad_char);
for (i = 1; i < arguments.length; i++) {
output += '\n' + _formatArray(arguments[i], 0, pad_val, pad_char);
}
this.echo(output);
}
print_r() in JavaScript
Here is the print_r() function:
http://phpjs.org/functions/print_r/
It depends on echo() too.
function print_r(array, return_val) {
// discuss at: http://phpjs.org/functions/print_r/
// original by: Michael White (http://getsprink.com)
// improved by: Ben Bryan
// improved by: Brett Zamir (http://brett-zamir.me)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// input by: Brett Zamir (http://brett-zamir.me)
// depends on: echo
// example 1: print_r(1, true);
// returns 1: 1
var output = '',
pad_char = ' ',
pad_val = 4,
d = this.window.document,
getFuncName = function(fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/)
.exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
};
repeat_char = function(len, pad_char) {
var str = '';
for (var i = 0; i < len; i++) {
str += pad_char;
}
return str;
};
formatArray = function(obj, cur_depth, pad_val, pad_char) {
if (cur_depth > 0) {
cur_depth++;
}
var base_pad = repeat_char(pad_val * cur_depth, pad_char);
var thick_pad = repeat_char(pad_val * (cur_depth + 1), pad_char);
var str = '';
if (typeof obj === 'object' && obj !== null && obj.constructor && getFuncName(obj.constructor) !==
'PHPJS_Resource') {
str += 'Array\n' + base_pad + '(\n';
for (var key in obj) {
if (Object.prototype.toString.call(obj[key]) === '[object Array]') {
str += thick_pad + '[' + key + '] => ' + formatArray(obj[key], cur_depth + 1, pad_val, pad_char);
} else {
str += thick_pad + '[' + key + '] => ' + obj[key] + '\n';
}
}
str += base_pad + ')\n';
} else if (obj === null || obj === undefined) {
str = '';
} else {
// for our "resource" class
str = obj.toString();
}
return str;
};
output = formatArray(array, 0, pad_val, pad_char);
if (return_val !== true) {
if (d.body) {
this.echo(output);
} else {
try {
// We're in XUL, so appending as plain text won't work; trigger an error out of XUL
d = XULDocument;
this.echo('<pre xmlns="http://www.w3.org/1999/xhtml" style="white-space:pre;">' + output + '</pre>');
} catch (e) {
// Outputting as plain text may work in some plain XML
this.echo(output);
}
}
return true;
}
return output;
}
var_export() in JavaScript
You may also find the var_export() alternative useful, which also depends on echo():
http://phpjs.org/functions/var_export/
function var_export(mixed_expression, bool_return) {
// discuss at: http://phpjs.org/functions/var_export/
// original by: Philip Peterson
// improved by: johnrembo
// improved by: Brett Zamir (http://brett-zamir.me)
// input by: Brian Tafoya (http://www.premasolutions.com/)
// input by: Hans Henrik (http://hanshenrik.tk/)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// depends on: echo
// example 1: var_export(null);
// returns 1: null
// example 2: var_export({0: 'Kevin', 1: 'van', 2: 'Zonneveld'}, true);
// returns 2: "array (\n 0 => 'Kevin',\n 1 => 'van',\n 2 => 'Zonneveld'\n)"
// example 3: data = 'Kevin';
// example 3: var_export(data, true);
// returns 3: "'Kevin'"
var retstr = '',
iret = '',
value,
cnt = 0,
x = [],
i = 0,
funcParts = [],
// We use the last argument (not part of PHP) to pass in
// our indentation level
idtLevel = arguments[2] || 2,
innerIndent = '',
outerIndent = '',
getFuncName = function(fn) {
var name = (/\W*function\s+([\w\$]+)\s*\(/)
.exec(fn);
if (!name) {
return '(Anonymous)';
}
return name[1];
};
_makeIndent = function(idtLevel) {
return (new Array(idtLevel + 1))
.join(' ');
};
__getType = function(inp) {
var i = 0,
match, types, cons, type = typeof inp;
if (type === 'object' && (inp && inp.constructor) &&
getFuncName(inp.constructor) === 'PHPJS_Resource') {
return 'resource';
}
if (type === 'function') {
return 'function';
}
if (type === 'object' && !inp) {
// Should this be just null?
return 'null';
}
if (type === 'object') {
if (!inp.constructor) {
return 'object';
}
cons = inp.constructor.toString();
match = cons.match(/(\w+)\(/);
if (match) {
cons = match[1].toLowerCase();
}
types = ['boolean', 'number', 'string', 'array'];
for (i = 0; i < types.length; i++) {
if (cons === types[i]) {
type = types[i];
break;
}
}
}
return type;
};
type = __getType(mixed_expression);
if (type === null) {
retstr = 'NULL';
} else if (type === 'array' || type === 'object') {
outerIndent = _makeIndent(idtLevel - 2);
innerIndent = _makeIndent(idtLevel);
for (i in mixed_expression) {
value = this.var_export(mixed_expression[i], 1, idtLevel + 2);
value = typeof value === 'string' ? value.replace(/</g, '<')
.
replace(/>/g, '>'): value;
x[cnt++] = innerIndent + i + ' => ' +
(__getType(mixed_expression[i]) === 'array' ?
'\n' : '') + value;
}
iret = x.join(',\n');
retstr = outerIndent + 'array (\n' + iret + '\n' + outerIndent + ')';
} else if (type === 'function') {
funcParts = mixed_expression.toString()
.
match(/function .*?\((.*?)\) \{([\s\S]*)\}/);
// For lambda functions, var_export() outputs such as the following:
// '\000lambda_1'. Since it will probably not be a common use to
// expect this (unhelpful) form, we'll use another PHP-exportable
// construct, create_function() (though dollar signs must be on the
// variables in JavaScript); if using instead in JavaScript and you
// are using the namespaced version, note that create_function() will
// not be available as a global
retstr = "create_function ('" + funcParts[1] + "', '" +
funcParts[2].replace(new RegExp("'", 'g'), "\\'") + "')";
} else if (type === 'resource') {
// Resources treated as null for var_export
retstr = 'NULL';
} else {
retstr = typeof mixed_expression !== 'string' ? mixed_expression :
"'" + mixed_expression.replace(/(["'])/g, '\\$1')
.
replace(/\0/g, '\\0') + "'";
}
if (!bool_return) {
this.echo(retstr);
return null;
}
return retstr;
}
echo() in JavaScript
http://phpjs.org/functions/echo/
function echo() {
// discuss at: http://phpjs.org/functions/echo/
// original by: Philip Peterson
// improved by: echo is bad
// improved by: Nate
// improved by: Brett Zamir (http://brett-zamir.me)
// improved by: Brett Zamir (http://brett-zamir.me)
// improved by: Brett Zamir (http://brett-zamir.me)
// revised by: Der Simon (http://innerdom.sourceforge.net/)
// bugfixed by: Eugene Bulkin (http://doubleaw.com/)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: EdorFaus
// input by: JB
// note: If browsers start to support DOM Level 3 Load and Save (parsing/serializing),
// note: we wouldn't need any such long code (even most of the code below). See
// note: link below for a cross-browser implementation in JavaScript. HTML5 might
// note: possibly support DOMParser, but that is not presently a standard.
// note: Although innerHTML is widely used and may become standard as of HTML5, it is also not ideal for
// note: use with a temporary holder before appending to the DOM (as is our last resort below),
// note: since it may not work in an XML context
// note: Using innerHTML to directly add to the BODY is very dangerous because it will
// note: break all pre-existing references to HTMLElements.
// example 1: echo('<div><p>abc</p><p>abc</p></div>');
// returns 1: undefined
var isNode = typeof module !== 'undefined' && module.exports && typeof global !== "undefined" && {}.toString.call(
global) == '[object global]';
if (isNode) {
var args = Array.prototype.slice.call(arguments);
return console.log(args.join(' '));
}
var arg = '';
var argc = arguments.length;
var argv = arguments;
var i = 0;
var holder, win = this.window;
var d = win.document;
var ns_xhtml = 'http://www.w3.org/1999/xhtml';
// If we're in a XUL context
var ns_xul = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
var stringToDOM = function(str, parent, ns, container) {
var extraNSs = '';
if (ns === ns_xul) {
extraNSs = ' xmlns:html="' + ns_xhtml + '"';
}
var stringContainer = '<' + container + ' xmlns="' + ns + '"' + extraNSs + '>' + str + '</' + container + '>';
var dils = win.DOMImplementationLS;
var dp = win.DOMParser;
var ax = win.ActiveXObject;
if (dils && dils.createLSInput && dils.createLSParser) {
// Follows the DOM 3 Load and Save standard, but not
// implemented in browsers at present; HTML5 is to standardize on innerHTML, but not for XML (though
// possibly will also standardize with DOMParser); in the meantime, to ensure fullest browser support, could
// attach http://svn2.assembla.com/svn/brettz9/DOMToString/DOM3.js (see http://svn2.assembla.com/svn/brettz9/DOMToString/DOM3.xhtml for a simple test file)
var lsInput = dils.createLSInput();
// If we're in XHTML, we'll try to allow the XHTML namespace to be available by default
lsInput.stringData = stringContainer;
// synchronous, no schema type
var lsParser = dils.createLSParser(1, null);
return lsParser.parse(lsInput)
.firstChild;
} else if (dp) {
// If we're in XHTML, we'll try to allow the XHTML namespace to be available by default
try {
var fc = new dp()
.parseFromString(stringContainer, 'text/xml');
if (fc && fc.documentElement && fc.documentElement.localName !== 'parsererror' && fc.documentElement.namespaceURI !==
'http://www.mozilla.org/newlayout/xml/parsererror.xml') {
return fc.documentElement.firstChild;
}
// If there's a parsing error, we just continue on
} catch (e) {
// If there's a parsing error, we just continue on
}
} else if (ax) {
// We don't bother with a holder in Explorer as it doesn't support namespaces
var axo = new ax('MSXML2.DOMDocument');
axo.loadXML(str);
return axo.documentElement;
}
/*else if (win.XMLHttpRequest) {
// Supposed to work in older Safari
var req = new win.XMLHttpRequest;
req.open('GET', 'data:application/xml;charset=utf-8,'+encodeURIComponent(str), false);
if (req.overrideMimeType) {
req.overrideMimeType('application/xml');
}
req.send(null);
return req.responseXML;
}*/
// Document fragment did not work with innerHTML, so we create a temporary element holder
// If we're in XHTML, we'll try to allow the XHTML namespace to be available by default
//if (d.createElementNS && (d.contentType && d.contentType !== 'text/html')) {
// Don't create namespaced elements if we're being served as HTML (currently only Mozilla supports this detection in true XHTML-supporting browsers, but Safari and Opera should work with the above DOMParser anyways, and IE doesn't support createElementNS anyways)
if (d.createElementNS && // Browser supports the method
(d.documentElement.namespaceURI || // We can use if the document is using a namespace
d.documentElement.nodeName.toLowerCase() !== 'html' || // We know it's not HTML4 or less, if the tag is not HTML (even if the root namespace is null)
(d.contentType && d.contentType !== 'text/html') // We know it's not regular HTML4 or less if this is Mozilla (only browser supporting the attribute) and the content type is something other than text/html; other HTML5 roots (like svg) still have a namespace
)) {
// Don't create namespaced elements if we're being served as HTML (currently only Mozilla supports this detection in true XHTML-supporting browsers, but Safari and Opera should work with the above DOMParser anyways, and IE doesn't support createElementNS anyways); last test is for the sake of being in a pure XML document
holder = d.createElementNS(ns, container);
} else {
// Document fragment did not work with innerHTML
holder = d.createElement(container);
}
holder.innerHTML = str;
while (holder.firstChild) {
parent.appendChild(holder.firstChild);
}
return false;
// throw 'Your browser does not support DOM parsing as required by echo()';
};
var ieFix = function(node) {
if (node.nodeType === 1) {
var newNode = d.createElement(node.nodeName);
var i, len;
if (node.attributes && node.attributes.length > 0) {
for (i = 0, len = node.attributes.length; i < len; i++) {
newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i].nodeName));
}
}
if (node.childNodes && node.childNodes.length > 0) {
for (i = 0, len = node.childNodes.length; i < len; i++) {
newNode.appendChild(ieFix(node.childNodes[i]));
}
}
return newNode;
} else {
return d.createTextNode(node.nodeValue);
}
};
var replacer = function(s, m1, m2) {
// We assume for now that embedded variables do not have dollar sign; to add a dollar sign, you currently must use {$$var} (We might change this, however.)
// Doesn't cover all cases yet: see http://php.net/manual/en/language.types.string.php#language.types.string.syntax.double
if (m1 !== '\\') {
return m1 + eval(m2);
} else {
return s;
}
};
this.php_js = this.php_js || {};
var phpjs = this.php_js;
var ini = phpjs.ini;
var obs = phpjs.obs;
for (i = 0; i < argc; i++) {
arg = argv[i];
if (ini && ini['phpjs.echo_embedded_vars']) {
arg = arg.replace(/(.?)\{?\$(\w*?\}|\w*)/g, replacer);
}
if (!phpjs.flushing && obs && obs.length) {
// If flushing we output, but otherwise presence of a buffer means caching output
obs[obs.length - 1].buffer += arg;
continue;
}
if (d.appendChild) {
if (d.body) {
if (win.navigator.appName === 'Microsoft Internet Explorer') {
// We unfortunately cannot use feature detection, since this is an IE bug with cloneNode nodes being appended
d.body.appendChild(stringToDOM(ieFix(arg)));
} else {
var unappendedLeft = stringToDOM(arg, d.body, ns_xhtml, 'div')
.cloneNode(true); // We will not actually append the div tag (just using for providing XHTML namespace by default)
if (unappendedLeft) {
d.body.appendChild(unappendedLeft);
}
}
} else {
// We will not actually append the description tag (just using for providing XUL namespace by default)
d.documentElement.appendChild(stringToDOM(arg, d.documentElement, ns_xul, 'description'));
}
} else if (d.write) {
d.write(arg);
} else {
console.log(arg);
}
}
}
Firebug.
Then, in your javascript:
var blah = {something: 'hi', another: 'noway'};
console.debug("Here is blah: %o", blah);
Now you can look at the console, click on the statement and see what is inside blah
A nice simple solution for parsing a JSON Response to HTML.
var json_response = jQuery.parseJSON(data);
html_response += 'JSON Response:<br />';
jQuery.each(json_response, function(k, v) {
html_response += outputJSONReponse(k, v);
});
function outputJSONReponse(k, v) {
var html_response = k + ': ';
if(jQuery.isArray(v) || jQuery.isPlainObject(v)) {
jQuery.each(v, function(j, w) {
html_response += outputJSONReponse(j, w);
});
} else {
html_response += v + '<br />';
}
return html_response;
}
You could also try this function. I can't remember the original author, but all credits go to them.
Works like a charm - 100% the same as var_dump in PHP.
Check it out.
function dump(arr,level) {
var dumped_text = "";
if(!level) level = 0;
//The padding given at the beginning of the line.
var level_padding = "";
for(var j=0;j<level+1;j++) level_padding += " ";
if(typeof(arr) == 'object') { //Array/Hashes/Objects
for(var item in arr) {
var value = arr[item];
if(typeof(value) == 'object') { //If it is an array,
dumped_text += level_padding + "'" + item + "' ...\n";
dumped_text += dump(value,level+1);
} else {
dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
}
}
} else { //Stings/Chars/Numbers etc.
dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
}
return dumped_text;
}
// Example:
var employees = [
{ id: '1', sex: 'm', city: 'Paris' },
{ id: '2', sex: 'f', city: 'London' },
{ id: '3', sex: 'f', city: 'New York' },
{ id: '4', sex: 'm', city: 'Moscow' },
{ id: '5', sex: 'm', city: 'Berlin' }
]
// Open dev console (F12) to see results:
console.log(dump(employees));
I put this forward to help anyone needing something readily practical for giving you a nice, prettified (indented) picture of a JS Node. None of the other solutions worked for me for a Node ("cyclical error" or whatever...). This walks you through the tree under the DOM Node (without using recursion) and gives you the depth, tagName (if applicable) and textContent (if applicable).
Any other details from the nodes you encounter as you walk the tree under the head node can be added as per your interest...
function printRNode( node ){
// make sort of human-readable picture of the node... a bit like PHP print_r
if( node === undefined || node === null ){
throwError( 'node was ' + typeof node );
}
let s = '';
// NB walkDOM could be made into a utility function which you could
// call with one or more callback functions as parameters...
function walkDOM( headNode ){
const stack = [ headNode ];
const depthCountDowns = [ 1 ];
while (stack.length > 0) {
const node = stack.pop();
const depth = depthCountDowns.length - 1;
// TODO non-text, non-BR nodes could show more details (attributes, properties, etc.)
const stringRep = node.nodeType === 3? 'TEXT: |' + node.nodeValue + '|' : 'tag: ' + node.tagName;
s += ' '.repeat( depth ) + stringRep + '\n';
const lastIndex = depthCountDowns.length - 1;
depthCountDowns[ lastIndex ] = depthCountDowns[ lastIndex ] - 1;
if( node.childNodes.length ){
depthCountDowns.push( node.childNodes.length );
stack.push( ... Array.from( node.childNodes ).reverse() );
}
while( depthCountDowns[ depthCountDowns.length - 1 ] === 0 ){
depthCountDowns.splice( -1 );
}
}
}
walkDOM( node );
return s;
}

Categories

Resources