Javascript to fetch json from unordered data - javascript

I have below input code inside script code which comes like a string
The output should be below as a JSON object and extract flags and preference object. Need a solution using regex or any other way
flags = { "onFlag" : true, "offFlag : false }
Preference = { "onPreference" : true, "offPreference : false }

You can use regex to extract data inside the script tag and then parse content in javascript to generate JSON.
const regex = /<script[^>]+>(.*?)<\/script>/gs;
const str = `<script type="text/javascript">
window.__getRoute__=function() {
console.log('hi');
}
window.__LOADED_STATE__ = {
"context": {
"flags": {"onFlag": true, "offFlag": false},
"Preference": {"onPreference": true, "offPreference": false}
}
}
</script>`;
const m = regex.exec(str);
const json = new Function('var window={}; ' + m[1] + ' return window.__LOADED_STATE__')();
console.log(json.context.flags);
console.log(json.context.Preference);

Related

Converting XML to JSON in JS

I just recently started learning js and trying to solve the problem of converting xml source file
<ns1:input xmlns:ns1="ns1:test" xmlns:ns2="ns2:test">
<ns1:element id="1">
<ns2:field1>1</ns2:field1>
<ns2:field2>2</ns2:field2>
<ns2:field3>3</ns2:field3>
</ns1:element>
<ns1:element id="2">
<ns2:field1>4</ns2:field1>
<ns2:field2>5</ns2:field2>
<ns2:field3>6</ns2:field3>
</ns1:element>
</ns1:input>
to json of the following content
{
"elements":[
{
"element":{
"field1":"1",
"field2":"2",
"field3":"3",
"id":"1"
}
},
{
"element":{
"field1":"4",
"field2":"5",
"field3":"6",
"id":"2"
}
}
]
}
using javascript.
I tried to solve the problem using the xml2json library - it turned out not quite what I needed. Can you please tell me how this can be implemented?
Below is code and output
var convert = require('xml-js');
var xml =
'<ns1:input xmlns:ns1="ns1:test" xmlns:ns2="ns2:test">'+
'<ns1:element id="1">'+
'<ns2:field1>1</ns2:field1>'+
'<ns2:field2>2</ns2:field2>'+
'<ns2:field3>3</ns2:field3>' +
'</ns1:element>'+
'<ns1:element id="2">'+
'<ns2:field1>4</ns2:field1>'+
'<ns2:field2>5</ns2:field2>'+
'<ns2:field3>6</ns2:field3>'+
'</ns1:element>'+
'</ns1:input>';
var result2 = convert.xml2json(xml, {compact: true, spaces: 2, ignoreAttributes:true});
console.log(result2);
result
{
"ns1:input": {
"ns1:element": [
{
"ns2:field1": {
"_text": "1"
},
"ns2:field2": {
"_text": "2"
},
"ns2:field3": {
"_text": "3"
}
},
{
"ns2:field1": {
"_text": "4"
},
"ns2:field2": {
"_text": "5"
},
"ns2:field3": {
"_text": "6"
}
}
]
}
}
Try lib named x2js
var x2js = new X2JS();
var xmlText = "your_xml_string";
var jsonObj = x2js.xml_str2json( xmlText );
For more documentation refer to github page
Rather then doing a generic convert you can read the XML using DOM+Xpath and build up the JSON. The main benefit is that the JSON structure does not directly depend on the XML structure.
This works in any modern browser, in node.js you need the xmldom and xpath packages.
// provide namespace resolution for the Xpath expressions
const resolver = function(prefix) {
const namespaces = {
n1: 'ns1:test',
n2: 'ns2:test'
}
return namespaces[prefix || ''] || null;
}
const data = new DOMParser().parseFromString(getXMLString(), 'text/xml');
// fetch "{ns1:test}element" nodes
const elementNodes = data.evaluate(
"//n1:element", data, resolver, XPathResult.ANY_TYPE, null
);
let elementNode;
const elements = [];
while (elementNode = elementNodes.iterateNext()) {
const element = {
// read the id attribute
id: elementNode.getAttribute('id'),
// fetch the text contents of the first "{ns2:test}field1"
// note the string cast in the expression
field1: data.evaluate(
'string(n2:field1)', elementNode, resolver, XPathResult.STRING_TYPE, null
).stringValue,
field2: data.evaluate(
'string(n2:field2)', elementNode, resolver, XPathResult.STRING_TYPE, null
).stringValue,
field3: data.evaluate(
'string(n2:field3)', elementNode, resolver, XPathResult.STRING_TYPE, null
).stringValue
}
elements.push({element});
}
console.log({elements});
function getXMLString() {
return `<ns1:input xmlns:ns1="ns1:test" xmlns:ns2="ns2:test">
<ns1:element id="1">
<ns2:field1>1</ns2:field1>
<ns2:field2>2</ns2:field2>
<ns2:field3>3</ns2:field3>
</ns1:element>
<ns1:element id="2">
<ns2:field1>4</ns2:field1>
<ns2:field2>5</ns2:field2>
<ns2:field3>6</ns2:field3>
</ns1:element>
</ns1:input>
`;
}

Make a nested loop for a JSON object in nodejs

Hi I'm new to React and nodejs. I get from the user his preferences for certain categories in the json code for example:
{
"sport" : {
"tennis": "5",
"running": "4",
"swimming": "5"
},
"study" : {
"history" : "0"
}
}
I want for each preference to create its own field in the "userPreferences" object.
This is the code I wrote down but I can not see what the error is here
exports.reduceUserPreferences = (data) => {
let userPreferences = {};
data.forEach(category => {
category.forEach(preference => {
category_preference_name = category.string + "_" + preference.string;
if (!isEmpty(preference.trim())) userPreferences.category_preference_name = preference;
});
});
//if (!isEmpty(data.tennis.trim())) userPreferences.sport_tennis = data.tennis;
//if (!isEmpty(data.swimming.trim())) userPreferences.sport_swimming = data.swimming;
//if (!isEmpty(data.running.trim())) userPreferences.sport_running = data.running;
//if (!isEmpty(data.history.trim())) userPreferences.study_history = data.history;
return userPreferences;
};
I want the "" object to have fields of all preferences along with the category to which they belong.
I can not understand what I am doing wrong, I linger on this code for several hours.
add example
I have another function similar to this function, the input is similar and the output is similar.
For example input:
{
"bio": "hello there",
"website": "",
"location": "los angles"
}
Example function:
exports.reduceUserDetails = (data) => {
let userDetails = {};
if (!isEmpty(data.bio.trim())) userDetails.bio = data.bio;
if (!isEmpty(data.website.trim())) {
// https://website.com
if (data.website.trim().substring(0, 4) !== 'http') {
userDetails.website = `http://${data.website.trim()}`;
} else userDetails.website = data.website;
}
if (!isEmpty(data.location.trim())) userDetails.location = data.location;
return userDetails;
};
The output will be:
An object with the attribute of all preferences along with their value.
I was looking for examples with a nested loop, I could not find.
There are a couple of things you need to fix in your code.
First, when using a variable name as the key to extract from an object, user obj[varName], not obj.varName.
(read more here: Dynamically access object property using variable)
Also, you're trying to loop an Object, not an array. To loop through the keys, use Object.keys()
Combining these two things you get the desired result, as you can see in this snippet. Also, for future questions, I highly recommend you make a snippet yourself.
const jsonOriginal = {
"sport" : {
"tennis": "5",
"running": "4",
"swimming": "5"
},
"study" : {
"history" : "0"
}
}
const reduceUserPreferences = (data) => {
let userPreferences = {};
Object.keys(data).forEach(category => {
Object.keys(data[category]).forEach(preference => {
category_preference_name = category + "_" + preference;
const preferenceValue = data[category][preference].trim();
if (preferenceValue !== '') userPreferences[category_preference_name] = preferenceValue;
});
});
return userPreferences;
};
console.log(reduceUserPreferences(jsonOriginal))

How to save the results of a templete literals into an object? [duplicate]

This question already has answers here:
Convert a string to a template string
(22 answers)
Closed 3 years ago.
I have some template literals as values in a json file. When I access the values I need the values of the variables not the string of the template literal.
I have tried adding back-tick (`) like this but did not work:
value = '`' + value + '`';
Here is a snip of the code I'm trying to run:
const map = require('./mapping.json');
// declared here for testing
const engagement_id = '000909000132';
const start_date = '08/08/2011';
let obj = {};
for (let header in map) {
value = map[header].value;
// Do other things
obj[header] = value;
}
my mapping.json looks something like this:
{
"C_ID": {
"value": "16520780,${engagement_id}"
},
"C_DATE": {
"value": "${start_date}",
"format": "mm/dd/yy",
},
"SURV_TYPE": {
"value": "S"
}
}
console.log(obj) gives me this:
{ C_ID: '16520780,${engagement_id}',
C_DATE: '${start_date}',
SURV_TYPE: 'S' }
But what I want is the object to have the actual values of the variables like this:
{ C_ID: '16520780,000909000132',
C_DATE: '08/08/2011',
SURV_TYPE: 'S' }
Template literals are part of JavaScript source code.
You can't put JavaScript source code in a string and then just use it: It is data, not code.
You could, possibly, use eval(), but that brings its own share of problems and security risks.
Use a template library instead. For example, Nunjucks.
const map = {
"C_ID": {
"value": "16520780,{{engagement_id}}"
},
"C_DATE": {
"value": "{{start_date}}",
"format": "mm/dd/yy",
},
"SURV_TYPE": {
"value": "S"
}
};
const engagement_id = '000909000132';
const start_date = '08/08/2011';
let obj = {};
for (let header in map) {
const value = nunjucks.renderString(map[header].value, {
engagement_id,
start_date
})
obj[header] = value;
}
console.log(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/3.0.1/nunjucks.min.js"></script>
You could use String.replace() with a function to return the corresponding value:
const map = {
"C_ID": {
"value": "16520780,${engagement_id}"
},
"C_DATE": {
"value": "${start_date}",
"format": "mm/dd/yy",
},
"SURV_TYPE": {
"value": "S"
}
};
const values = {
engagement_id: '000909000132',
start_date: '08/08/2011',
};
const replacer = (_, p1) => (values[p1]);
let obj = {};
for (let header in map) {
value = map[header].value.replace(/\${(.+)}/, replacer);
// Do other things
obj[header] = value;
}
console.log(obj);

how to parse backslash json structure using jquery parse?

This is my code. I have used jquery parse. Can you Please help me? How to parse this?
var jsondata= {
"forms": [
"{\"lat\":11.913859799999999,\"lng\":79.8144722}",
"{\"lat\":11.913859799999999,\"lng\":79.8144722}"
]
}
var a=$.parseJSON(jsondata);
alert(a.forms[0].lat); // not working show "undefined"
error:
Uncaught SyntaxError: Unexpected token ,
You have to parse the forms[0] element to convert it to a real object:
var jsondata= {
"forms": [
"{\"lat\":11.913859799999999,\"lng\":79.8144722}",
"{\"lat\":11.913859799999999,\"lng\":79.8144722}"
]
}
var result = document.querySelector('pre');
result.textContent = JSON.parse(jsondata.forms[0]).lat;
// ^ parse here
// parse all elements of jsondata.forms:
// first: convert the elements of jsondata.forms to objects
jsondata.forms = jsondata.forms.map(function (v) { return JSON.parse(v); });
// now the jsondata.forms elements are objects
result.textContent += '\n\nThe converted jsondata.forms Array\n' +
JSON.stringify(jsondata.forms, null, ' ') +
'\n\nso: jsondata.forms[1].lng = ' + jsondata.forms[1].lng;
<pre></pre>
JSON is not JavaScript! It is a data serialization format.
var jsondata =
"{ \"forms\": ["
+ "{\"lat\":11.913859799999999,\"lng\":79.8144722} , "
+ "{\"lat\":11.913859799999999,\"lng\":79.8144722} ] }"
var a = JSON.parse(jsondata)
no need for jQuery -- the JavaScript language provides native JSON.parse and JSON.stringify
JSON data must be one long, single string that is passed to parse
JSON keys have to be quoted
I think the backend is generating a wrong response to your application
Sample like this lets say i have an array of
$data['default'] = array(
array(
'email' => 'sample#gmail.com',
'username' => 'username1'
),
array(
'email' => 'sample#yahoo.com',
'username' => 'username2'
),
array(
'email' => 'sample#hot.com',
'username' => 'username3'
)
);
$data['title'] = 'Sample';
and use
echo json_encode(json_encode($data));die();
would result to a data like this
"{\"default\":[{\"email\":\"sample#gmail.com\",\"username\":\"username1\"},{\"email\":\"sample#yahoo.com\",\"username\":\"username2\"},{\"email\":\"sample#hot.com\",\"username\":\"username3\"}],\"title\":\"Sample\"}"
but if use only
echo json_encode($data);die();
It would create a valid json data
{
"default": [
{
"email": "sample#gmail.com",
"username": "username1"
},
{
"email": "sample#yahoo.com",
"username": "username2"
},
{
"email": "sample#hot.com",
"username": "username3"
}
],
"title": "Sample"
}
Using your data
var jsondata= {
"forms": [
"{\"lat\":11.913859799999999,\"lng\":79.8144722}",
"{\"lat\":11.913859799999999,\"lng\":79.8144722}"
]
};
and using some jQuery code:
$.each(jsondata.forms, function(i, me){
console.log(JSON.parse(me));
});
using navite javascript
for (var i = 0; i < jsondata.forms.length; i++) {
console.log(JSON.parse(jsondata.forms[i]));
}
returns
{lat: 11.913859799999999, lng: 79.8144722}
{lat: 11.913859799999999, lng: 79.8144722}

Creating a nested object from parsed bb code

I am trying to create an object in javascript from a given string which includes some bbcode.
var bbStr = 'Text with [url=http://somelink]links and [i]nested bb code[/i][/url].';
I need to recursively iterate through the object and transform the above string into something like this:
var result = {
children : [
{
text : 'Text with ',
type : 'text'
},
{
children: [
{
text : 'links and ',
type : 'text'
},
{
text : 'nested bb code',
type : 'italic'
}
],
text : null,
type : 'url',
url : 'http://somelink'
},
{
text : '.',
type : 'text'
}
],
type : null,
text : null
};
Then I would send the object to a rendering function which would recursively create canvas text from it. But I just can't get my head around, how to form this object.
Try this simple stack-based parser:
token = /(?:\[(\w+)(.*?)\])|(?:\[\/(\w+)\])|([^\[\]]+)/g
root = {children:[]}
stack = [root]
bbStr.replace(token, function() {
var a = arguments;
if(a[1]) {
var node = {tag: a[1], attr: a[2], children:[]}
stack[0].children.push(node);
stack.unshift(node);
} else if(a[3]) {
if(stack[0].tag != a[3])
throw "Unmatched tag";
stack.shift();
} else if(a[4]) {
stack[0].children.push({tag: "#text", value: a[4]});
}
})
The output format differs from what you've posted, but that should be no problem.
http://jsfiddle.net/L8UZf/

Categories