I have the following string:
let disposibleHTML = "<html>cid1=2&cid2=3&seqno=4&tdate=20220616&ttime=11355525&cname=Test E&payment_method=&payon=33&amount=5&productcode=gp&PaymentStatus=Approved</html>";
I would like it to be as such:
{
"cid1": "2",
"cid2": "3",
"seqno": "4",
// and so on
}
Here is my current approach:
let n = disposibleHTML.replace('<html>', '');
let splitedArray = n.split("&");
let json = { ...splitedArray }
console.log(json);
Which produces the output below:
{0: 'cid1=1122', 1: 'cid2=2', 2: 'seqno=3', 3: 'tdate=20220616', 4: 'ttime=11355525', 5: 'cname=Test ECSI', 6: 'payment_method=', 7: 'payon=4', 8: 'amount=5', 9: 'productcode=ff', 10: 'PaymentStatus=Approved</html>'}
How can I fix this issue and get the desired output?
CodePudding user response:
You can clean up the string and use URLSearchParams to get the values.
const disposibleHTML = "<html>cid1=2&cid2=3&seqno=4&tdate=20220616&ttime=11355525&cname=Test E&payment_method=&payon=33&amount=5&productcode=gp&PaymentStatus=Approved</html>";
const result = Object.fromEntries(new URLSearchParams(disposibleHTML.replace(/<\/?html>/g, '').replace(/&/g,'&')));
// everything as strings
console.log(result);
If you want them as numbers you can add some more processing.
const disposibleHTML = "<html>cid1=2&cid2=3&seqno=4&tdate=20220616&ttime=11355525&cname=Test E&payment_method=&payon=33&amount=5&productcode=gp&PaymentStatus=Approved</html>";
const result = Object.fromEntries(new URLSearchParams(disposibleHTML.replace(/<\/?html>/g, '').replace(/&/g,'&')));
Object.entries(result).forEach(([key, value]) => {
if(isFinite(value)) result[key] = value;
});
// everything as strings
console.log(result);
CodePudding user response:
I'd use reduce for that:
let disposibleHTML = "<html>cid1=2&cid2=3&seqno=4&tdate=20220616&ttime=11355525&cname=Test E&payment_method=&payon=33&amount=5&productcode=gp&PaymentStatus=Approved</html>";
let n = disposibleHTML.replace('<html>', '').replace('</html>', '');
let splitedArray = n.split("&");
let json = splitedArray.reduce((p, c) => {let t = c.split('='); p[t[0]] = t[1]; return p;}, {});
console.log(json);
CodePudding user response:
Sightly ugly but should suffice:
const str = "<html>cid1=2&cid2=3&seqno=4&tdate=20220616&ttime=11355525&cname=Test E&payment_method=&payon=33&amount=5&productcode=gp&PaymentStatus=Approved</html>";
const obj = JSON.parse("{" str.replace('<html>', '').replace('</html>', '').replaceAll('amp;', '').split('&').map(e => e.split('=').map(f => `"${f}"`).join(':')).join(',') "}");
console.log(obj);
CodePudding user response:
I went about it in a different way than others .. Just because:
let disposibleHTML = "<html>cid1=2&cid2=3&seqno=4&tdate=20220616&ttime=11355525&cname=Test E&payment_method=&payon=33&amount=5&productcode=gp&PaymentStatus=Approved</html>";
let n = disposibleHTML.replace('<html>', '');
n = n.replace('</html>', '');
let splitedArray = n.split("&");
const mainArr = [];
let count = 0;
for (const item of splitedArray) {
item.replace('"', '');
items = item.split('=');
mainArr[count] = items;
count ;
}
let finalJSON = JSON.parse(JSON.stringify(mainArr));
console.log(finalJSON);
CodePudding user response:
Similar idea but perhaps slightly more understandable. Basically we split the string on &
, thus constructing an array like ["cid1=2", "cid2=3", ...]
. Then we loop over each item in the array using Array.reduce
, split the the item on the =
sign, and append that to an object.
let disposibleHTML = "<html>cid1=2&cid2=3&seqno=4&tdate=20220616&ttime=11355525&cname=Test E&payment_method=&payon=33&amount=5&productcode=gp&PaymentStatus=Approved</html>";
let n = disposibleHTML.replace('<html>', '').replace('</html>', '');
let splitedArray = n.split("&");
let keyMap = [...splitedArray];
const json = keyMap.reduce((values, item) => {
const [key, value] = item.split("=");
return {
...values,
[key]: value
}
}, {})
console.log(json)
CodePudding user response:
Using String.prototype.replace
and .split
and other surprisingly nontrivial string operations is not the best way to process string input (in fact, if you ever catch yourself using split
it means you're probably doing something wrong, even for CSV (i.e. split(',')
) because a CSV value can contain a comma when enclosed in quotes).
Also, you're processing what looks like HTML-encoded application/x-www-form-urlencoded
-data contained within a dummy <html>
element.
I think the best approach would be to use JavaScript DOM's built-in HTML decoding abilities, then use URLSearchParams
to correctly parse the application/x-www-form-urlencoded
data out, then build a JS object
by enumerating over name/value pairs, like so:
let disposibleHTML = "<html>cid1=2&cid2=3&seqno=4&tdate=20220616&ttime=11355525&cname=Test E&payment_method=&payon=33&amount=5&productcode=gp&PaymentStatus=Approved</html>";
function run() {
const urlEncodedParams = htmlDecode( disposibleHTML );
const obj = urlParamsToJSObject( urlEncodedParams );
console.log( "urlencoding to JS object: %o", obj );
}
run();
function htmlDecode( html ) {
const el = document.createElement('div')
el.innerHTML = disposibleHTML;
return el.textContent;
}
function urlParamsToJSObject( p ) {
let parsed;
try {
parsed = new URLSearchParams( p );
}
catch( err ) {
console.error( err );
throw new Error( "Couldn't parse URL-encoded text: " err );// err; // TODO: Better handling?
}
//
const obj = {};
for( const key of parsed.keys() ) {
const firstValue = parsed.get( key );
obj[ key ] = firstValue;
}
return obj;
}