JSON parsing in javascript - javascript

I'm trying to parse JSON in JavaScript. If my JSON data looks like below, I want to iterate through all the JSON elements that start with "custom" and not with any other string. How do I do this?
{
"fields": {
"custom12": {
value: "dsada"
},
"custom45": {
value: "adsadad"
},
"test12": {
value: "12323"
}
}
}​

var newObject = {}, key;
for(key in data.fields){
if(key.search(/custom/) > -1){
newObject[key] = data.fields[key];
}
}
console.log(newObject);

The following iterates the properties of the fields object and checks whether the property's name contains custom:
var data = yourObjectLiteral, i, current;
for(i in data.fields) {
if(i.indexOf('custom') > -1) {
current = data.fields[i];
// ... your logic ...
}
}

With the json string you provided I'd do it as such:
<script src="json2.js"></script>
<script>
var raw = '{'
+ ' "fields": {'
+ ' "custom12": {'
+ ' "value": "dsada"'
+ ' },'
+ ' "custom45": {'
+ ' "value": "adsadad"'
+ ' },'
+ ' "test12": {'
+ ' "value": "12323"'
+ ' }'
+ ' }'
+ '}';
var data = JSON.parse(raw);
var fields = data.fields;
var message = '';
for (var key in fields) {
if (key.indexOf('custom') === 0) {
message += key + ': ' + fields[key].value + '\n';
}
}
alert(message);
</script>
But, if you can rewrite the incomming message a little it will look simpler.
<script src="json2.js"></script>
<script>
var raw = '{'
+ ' "custom12": "dsada",'
+ ' "custom45": "adsadad",'
+ ' "test12": "12323"'
+ '}';
var fields = JSON.parse(raw);
var message = '';
for (var key in fields) {
if (key.indexOf('custom') === 0) {
message += key + ': ' + fields[key] + '\n';
}
}
alert(message);
</script>

Related

Why is *ngFor seemingly looping infinitley?

Can anyone help me understand why this ngFor seemingly gets to the end and then loops again?
Template
<div class="row">
<h2>Results</h2>
</div>
<div *ngFor="let bson of bsonResults; let i = index">
{{i}}
{{getItemContext(bson, i)}}
<!-- <mat-card class="card collection-card">
<a [routerLink]="toDetails(results.database, results.collection, bson.data._id.$oid)" data-toggle="tooltip"
title="Click to visit details page" attr.aria-label="Item Name: {{utility.getItemTitle(bson, results.nameField)}}">{{utility.getItemTitle(bson, results.nameField)}}</a>
<mat-card-content [innerHTML]="getItemContext(bson)">
{{getItemContext(bson)}}
</mat-card-content>
</mat-card> -->
</div>
Relevant methods from .ts file
getItemContext(bson, i) {
console.log(i);
console.log(bson);
if (this.searchCriteria.q !== '') {
return this.contextWithSearchString(bson);
} else {
return this.contextWithoutSearchString(bson);
}
}
contextWithSearchString(bson) {
let keys = Object.keys(bson.data);
let longString: string;
let highlightedText: string;
for (let key of keys) {
let bsonItem: string = bson.data[key];
bsonItem.toString();
if (typeof bsonItem === 'string') {
if (bsonItem.toUpperCase().includes(this.searchCriteria.q.toUpperCase())) {
let indexOfTerm = bsonItem.toUpperCase().indexOf(this.searchCriteria.q.toUpperCase());
if (bsonItem.length > 100) {
if (indexOfTerm - 50 <= 0) {
bsonItem = bsonItem.substring(0, 100) + '...';
} else {
bsonItem = '...' + bsonItem.substring(indexOfTerm - 50, indexOfTerm + 50) + '...';
}
}
if (longString === undefined) {
highlightedText = this.utility.highlight(bsonItem, this.searchCriteria.q);
longString = '<b>' + key + ': ' + '</b> ' + highlightedText + ' | ' ;
} else {
highlightedText = this.utility.highlight(bsonItem, this.searchCriteria.q);
longString = longString + '<b>' + key + ': ' + highlightedText + ' | ';
}
}
}
}
return longString;
}
contextWithoutSearchString(bson) {
let keys = Object.keys(bson.data);
let longString: string;
let i = 0;
keys.forEach(key => {
// only return strings in search context, and only return the first 4.
if (typeof (bson.data[key]) === 'string' && i < 4) {
let dataValue: string = bson.data[key];
if (dataValue.length > 100) {
dataValue = dataValue.substring(1, 100) + '...';
}
if (longString === undefined) {
longString = '<b>' + key + ': </b>' + ' ' + dataValue + ' | ';
} else {
longString = longString + '<b>' + key + ': </b> ' + dataValue + ' | ';
i++;
}
}
});
// if the item only contains objects (no strings) then just return 600 chars of the raw JSON.
if (longString === undefined) { return JSON.stringify(bson.data).substring(0, 600); } else {
return longString;
}
}
and here's how it looks on the page (..looks fine)
yet here is my console getting bombarded
Strangely enough the page is displaying the output from the getItemContext function on the page the correct amount of times. However, I put a console log at the start of the function to log my bson objects and this is continually filling up the console with objects. I stuck an index variable in to see if the count looked right and it does (bsonResults contains a 11 items). When the console has gotten up to logging out the 11th item it just starts again.

