Given (as a post response body):
RESULT: OK
RESULT_PS: FINISHED
RESULT_CODE: 000
I need to serialize it to json, I use node's request to get this from server.
Surely I can parse it string by string.
But isn't there an easier way?
Maybe ready serializer or something to serialize such data to JSON?
What format is this?
filter each line from following code
var jsonObject = {}
function parser(str){
var arr = str.split(":");
jsonObject[arr[0]] = arr[1];
}
your final jsonObject is json you needed.
Make sure that you need to pass RESULT: OK, RESULT_PS: FINISHED,RESULT_CODE: 000 as seperate strings from parser.
As far as I can tell, this is just a delimited plain text response. (Where are you getting it from? Transaction response?) However, since it's that simple it's easily parseable with a quick map-reduce operation.
function trim(str) {
return str.replace(/^\s+|\s+$/g, "");
}
function nonEmpty(str) {
return null != str && str.length > 0;
}
function splitKeyValue(row) {
var tokens = row.split(":").map(trim);
// My assumption that a row should only contain 2 colon separated tokens
if (tokens.length > 2) {
throw new Error("Malformed row: " + row);
}
return tokens;
}
function merge(acc, item) {
// Normalise key to lower case, to guarantee spelling
acc[item[0].toLowerCase()] = item[1];
return acc;
}
function parseResponse(payload) {
return payload.split("\n").
filter(nonEmpty).
map(splitKeyValue).
reduce(merge, {});
}
Using the snippet of code above, the result should be:
var payload =
"RESULT: OK\n" +
"RESULT_PS: FINISHED\n" +
"RESULT_CODE: 000\n";
var parsed = parseResponse(payload);
console.log(parsed);
// Output:
// {
// result: "OK",
// result_ps: "FINISHED",
// result_code: "000"
// }
// Each separate field is then accessible from it's name
console.log(parsed.result); // Output: "OK"
Ok, didn't find any ready solution.
So wrote this function:
parseResponse = function(response) {
var result = { };
response.replace(/([^\s:]+)\s*:\s*([^\n\s]+)/gi, function() {
var key = arguments[1], value = decodeURIComponent(arguments[2]);
result[key] = !isNaN(parseFloat(value)) && isFinite(value) ? parseFloat(value) : value;
});
return result;
}
If you use node.js there is handy module called querystring:
const querystring = require('querystring'),
payload =
"RESULT: OK\n\r" +
"RESULT_PS: FINISHED\n" +
"RESULT_CODE: 000\n";
let parsed = querystring.parse(payload, '\n', ':', {decodeURIComponent: s => s.trim()});
console.log(parsed);
For browsers there is a lot of good methods described in answers. Here is another one (vanilla JS):
var payload =
"RESULT: OK\n\r" +
"RESULT_PS: FINISHED\n" +
"RESULT_CODE: 000\n";
var browserParsed = payload.split("\n")
.map(function (s) {
return s.trim().split(":");
})
.filter(function (s) {
return s.length && s.length > 1;
})
.reduce(function (acc, c) {
acc[ c[ 0 ].trim() ] = c[ 1 ].trim();
return acc;
}, {});
console.log(browserParsed);
Related
I have the following querystring which is a IPN by wirecard, so i can't modify this input, this is what i receive in the POST.
I have no clue why is this being sent as text/plain instead of application/json
https://doc.wirecard.com/GeneralPlatformFeatures.html#GeneralPlatformFeatures_IPN
response-signature-base64=sGwuDEpTnTB7XwzPga8DG+pYYjB3bga7YOZI8n26yOns=&response-signature-algorithm=HmacSHA256&response-base64=eyJwYXltZW50Ijp7InN0YXR1c2VzIjp7InN0YXR1cyI6W3siY29kZSI6Ij
IwMS4wMDAwIiwiZGVzY3JpcHRpb24iOiIzZC1hY3F1aXJlcjpUaGUgcmVzb3VyY2Ugd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiIsInNldmVyaXR5IjoiaW5mb3JtYXRpb24ifV19LCJjYXJkIjp7ImV4cGlyYXRpb24tbW9udGgiOjEsImV4cGl
yYXRpb24teWVhciI6MjAyMywiY2FyZC10eXBlIjoidmlzYSJ9LCJkZXNjcmlwdG9yIjoiIiwibm90aWZpY2F0aW9ucyI6eyJub3RpZmljYXRpb24iOlt7InVybCI6Imh0dHBzOi8vNDY0Yjk4N2M2ZDk5Lm5ncm9rLmlvL3B1YmxpY3Mvd2lyZWNh
cmQyIn1dLCJmb3JtYXQiOiJhcHBsaWNhdGlvbi9qc29uLXNpZ25lZCJ9LCJtZXJjaGFudC1hY2NvdW50LWlkIjp7InZhbHVlIjoiN2E2ZGQ3NGYtMDZhYi00ZjNmLWE4NjQtYWRjNTI2ODcyNzBhIn0sInRyYW5zYWN0aW9uLWlkIjoiOTQwNGIxN
jQtMTgzYy00ZjllLThmNGEtN2QzMGUxODA2ZWRjIiwicmVxdWVzdC1pZCI6Ijk3NzJiMzViLTdmYmUtNGYxZS04NmQ5LThhNjMwZDljZDg3YyIsInRyYW5zYWN0aW9uLXR5cGUiOiJwdXJjaGFzZSIsInRyYW5zYWN0aW9uLXN0YXRlIjoic3VjY2
VzcyIsImNvbXBsZXRpb24tdGltZS1zdGFtcCI6MTU5NTkyNDA0OTAwMCwicmVxdWVzdGVkLWFtb3VudCI6eyJ2YWx1ZSI6MTAsImN1cnJlbmN5IjoiVVNEIn0sImFjY291bnQtaG9sZGVyIjp7ImZpcnN0LW5hbWUiOiJkIiwibGFzdC1uYW1lIjo
iZCJ9LCJjYXJkLXRva2VuIjp7InRva2VuLWlkIjoiNDI0Mjc5NjQ0NDA5MDAxOCIsIm1hc2tlZC1hY2NvdW50LW51bWJlciI6IjQyMDAwMCoqKioqKjAwMTgifSwicGF5bWVudC1tZXRob2RzIjp7InBheW1lbnQtbWV0aG9kIjpbeyJuYW1lIjoi
Y3JlZGl0Y2FyZCJ9XX0sImF1dGhvcml6YXRpb24tY29kZSI6IjE0Mzk3NyIsImFwaS1pZCI6IndwcCIsImNhbmNlbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvY2FuY2VsIiwiZ
mFpbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvZXJyb3IiLCJzdWNjZXNzLXJlZGlyZWN0LXVybCI6Imh0dHBzOi8vZGVtb3Nob3AtdGVzdC53aXJlY2FyZC5jb20vZGVtb3Nob3
AvIy9zdWNjZXNzIiwicHJvdmlkZXItYWNjb3VudC1pZCI6IjcwMDEwIn19
As you can see the query parameters are base64 encoded, which is a problem because it includes + and = that are going to break if use URLSearchParams or any other method of converting .
I tried using bodyparser.urlencoded but this transforms '+' to ' '
how can i split this safely while keeping the 3 variables intact
response-signature-base64
response-signature-algorithm
response-base64
If the URL Web API available you could create a URL and read the searchParams from it.
If not you can use Javascripts split() function using the limit argument:
queryString.split('&').map((value) => value.split('=', 2));
if an array of arrays is not what you want you can append an other processing step and do something like this:
queryString
.split('&').map((value) => value.split('=', 2))
.reduce((obj, value) => {
obj[value[0]] = value[1];
return obj;
}, {});
the following snippet shows the code in action
const queryString = 'response-signature-base64=sGwuDEpTnTB7XwzPga8DG+pYYjB3bga7YOZI8n26yOns=&response-signature-algorithm=HmacSHA256&response-base64=eyJwYXltZW50Ijp7InN0YXR1c2VzIjp7InN0YXR1cyI6W3siY29kZSI6IjIwMS4wMDAwIiwiZGVzY3JpcHRpb24iOiIzZC1hY3F1aXJlcjpUaGUgcmVzb3VyY2Ugd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiIsInNldmVyaXR5IjoiaW5mb3JtYXRpb24ifV19LCJjYXJkIjp7ImV4cGlyYXRpb24tbW9udGgiOjEsImV4cGlyYXRpb24teWVhciI6MjAyMywiY2FyZC10eXBlIjoidmlzYSJ9LCJkZXNjcmlwdG9yIjoiIiwibm90aWZpY2F0aW9ucyI6eyJub3RpZmljYXRpb24iOlt7InVybCI6Imh0dHBzOi8vNDY0Yjk4N2M2ZDk5Lm5ncm9rLmlvL3B1YmxpY3Mvd2lyZWNhcmQyIn1dLCJmb3JtYXQiOiJhcHBsaWNhdGlvbi9qc29uLXNpZ25lZCJ9LCJtZXJjaGFudC1hY2NvdW50LWlkIjp7InZhbHVlIjoiN2E2ZGQ3NGYtMDZhYi00ZjNmLWE4NjQtYWRjNTI2ODcyNzBhIn0sInRyYW5zYWN0aW9uLWlkIjoiOTQwNGIxNjQtMTgzYy00ZjllLThmNGEtN2QzMGUxODA2ZWRjIiwicmVxdWVzdC1pZCI6Ijk3NzJiMzViLTdmYmUtNGYxZS04NmQ5LThhNjMwZDljZDg3YyIsInRyYW5zYWN0aW9uLXR5cGUiOiJwdXJjaGFzZSIsInRyYW5zYWN0aW9uLXN0YXRlIjoic3VjY2VzcyIsImNvbXBsZXRpb24tdGltZS1zdGFtcCI6MTU5NTkyNDA0OTAwMCwicmVxdWVzdGVkLWFtb3VudCI6eyJ2YWx1ZSI6MTAsImN1cnJlbmN5IjoiVVNEIn0sImFjY291bnQtaG9sZGVyIjp7ImZpcnN0LW5hbWUiOiJkIiwibGFzdC1uYW1lIjoiZCJ9LCJjYXJkLXRva2VuIjp7InRva2VuLWlkIjoiNDI0Mjc5NjQ0NDA5MDAxOCIsIm1hc2tlZC1hY2NvdW50LW51bWJlciI6IjQyMDAwMCoqKioqKjAwMTgifSwicGF5bWVudC1tZXRob2RzIjp7InBheW1lbnQtbWV0aG9kIjpbeyJuYW1lIjoiY3JlZGl0Y2FyZCJ9XX0sImF1dGhvcml6YXRpb24tY29kZSI6IjE0Mzk3NyIsImFwaS1pZCI6IndwcCIsImNhbmNlbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvY2FuY2VsIiwiZmFpbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvZXJyb3IiLCJzdWNjZXNzLXJlZGlyZWN0LXVybCI6Imh0dHBzOi8vZGVtb3Nob3AtdGVzdC53aXJlY2FyZC5jb20vZGVtb3Nob3AvIy9zdWNjZXNzIiwicHJvdmlkZXItYWNjb3VudC1pZCI6IjcwMDEwIn19'
const result = queryString
.split('&').map((value) => value.split('=', 2))
.reduce((obj, value) => {
obj[value[0]] = value[1];
return obj;
}, {});
console.log(result)
ALMOST, but not quite, using this code
function fromBinary(binary) {
console.log(binary.length)
if (binary.length%2 != 0) binary += "="; // my hack - may not work
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < bytes.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return String.fromCharCode(...new Uint16Array(bytes.buffer));
};
const str = `response-signature-base64=sGwuDEpTnTB7XwzPga8DG+pYYjB3bga7YOZI8n26yOns=&response-signature-algorithm=HmacSHA256&response-base64=eyJwYXltZW50Ijp7InN0YXR1c2VzIjp7InN0YXR1cyI6W3siY29kZSI6Ij
IwMS4wMDAwIiwiZGVzY3JpcHRpb24iOiIzZC1hY3F1aXJlcjpUaGUgcmVzb3VyY2Ugd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiIsInNldmVyaXR5IjoiaW5mb3JtYXRpb24ifV19LCJjYXJkIjp7ImV4cGlyYXRpb24tbW9udGgiOjEsImV4cGl
yYXRpb24teWVhciI6MjAyMywiY2FyZC10eXBlIjoidmlzYSJ9LCJkZXNjcmlwdG9yIjoiIiwibm90aWZpY2F0aW9ucyI6eyJub3RpZmljYXRpb24iOlt7InVybCI6Imh0dHBzOi8vNDY0Yjk4N2M2ZDk5Lm5ncm9rLmlvL3B1YmxpY3Mvd2lyZWNh
cmQyIn1dLCJmb3JtYXQiOiJhcHBsaWNhdGlvbi9qc29uLXNpZ25lZCJ9LCJtZXJjaGFudC1hY2NvdW50LWlkIjp7InZhbHVlIjoiN2E2ZGQ3NGYtMDZhYi00ZjNmLWE4NjQtYWRjNTI2ODcyNzBhIn0sInRyYW5zYWN0aW9uLWlkIjoiOTQwNGIxN
jQtMTgzYy00ZjllLThmNGEtN2QzMGUxODA2ZWRjIiwicmVxdWVzdC1pZCI6Ijk3NzJiMzViLTdmYmUtNGYxZS04NmQ5LThhNjMwZDljZDg3YyIsInRyYW5zYWN0aW9uLXR5cGUiOiJwdXJjaGFzZSIsInRyYW5zYWN0aW9uLXN0YXRlIjoic3VjY2
VzcyIsImNvbXBsZXRpb24tdGltZS1zdGFtcCI6MTU5NTkyNDA0OTAwMCwicmVxdWVzdGVkLWFtb3VudCI6eyJ2YWx1ZSI6MTAsImN1cnJlbmN5IjoiVVNEIn0sImFjY291bnQtaG9sZGVyIjp7ImZpcnN0LW5hbWUiOiJkIiwibGFzdC1uYW1lIjo
iZCJ9LCJjYXJkLXRva2VuIjp7InRva2VuLWlkIjoiNDI0Mjc5NjQ0NDA5MDAxOCIsIm1hc2tlZC1hY2NvdW50LW51bWJlciI6IjQyMDAwMCoqKioqKjAwMTgifSwicGF5bWVudC1tZXRob2RzIjp7InBheW1lbnQtbWV0aG9kIjpbeyJuYW1lIjoi
Y3JlZGl0Y2FyZCJ9XX0sImF1dGhvcml6YXRpb24tY29kZSI6IjE0Mzk3NyIsImFwaS1pZCI6IndwcCIsImNhbmNlbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvY2FuY2VsIiwiZ
mFpbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvZXJyb3IiLCJzdWNjZXNzLXJlZGlyZWN0LXVybCI6Imh0dHBzOi8vZGVtb3Nob3AtdGVzdC53aXJlY2FyZC5jb20vZGVtb3Nob3
AvIy9zdWNjZXNzIiwicHJvdmlkZXItYWNjb3VudC1pZCI6IjcwMDEwIn19`
console.log([...new URLSearchParams(str).values()].map(val => fromBinary(atob(val))))
I have some data i am pulling from a web service. This is the string
(Body:'3886' MessageProperties [headers={}, timestamp=null,
messageId=null, userId=null, receivedUserId=null, appId=null,
clusterId=null, type=null, correlationId=null,
correlationIdString=null, replyTo=null,
contentType=application/x-java-serialized-object,
contentEncoding=null, contentLength=0, deliveryMode=null,
receivedDeliveryMode=PERSISTENT, expiration=null, priority=0,
redelivered=false, receivedExchange=,
receivedRoutingKey=bottomlesspit, receivedDelay=null, deliveryTag=62,
messageCount=0, consumerTag=amq.ctag-sCwfLaMEqWp2GkFwFrY1yg,
consumerQueue=bottomlesspit])
It looks like json but the key value pairs are almost fine but the most important key which is Body isn't like other keys as the string would tell.
I need to read the value of Body and be able to get the value like this
console.log(d.body);
//This above outputs the string as shown
obj = eval('{' + d.body + '}');
console.log(obj);
var match = "Body";
var val = obj.find( function(item) { return item.key == match } );
console.log(val);
How can i read the value of the key Body?.
Use this regular expression instead of a match Body:
\bBody:'(\d*)'
This will catch the Body number in group 1.
You can write a parser function get string and extract values. A very simple function is here. You can modify it also for all exceptions exist.
var str = `(Body:'3886' MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null, correlationIdString=null, replyTo=null, contentType=application/x-java-serialized-object, contentEncoding=null, contentLength=0, deliveryMode=null, receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=, receivedRoutingKey=bottomlesspit, receivedDelay=null, deliveryTag=62, messageCount=0, consumerTag=amq.ctag-sCwfLaMEqWp2GkFwFrY1yg, consumerQueue=bottomlesspit])`;
function f(inp) {
var index = str.indexOf(inp),
endIndex;
for(var i = index; i < str.length; i ++) {
if(str[i] == ',') {
endIndex = i;
break;
}
}
var output = str.substr(index, endIndex).split('=');
return output;
}
console.log(f('consumerQueue'));
Why not use a regex to match and extract the Body.
Example:
const match = d.body.match(/Body:\'(.+)\'/)
if (match) {
const body = match[1] // This is the value of Body
} else {
// Unable to find Body, handle it here
}
I looked through a number of posts (and other websites) and I seem to have a hit a roadblock. I have the following array:
var data_dictionary = ["youtube.com", "facebook.com", "youtube.com/feed/subscriptions", "twitter.com"]
I'm trying to return data for everything that has youtube.com*. Below is the relevant snippet of my function:
var result = []
for (var i=0; i<data_dictionary.length; i++) {
if (data_dictionary[i].page == /^youtube.com/) {
result.push (data_dictionary[i].page,data_dictionary[i].share)
}
}
break;
}
return result
The problematic area is in the if clause (/^youtube.com/). How can I receive the following return:
["youtube.com" , "youtube.com/feed/subscriptions"]
You can use Array.prototype.filter() method to filter array and RegExp.prototype.test() to check for match.
var data_dictionary = ["youtube.com", "facebook.com", "youtube.com/feed/subscriptions", "twitter.com"];
function check(data_dictionary) {
return data_dictionary.filter(function(v) {
return /^youtube\.com/.test(v);
// using indexOf
// v.indexOf('youtube.com') == 0;
});
}
console.log(check(data_dictionary));
FYI: Your if condition will be only true if the string is '/^youtube.com/'. ie, ('/^youtube.com/' == /^youtube.com/) === true. Your code will work if you changed the if condition to /^youtube.com/.test(data_dictionary[i]). Also in the provided data page and share properties are undefined only plain strings are the element.
Using the same approach that you had before. However using ".filter" won't be a bad idea, but I will suggest you compare their benchmark
var data_dictionary = ["youtube.com", "facebook.com", "youtube.com/feed/subscriptions", "twitter.com"];
var pattern = /^youtube.com/;
var result = [];
var i = 0;
function loop (args) {
for (i; i < args.length; i++) {
if (pattern.test(args[i])) {
result.push(args[i]);
}
}
return result;
}
console.log(loop(data_dictionary)) // ["youtube.com" , "youtube.com/feed/subscriptions"]
Comparing the speed below I would suggest you use the approach above
No need for regex here you can do like this;
var data_dictionary = ["youtube.com", "facebook.com", "youtube.com/feed/subscriptions", "twitter.com"],
filtered = data_dictionary.filter(e => !!~e.indexOf("youtube.com") && e);
document.write("<pre>" + JSON.stringify(filtered) + "</pre>");
Or if you want a faster solution still with Array methods then
var data_dictionary = ["youtube.com", "facebook.com", "youtube.com/feed/subscriptions", "twitter.com"],
filtered = data_dictionary.reduce((p,c) => !!~c.indexOf("youtube.com") ? p.concat(c):p,[]);
document.write("<pre>" + JSON.stringify(filtered) + "</pre>");
I read a HTML element's property using JavaScript like this:
<table data-option="pageSize:10, pageNumber:1, rowNumber:true"></table>
I will have a string like this:
attrs="pageSize:10, pageNumber:1, rowNumber:true";
I have a key and value JavaScript object like this:
obj={pageSize:12, pageNumber:1, rowNumber:true}
I want to convert my attrs to object like obj.
You could iterate and create the object yourself
var attr = $('table').data('option');
var obj = {};
$.each(attr.split(','), function(index, item) {
var parts = $.map(item.split(':'), function(part) {
part = $.trim(part);
if ( +part == part ) return +part
else if ( part === 'true' ) return true
else if ( part === 'false') return false
else return part;
});
obj[parts[0]] = parts[1];
});
var attr = $('table').data('option');
var obj = {};
$.each(attr.split(','), function(index, item) {
var parts = $.map(item.split(':'), function(part) {
part = $.trim(part);
if ( +part == part ) return +part
else if ( part === 'true' ) return true
else if ( part === 'false') return false
else return part;
});
obj[parts[0]] = parts[1];
});
document.body.innerHTML = '<pre>' + JSON.stringify(obj, null, 4) + '</pre>';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table data-option="pageSize:10, pageNumber:1, rowNumber:true"></table>
Option 1.
Store an entire json-encoded string.
Option 2.
To convert that from string to an object with JSON.parse you'll need double quotes.
Using a regex to add double quotes taken from here, we get the desired result:
attrs = ("{" + attrs + "}").replace(/([{,])(\s*)([A-Za-z0-9_\-]+?)\s*:/g,'$1"$3":');
var obj = JSON.parse(attrs);
UPD:
As mentioned by epascarello, if you have unquoted string values there like name: Jack, this approach would obviously fail. But if you're putting raw strings there, mind that they might contain commas or spaces or whatever, so you'd better quote them
I am trying to traverse a JSON object with jQuery recursive.. normally it worked , but not on the following JSON.
I want to traverse this JSON, here I uploaded an image:
For my json objects, i had this jquery function:
var construct_id = "#ecommerce_form_";
// function to traverse json objects given back from Serializer class
function process(callback, id) {
var key;
for (key in callback) {
// Handle the arrays
if ('length' in callback[key]) {
// Handle the end - we found a string
if (typeof callback[key][0] == "string") {
var field_id = construct_id + id + key;
var err_msg = callback[key][0];
$(field_id).tooltip('destroy');
$(field_id).tooltip({'title': err_msg});
$(field_id).closest('div[class="form-group"]').addClass('has-error');
console.log(field_id, ":", err_msg);
}
// Else we found something else, so recurse.
else {
var i = 0;
while (i < callback[key].length) {
process(callback[key][i], key + "_" + i + "_");
i++;
}
}
}
// Handle the objects by recursing.
else {
process(callback[key], key + "_");
}
}
}
But that functions fails when trying to build the contact > addresses id with the error message:
"Uncaught TypeError: Cannot use 'in' operator to search for 'length'
in This value should not be blank."
Hope you guys can help me enhancing the jQuery function, it is not 100% successfull as you can see on this json example.
Regards
You are trying to search for the property "length" in a string, which can't be done. In the erroneous iteration: callback = obj.contacts.addresses, key = cities and then callback[key][0] = "This value should not be blank".
What you should do is check if you have reached a string before looking for the "length" property, and only then if you haven't found a string, begin the recursion check.
see jsfiddle example here:
http://jsfiddle.net/38d15z4o/
var construct_id = "#ecommerce_form_";
// function to traverse json objects given back from Serializer class
function process(callback, id) {
var key;
for (key in callback) {
// Handle the end - we found a string
if (typeof callback[key] == "string") {
var field_id = construct_id + id + key;
var err_msg = callback[key][0];
$(field_id).tooltip('destroy');
$(field_id).tooltip({'title': err_msg});
$(field_id).closest('div[class="form-group"]').addClass('has-error');
console.log(field_id, ":", err_msg);
}
// Handle the objects and arrays by recursing.
else {
process(callback[key], id + key + "_");
}
}
}
NOTE: for the error message, you are only showing the first letter of the string, I think you meant to put: err_msg = callback[key] not err_msg = callback[key][0].
Why don't you check for
typeof callback[key] === 'array'
Instead checking the length property?