My mobile app reads an external json object. How can I check in javascript that a key node exists in the dynamically generated json structure? I tried the hasOwnProperty or containsKey methods, but without luck.
Example json data:
{ "element1":
{ "element2": { "Number": "0" },
"element3": { "Number": "1" },
"element4": { "Number": "2" }
}
}
As these elements are generated dynamically, I want to check if the key element3 exists in this structure. No luck with data.element1.hasOwnProperty("element3").
Yes, hasOwnProperty() method does not work for a Json object. It works for a Java Script Object. So You just need to convert this Json object into a Java Script Object using eval() method and check inside that object.
When you convert above Json structure, it will create an Object (element1) inside another Object (say JSObject). element1 will contain properties element2, element3 and element4. So your code should go like this.
var MyObject={ "element1":
{ "element2": { "Number": "0" },
"element3": { "Number": "1" },
"element4": { "Number": "2" }
}
}
var JSObject=eval('(' + MyObject+ ')');
var IsExistElement3 = JSObject.element1.hasOwnProperty("element3");
Related
I have a list of data displayed on my page that is broken down into divs. Each div represents an array of data in my object, pretty common.
I am trying to add a text box to my page where I can filter out the data and it will narrow down the results shown on the page as more data is entered into the text box.
For that, I added a filter on my ngFor like so: *ngFor="let x of data | filter: filterString".
My text-box then uses ngModel to filter that data down:
<input type="text" class="form-control" placeholder="Filter..." name="ruleFilter" id="ruleFilter" [(ngModel)]="filterString" (keyup)="onFilter($event)">
The issue I am having is that the filter seems to only be working with the top layer of data in my object. For example, the data below is what one of the results looks like in my ngFor loop. I can search Omaha just fine since its in the top level and it filters it down correctly.
However, If I look for something like Campus which is nested inside Attribute, it doesn't find it in the filter and no results are shown.
{
"RuleParentID": "618",
"RuleVersionID": "18",
"MappedValue": "1",
"ProcessingOrder": 1,
"KeyID": "1",
"Value": "Omaha",
"IsRuleRetired": "0",
"UserImpactCount": "0",
"Attribute": [
{
"AttributeID": "6",
"AttributeName": "Campus",
"Operator": {
"OperatorID": "3",
"OperatorName": "In List",
"SqlOperator": "IN"
},
"AttributeValue": [
{
"AttrValue": "1",
"Value": "Omaha",
"IsValueRetired": "0",
"disabled": "False"
}
]
},
{
"AttributeID": "14",
"AttributeName": "Grade",
"Operator": {
"OperatorID": "1",
"OperatorName": "Greater Than",
"SqlOperator": ">"
},
"AttributeValue": [
{
"AttrValue": "14",
"Value": "14",
"IsValueRetired": "0",
"disabled": "False"
}
]
}
]
}
Is there any way to have the model look at all layers of the object for my binding instead of just the top layer (which I only assume its doing at this time) ?
Update: Here is a plunker of what my basic setup is like: https://plnkr.co/edit/eywuWmPRseUkmVPbTEOf?p=preview
You will see the data model that searches by the top level properties just fine, but when I search for something nested, I don't get any results back.
If I understand well the question, I think that to flat the data will help you:
var flattenObject = function(ob) {
var toReturn = {};
for (var i in ob) {
if (!ob.hasOwnProperty(i)) continue;
if ((typeof ob[i]) == 'object') {
var flatObject = flattenObject(ob[i]);
for (var x in flatObject) {
if (!flatObject.hasOwnProperty(x)) continue;
toReturn[i + '.' + x] = flatObject[x];
}
} else {
toReturn[i] = ob[i];
}
}
return toReturn;
};
let newData = flattenObject(data);
Code source: https://gist.github.com/penguinboy/762197
To achieve expected result , use below option
1.In your component below variable
jsonVal:any=JSON; // for using JSON.stringify and indexOf
Use *ngIf to filter value from input with indexOf
<input type="text" [(ngModel)]="filterString">
<div *ngFor="let data of result">
<div *ngIf="jsonVal.stringify(data).indexOf(filterString)!= -1">{{data| json}}</div>
</div>
code sample for reference - https://stackblitz.com/edit/angular-ht2afv?file=app/app.component.html
Just for testing , I have added another Object with Campus2 and Omaha2
When filtering on a nested property of data you can use the map function or similar.
This will be in your component and not the template. Filtering using pipes in the template is discouraged by the Angular team for performance reasons.
Instead I would do something like this:
const data = [{//your data}]
let filteredData = [];
data.map(val => {
if (val.Attribute.filter(name => name.AttributeName === "Foo").length > 0) {
filteredData.push(val)
}
});
I am assuming your data is an array of objects.
Beware I am mutating my data object. To avoid this you do this:
const data = [{//your original data}]
const dataToFilter = JSON.Parse(JSON.stringify(data))
This will make copy of your data without references to your original object. Useful if you want to clear your filter. Not useful if your data object contains functions.
On re-reading your question I think this is not the solution you were looking for but rather a method to look anywhere in the data. For this you should probably flatten your data as suggested by Zelda7. Another approach would be to extend a filtering method to explicitly filter on all relevant fields.
I am creating this JSON object
{
"attachment": {
"type": "template",
"payload": {
"template_type": "generic",
"image_aspect_ratio": "square"
"elements": [
new CreateBallon(results[rand])
]
}
}
}
I want to set the image_aspect_ratio in only if elements[0].someProp is present.
How can I do that?
Let's clear what JSON is. It is a textual notation for data. If you do anything with the object that involves code of Javascript don't call it JSON so, The object you're talking about is not a JSON but a JavaScript object created via object literal notation.
Now to answer your query, you can't refer to this object before you've fully initialized that object. So what you can do is initialize your object with some default value and then you should be able to edit any property based on the properties from the same object. Something like
var obj = {"property1" : "X", "property2" : ""};
Now you can update your object like
obj.property2 = obj.property1 =='yourCondition' ? 'NewValue' : obj.property2
I am new to Underscore. I have a json array which is pasted below. If I want to filter the below array based on developed field having "yes" as value. How can I do using Underscore.js. Currently I am iterating over the content of array and manually selecting the objects and populating in into another array. Is there a better way to do using Underscore?
{
"content": [
{
"stateName": "Karnataka",
"population": 1000000,
"developed": "yes"
},
{
"stateName": "Kerala",
"population": 1000000,
"developed": "yes"
},
{
"stateName": "Tamilnadu",
"population": 1023213213213,
"developd": "yes"
},
{
"stateName": "Bsadasd",
"population": 1023213213213,
"developed": "no"
}
]
}
Not sure if I'm missing something here but the obvious underscore function is filter:
var developedStates = _.filter(data.content, function(state){
return state.developed == 'yes';
});
You can filter an array on its properties by using _.where :
where _.where(list, properties)
Looks through each value in the list, returning an array of all the values that contain all of the
key-value pairs listed in properties.
which leads to
var filtered = _.where(data.content, {developed: "yes"});
and a demo http://jsfiddle.net/nikoshr/NExZC/
As far as I know, underscore doesn't have a way to help you with this task. You can do this without using underscore with a native Javascript method called select:
var filteredArray = originalArray.select(function(item, index) {
return item.developed == "yes"; // Include this item if it has a proper value
});
Note that the select method is only available in browsers that support EcmaScript 5 specifications, so for older browsers you will need some supporting library like es5-shim.
I have a json url that returns data in the format
{
"photos" : [
{
"id": 1, "image":"https://path/to/my/image/1.jpg"
},
{
"id": 2, "image":"https://path/to/my/image/2.jpg"
}
]
}
I'm using the json in a javascript function, and need to manipulate it to remove the root key. i.e. I want something that looks like
[
{
"id": 1, "image":"https://path/to/my/image/1.jpg"
},
{
"id": 2, "image":"https://path/to/my/image/2.jpg"
}
]
I've been hacking around with various approaches, and have referred to several similar posts on SO, but nothing seems to work. The following seems like it should.
var url = 'http://path/to/my/json/feed.json';
var jsonSource = $.getJSON( url );
var jsonParsed = $.parseJSON(jsonSource);
var jsonFeed = jsonParsed.photos
What am I doing wrong?
A couple of issues there.
That's invalid JSON, in two different ways. A) The : after "photos" means that it's a property initializer, but it's inside an array ([...]) when it should be inside an object ({...}). B) There are extra " characters in front of the images keys. So the first thing is to fix that.
You're trying to use the return value of $.getJSON as though it were a string containing the JSON text. But $.getJSON returns a jqXHR object. You need to give it a success callback. That callback will be called with an object graph, the JSON is automatically parsed for you.
Assuming the JSON is fixed to look like this:
{
"photos": [
{
"id": 1,
"image": "https://path/to/my/image/1.jpg"
},
{
"id": 2,
"image": "https://path/to/my/image/2.jpg"
}
]
}
Then:
$.getJSON(url, function(data) {
var photos = data.photos;
// `photos` now refers to the array of photos
});
I am on a Dojo app, is there any special JS parser which enables me default values within JSON data ?
Example, I'd like to set "maxHeadingLength" in item[1] to the value in item[0].
{
items:[
{
"class": "pmedia.types.PMPlatformRenderConfiguration",
"listItemHeight": "70",
"listItemIconHeight": "60",
"maxDesktopItemsWithBannerP": "9",
"maxDesktopItemsWithBannerL": "9",
"platform": "Default",
"maxHeadingLength":
{
P:300,
L:400
}
},
{
"class": "pmedia.types.PMPlatformRenderConfiguration",
"listItemHeight": "70",
"listItemIconHeight": "60",
"platform": "IPAD",
"maxHeadingLength": "Default"
},
Something like this would good too :
"maxHeadingLength": "this.items[0].maxHeadingLength"
Thanks
Update, It seems I can and need to precise the question a bit better now.
I'd like to write any string expression into the pure JSON string data(file), as string of course and evaluate the data within the same data set without using "eval".
Thanks to all !
You can either do this in a backend process or using a front end process as you process the JSON.
Let's assume you're wanting to do it in the front end using JS, I would suggest firstly setting the items[0].maxHeadingLength as a var, like so:
var defaultMaxHeadingLength = items[0].maxHeadingLength;
And then as you loop through your JSON you can check whether the maxHeadingLength attribute has a value or not and default it, like so:
var item, i;
for ( i = 0; i < items.length; i++ )
{
item = items[ i ];
item.maxHeadingLength = item.maxHeadingLength ? item.maxHeadingLength : defaultMaxHeadingLength;
}
Here's an idea of one way to do it (if I understand what you're trying to do):
var defaultItem = {
"maxHeadingLength": {
P: 300,
L: 400
}
};
var jsondata = {
items: [
{
"class": "pmedia.types.PMPlatformRenderConfiguration",
"listItemHeight": "70",
"listItemIconHeight": "60",
"platform": "IPAD",
"maxHeadingLength": this.defaultItem.maxHeadingLength
}
]
};
alert(jsondata.items[0].maxHeadingLength.L);
//returns 400
Basically you have a default item separate to all your other items, allowing you to refer to the defaults in the main data.
I don't think you can use this.jsondata from within the same object, since it hasn't finished being created yet (but I could be wrong).