How to make variables optional while concatenation of string?

I am manipulating string to display in UI, Data is being dynamically with below code sometime i don't get header and details so how to make IHeader and IResponse optional for the string concatenation below.
if i dont have IHeader it will break at IHeader.id and throw exception i want to display whatever data is available to render.
main.js
const data = [{
id: "header",
name: "IHeader"
}, {
id: "param",
name: "IParams"
}, {
id: "details",
name: "IResponse"
}]
function buildText(data) {
var IParams;
var IResponse;
var IHeader;
for (var item of data) {
if (item.id === "param") {
IParams = item;
} else if (item.id === "header") {
IHeader = item;
} else if (item.id === "details") {
IResponse = item;
}
}
var text = '';
text += app + '.setConfig({\n' + "env:" + getEnv() + '\n});' + '\n\n';
text += 'let param:' + IParams.name + ' ' + '=' + '' + JSON.stringify(request, null, 4) + ';\n\n';
text += ref + '(' + 'param,(result:' + ' ' + '{' + '\n' + IHeader.id + ':' + IHeader.name + '\n' + IResponse.id + ':' + IResponse.name + '\n' + '})' + ' ' +
' => {\n console.log(result); \n});';
}
1 - You can try to create an object with empty values. That'll prevent the exception.
emptyObject = {id: ""} // more empty keys, if there is
IParam = (item.id === "param") ? item : emptyObject
2 - Or ignore that concatenation of the variable if undefined or null.
if (Iparam) {
// concatenation ..
}

Looping over JavaScript object and adding string to end if not the last item

{
field_country: ["England", "Netherlands", "India", "Italy"],
field_continent: ["Europe"],
field_group: ["Building", "People", "Landscape"
}
I want to loop over each item and return the key and the array together with ending 'OR' for example:
field_country: "England" OR field_country: "Netherlands"
The last item should not end with 'OR' in the loop. I am not sure what the best process is for this using vanilla JS. So far my code is as follows:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i == 1) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});
I would be very grateful for any assistance.
Thanks in advance.
You can do something like this with Object.entries and Array.reduce if you would like to get the final result in the form of an object:
const data = { field_country: ["England", "Netherlands", "India", "Italy"], field_continent: ["Europe"], field_group: ["Building", "People", "Landscape"] }
const result = Object.entries(data).reduce((r, [k, v]) => {
r[k] = v.join(' OR ')
return r
}, {})
console.log(result)
It is somewhat unclear what is the final format you need to result in but that should help you to get the idea. If ES6 is not an option you can convert this to:
const result = Object.entries(data).reduce(function(r, [k, v]) {
r[k] = v.join(' OR ')
return r
}, {})
So there are is no arrow function etc.
The idea is to get the arrays into the arrays of strings and use the Array.join to do the "replacement" for you via join(' OR ')
Here's the idea. In your code you are appending " or " at the end of your strings starting at index 0. I suggest you append it at the the beginning starting at index 1.
var somewords = ["ORANGE", "GREEN", "BLUE", "WHITE" ];
var retval = somewords[0];
for(var i = 1; i< somewords.length; i++)
{
retval += " or " + somewords[i];
}
console.log(retval);
//result is: ORANGE or GREEN or BLUE or WHITE
Your conditional expression if (i == 1) would only trigger on the second iteration of the loop since i will only equal 1 one time.
Try something like:
if (i < (facetResults.length - 1)) {
// only add OR if this isn't the last element of the array
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
}
Here's your updated code:
Object.keys(facets).forEach(function(facetKey) {
if (facets[facetKey].length > 1) {
facetResults = facets[facetKey];
for (var i = 0; i < facetResults.length; i ++) {
if (i < (facetResults.length - 1)) {
filter = "'" + facetKey + "'" + ":'" + facetResults[i] + " OR";
return filter;
} else {
filter = "'" + facetKey + "'" + ":'" + facetResults[i];
}
}
} else {
filter = "'" + facetKey + "'" + ": " + facets[facetKey] + "'";
return filter;
}
});

Accessing keys within Objects for use in a function

I have a nested object:
myObj = {
id:'AA',
child:{
id:'BB',
key1:'CC'
},
child2:{
id:'DD',
key1:'EE'
},
};
I also have a function where I am currently doing this:
doSomething = function(id,childid,key){
var str = id + childid + key;
console.log(str);
};
doSomething(myObj.id,myObj.child.id,myObj.child.key1);
I would like to simplify to this:
doSomething2 = function(incObj){
//myObj.child.key1;
var str = incObj.id + ' ' + incObj.child.id + ' ' + incObj.child.key;
//str = 'AA BB CC';
console.log(str);
}
doSomething2(myObj.child.key1);
Is there a clean/simple way of doing this?
The way you doing it:
myObj = {
id:'AA',
child:{
id:'BB',
key1:'CC'
},
child2:{
id:'DD',
key1:'EE'
},
};
doSomething2 = function(incObj){
//myObj.child.key1;
var str = incObj.id + ' ' + incObj.child.id + ' ' +incObj.child.key1;
//str = 'AA BB CC';
console.log(str);
}
doSomething2(myObj);
myObj = {
id:'AA',
child:{
id:'BB',
key1:'CC'
},
child2:{
id:'DD',
key1:'EE'
},
};
var config = {
"child" : "child2",
"key" :"key1"
}
doSomething2 = function(incObj, config){
//myObj.child.key1;
var str = incObj.id + ' ' + incObj[config.child].id + ' ' +incObj[config.child][config.key];
//str = 'AA BB CC';
console.log(str);
}
doSomething2(myObj,config);
You've already found the answer by yourself. You just have the pass the object and it's done.
Object:
myObj = {
id:'AA',
child:{
id:'BB',
key1:'CC'
},
child2:{
id:'DD',
key1:'EE'
},
};
function:
doSomething2 = function(incObj){
//myObj.child.key1;
var str = incObj.id + ' ' + incObj.child.id + ' ' + incObj.child.key1;
console.log(str);
}
doSomething2(myObj);

javascript convert JSON string to JSON object

I al using javascript and looping through the values of a submitted form and trying to build a son object out of the form values.
This is an example of the final object I need:
{
"DataObject": {
"user": { "-name": "username" },
"contentFile": {
"-filename": "Breaking_News",
"lock": { "-fileIsBeingEdited": "false" },
"content": {
"line": [
{
"-index": "1",
"-text": "this is the header"
},
{
"-index": "2",
"-text": "this is the first line"
},
{
"-index": "3",
"-text": "this is the second line"
}
]
}
}
}
}
So far i am adding all of this data to a string as that seems to be the only way i can insert the form values (the line array) into the middle of the object.
var jsonStr = '{'
+ 'iceteaDataObject: {'
+ 'user: {"-name": "hindsc52"},'
+ 'contentFile: {'
+ '"-filename": "Ticker",'
+ 'lock: { "-fileIsBeingEdited": "false" },'
+ 'content: {'
+ 'line: ['
for(var i = 0; i < elem.length; i++) {
if(!elem[i].value == '') {
jsonStr += '{'
jsonStr += "-index: " + i + ',';
jsonStr += "-text: " + elem[i].value;
jsonStr += '},'
}
}
jsonStr += ']}}}}';
console.log(JSON.parse(jsonData));
however when running this I get the error: unexpected token 'i'.
I have tried to use stringily but then just outputs the entire sting again.
You don't need or want JSON for this, just build the object:
// Sample data
var elem = [{
value: "one"
}, {
value: "two"
}];
// Build the object
var obj = {
"DataObject": {
"user": {
"-name": "username"
},
"contentFile": {
"-filename": "Breaking_News",
"lock": {
"-fileIsBeingEdited": "false"
},
"content": {
"line": []
}
}
}
};
var line = obj.DataObject.contentFile.content.line;
elem.forEach(function(entry, index) {
if (entry.value != '') {
line.push({
"-index": index,
"-text": entry.value
});
}
});
// Show result:
document.body.innerHTML =
"<pre>" +
JSON.stringify(obj, null, 2) +
"</pre>";
Side note: You don't check for blank strings like this:
if (!entry.value == '') { // <== Incorrect
You can use:
if (entry.value != '') {
or:
if (entry.value) {
You shouldn't build JSON like this, but use JSON.stringify() (see MDN doc) instead:
var myObject={foo:"bar"};
var myJSON=JSON.stringify(myObject);
console.log(myJSON); //echo {"foo":"bar"}
Here is an alternative way:
var json = {
iceteaDataObject: {
"-name": "hindsc52"
},
contentFile: {
"-filename": "Ticker",
lock: { "-fileIsBeingEdited": "false" },
content: {line: []}
}
}
for(var i = 0; i < elem.length; i++) {
if(!elem[i].value == '') {
json.contentFile.content.line.push({"-index": i,"-text": elem[i].value }
}
}
var jsonStr = JSON.stringify(json);
You need to put all your keys in quotes for this to work. As the others have pointed out though, you are not really supposed to do this.
If you still want to do it your way, try this:
var jsonStr = '{'
+ '"iceteaDataObject": {'
+ '"user": {"-name": "hindsc52"},'
+ '"contentFile": {'
+ '"-filename": "Ticker",'
+ '"lock": { "-fileIsBeingEdited": "false" },'
+ '"content": {'
+ '"line": ['
for(var i = 0; i < elem.length; i++) {
if(!elem[i].value == '') {
jsonStr += '{'
jsonStr += '"-index": ' + i + ',';
jsonStr += '"-text": ' + '"' + elem[i].value + '"';
jsonStr += '},'
}
}
jsonStr += ']}}}}';

Categories

Resources