How to pass a variable in to the JSON search loop? [duplicate] - javascript

This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 7 years ago.
I have the following code which works fine:-
$.getJSON("shipping.json")
.done(function(data) {
getUniqueCountries = function() {
var countries = [];
$.each(data.Services.intl.en, function( i, item ) {
if (countries.length==0) {
countries += item.countries;
}
else
{
countries += "," + item.countries;
}
});
}
})
However, I would like to make the first part of the $.each dynamic as this could be one of 3 possibilities based on a predefined variable, e.g.
var foo = "intl"
so the new line would read:-
$.each(data.Services.foo.en, function( i, item )
I can add another line of code and use an eval which works fine, but understand that this is not seen as best practice. i.e.
var foo = "intl";
var bar = eval("data.Services." + foo + ".en");
$.each(bar, function( i, item )
I have tried using JSON.parse (as seems to be popular way to resolve on google) instead of eval, i.e.
var bar = JSON.parse("data.Services." + foo + ".en");
but get an error :
'Unexpected token d'.
A snippet of the JSON file if needed :-
{
"Services": {
"intl": {
"en": [
{
"service": "PREMIER",
"countries": "United Kingdom",
"date": "Thursday 24th 10:00"
}
]
}
}
}
So I would like to know how to pass the variable foo into JavaScript to get the correct data and not get an error, without using the Eval function, or am I good to use the Eval function after all?
Thanks in advance for any help

If i'm understanding correctly, you should be able to do the following:
$.each(data.Services[foo].en, function( i, item ) {
if (countries.length==0) {
countries += item.countries;
}
else
{
countries += "," + item.countries;
}
});
Properties in javascript objects can be accessed as if you are accessing a particular key inside an array. For example you can do window.location or window["location"]
Hope this helps

It's actually fairly simple. JavaScript supports dynamic object keys with the [] notation:
data.Services[foo].en // Where foo = 'intl' or something.

Related

MarkLogic Get all Nested Field name of Json document using javascript

I need a recursive function in javascript, which can return me all fieldname (Key Name) of my json document store in MarkLogic. JSON document is very dynamic and have multiple hierarchical elements. So need a function which can traverse through JSON and fetch all fieldname (Keys Name).
One option I thought was to get entire document into MaP object and run Map function to get all keys. But not sure whether MarkLogic allows to capture entire json doucment into Map and one can read fields names.
Thanks in Advance
Got the function to iterate through JSON document to pull Key Name
Sample JSON
var object = {
aProperty: {
aSetting1: 1,
aSetting2: 2,
aSetting3: 3,
aSetting4: 4,
aSetting5: 5
},
bProperty: {
bSetting1: {
bPropertySubSetting : true
},
bSetting2: "bString"
},
cProperty: {
cSetting: "cString"
}
}
Solution available at StackOverflow
Recursively looping through an object to build a property list
*
function iterate(obj, stack) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property], stack + '.' + property);
} else {
console.log(property + " " + obj[property]);
$('#output').append($("<div/>").text(stack + '.' + property))
}
}
}
}
iterate(object, '')*
This handy page may help: MarkLogic - Native JSON
The following will extract all property names
var json = fn.head(xdmp.unquote('{ foo : "bar", baz : { buz: "boo", chicken : { option1 : "soup", option2 : "salad" } } }'))
json.xpath("//*/name()");
Output: foo baz buz chicken option1 option2
If, after reviewing the samples on that page you still need assistance, I suggest updating your question with example JSON and desired output (even if it is meant to be dynamic, an example people can copy/paste and work with helps alot)

How to access JSON-object with multiple values per key?

At the moment I am stuck with a problem that just seems stupid, but I don't know the answer to it.
I am trying to access this JSON-object:
var custom_fields =
{
"28246": 5123,5124,5125
}
I would like to get each value from that key. I would know how to access it if it was a nested-object, but it isn't sadly (it is coming from an API, which I can't change the JSON-response from sadly)
What I tried already is the following:
for (var key in custom_fields) {
if (custom_fields.hasOwnProperty(key)) {
console.log(key + " -> " + custom_fields[key]);
}
}
The problem here is that the result will be like this:
1 -> 5
2 -> 1
3 -> 2
4 -> 3
5 -> ,
6 -> 5
...etc...
Any suggestions are welcome, I am trying to access it in javascript/Jquery.
Thanks for helping in advance!
I assume that the data is in this format (note the string literals):
var custom_fields = {
"28246": "5123,5124,5125"
}
If that is the case, you can use String.split.
In your case, it would be something like this:
const values = custom_fields['28246'].split(',');
The values of they key 28246 are now stored in the new variable values as an array:
['5123','5124','5125']
If you want to parse all values to integers, I suggest using Array.map:
const valuesAsInt = custom_fields['28246'].split(',').map(value => parseInt(value);
Which will lead to this:
[5123, 5124, 5125]
Disclaimer: When using newer ECMAScript features such as Array.map, be sure to either use a browser which supports this our include a polyfill.
You can access it by using split function which will convert it into an array and then get the values from that array as below code.
var data = {
"28246": '5123,5124,5125'
}
var arr = data['28246'].split(',');
$.each(arr, function( index, value ) {
console.log(value);
});
You can split by ',' and transform each element to integer by using array.map and '+' operator:
var custom_fields =
{
"28246": "5123,5124,5125"
}
custom_fields["28246"] = custom_fields["28246"].split(',').map(el => +el);
console.log(custom_fields);
console.log(custom_fields["28246"][0], custom_fields["28246"][1], custom_fields["28246"][2]);

Read a JSON list in list [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 6 years ago.
I have a json like this :
{
"Project
[id=1, dateDebut=2017-01-13, dateFin=2017-01-18, description=qsd, sponsor=qsd ]"
:
[
{"id":1,"title":"qsd ","description":"qsdqsd","dateFin":"2017-01-26"},
{"id":2,"title":"sss ","description":"sss","dateFin":"2017-01-26"}
]
}
originated from : return new ObjectMapper.write(Map<Project,List<Task>> projectTasks = new LinkedMultiValueMap<>()) ;
EDIT : this is the real response :
{"Project [id=1, name=qsdsqd, type=null, done=false, dateDebut=2017-01-13, dateFin=2017-01-18, description=qsd, sponsor=qsd, client=qsd, showable=true]":
[{"id":1,"title":"qsd ","description":"qsdqsd","dateFin":"2017-01-26","dateDebut":"2017-01-14","period":null,"done":false,"status":"Actif","priority":"Normal"},
{"id":2,"title":"task 2 ","description":"qsdqsd","dateFin":"2017-01-26","dateDebut":"2017-01-14","period":null,"done":false,"status":"Actif","priority":"Normal"}]}
How can I read the list of tasks in the client side ?
First of all, your JSON is not valid. Are you sure that is a line break between the word Project and [id...]. A valid JSON would be:
{
"Project [id=1, dateDebut=2017-01-13, dateFin=2017-01-18, description=qsd, sponsor=qsd, ]":
[
{"id":1,"title":"qsd ","description":"qsdqsd","dateFin":"2017-01-26"},
{"id":2,"title":"sss ","description":"sss","dateFin":"2017-01-26"}
]
}
You can have object key names like that. But i'ts not very friendly to retrieve data.
If you cannot change your data schema (or just don't want), you can iterate over the Object with the
Object.keys(obj).forEach ( (key) => {
console.log('key: ' + key);
console.log('value: ' + obj[key]);
/* you can iterate over your value (tasks) here */
obj[key].forEach( (task) => {
console.log('task1: ', task);
});
}); //where obj is your json
Or you can access the first object property with:
obj[Object.keys(obj)[0]]; //where obj is your json
EDIT As pointed by #André Dion, forEachis best suited to iteration, not map. And we're assuming your response is already parsed from the server (by yourself or by a lib like jquery). If not, you should do a JSON.parse(response); to retrieve the object.
You may try this:
Assume above response in stored in var response.
for(var project in response) { // this will get every project
for(var i=0; i<project.length; i++) { // this will iterate over the array for each project which are your tasks.
console.log("task" + project[i]);
console.log(project[i]["id"]); // access each tasks id, similar for other attributes
}
}

Dynamically updating a JavaScript object from a string path [duplicate]

This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
How to set object property (of object property of..) given its string name in JavaScript?
(16 answers)
Closed 10 years ago.
Im trying to figure out if its possible to update a JavaScript object, using a string as the path.
In the example below, I'm trying to figure out how I can update the first books price using
store>book>0>price as my path.
I know I can access this by writing data['store']['book'][0]['price'] but I need to be able to do this dynamically. Ive tried a few things but had no luck. Any Ideas?
This needs to work for any depth , not a fixed depth
Data:
var data = {
"store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
var path = "store>book>0>price"
Function:
function updateObject(object, path, data) {
var pathArray = path.split(">");
// Some code here
}
updateObject(data, path, "10.00");
Update
As felix pointed out the answer can be found here.
Dynamic deep setting for a JavaScript object
Here is a working example for my scenario
http://jsfiddle.net/blowsie/Sq8j3/9/
function updateObject(object, newValue, path){
var stack = path.split('>');
while(stack.length>1){
object = object[stack.shift()];
}
object[stack.shift()] = newValue;
}
You want to update your method signature to accept the: object you're modifying, the path string, and the value you're assigning to the final path property.
function updateObject(data, path, value) {
var pathArray = path.split(">");
var pointer = data; // points to the current nested object
for (var i = 0, len = pathArray.length; i < len; i++) {
var path = pathArray[i];
if (pointer.hasOwnProperty(path)) {
if (i === len - 1) { // terminating condition
pointer[path] = value;
} else {
pointer = pointer[path];
}
} else {
// throw error or terminate. The path is incorrect
}
}
}
Or recurse. Or use a while loop. But this is the general idea.
Fiddle: http://jsfiddle.net/Sq8j3/8/
It's slightly confusing that you've called your object data but that data is also an argument of your function. I've changed the argument's name therefore to newVal in order to clear up this potential problem.
This loops through the path and constantly resets a variable called e which starts by pointing to the data object generally and gets more specific as we loop. At the end, you should have an almost reference to the exact property -- we use the last part of the path to set the new value.
function updateObject(newVal, path) {
var pathArray = path.split(">"),
i = 0,
p = pathArray.length - 1, // one short of the full path
e = data; // "import" object for changing (i.e., create local ref to it)
for (i; i < p; i += 1) { // loop through path
if (e.hasOwnProperty(pathArray[i])) { // check property exists
e = e[pathArray[i]]; // update e reference point
}
}
e[pathArray[i]] = newVal; // change the property at the location specified by path to the new value
};
You might need to add something to catch errors. I have put a check in with the hasOwnProperty() call but you might need something more elaborate than this.
UPDATE
Had made a silly mistake in the code before but it should be working now. As evidenced here.

Using variable keys to access values in JavaScript objects

The code:
function updateDashboardData() {
$.getJSON("includes/system/ajaxDataInterface.php", {recordcount:1}, function(data) {
$('.stationContainer').each(function(data) {
var bsID = $(this).attr("id");
var bsStatus = $(this).children('.stationStatus');
alert(data[bsID][0].time);
bsStatus.find('.bs_maxHandsets').text(data[bsID][0].maxHandsets);
bsStatus.find('.bs_time').text(data[bsID][0].time);
});
});
}
The object data:
{
"A5A50000": [{
"bsid": "A5A50000",
"chanCount": 17,
"time": "2009-05-27 16:36:45",
"avgInterference": 1.711765,
"maxInterference": 4.97,
"avgHandsets": 205.1176,
"maxHandsets": 315,
"avgCalls": 6.4118,
"maxCalls": 13,
"avgCBA": 3868.98059,
"maxCBA": 7463,
"sumSuccessCBA": 197318,
"sumTimeoutHandoff": 133,
"sumAttemptHandoff": 1028,
"sumDeniedHandoff": 216,
"sumConfirmHandoff": 679,
"sumHandoffNetwork": 61873,
"sumJoinNetwork": 96888,
"sumLeaveNetwork": 93754,
"sumRcvdKeepalive": 98773,
"sumTimeoutKeepalive": 19748,
"sumAttemptUplink": 93689,
"sumBlockedUplink": 62453
}]
}
The problem:
alert(data.A5A50000[0].time); properly displays "2009-05-27 16:36:45".
alert(bsID); properly displays "A5A50000".
alert(data.bsID[0].time); reports "data.bsID is undefined".
alert(data[bsID][0].time); reports "data[bsID] is undefined".
I'm a little unclear when a variable is/isn't evaluated. Maybe I'm overlooking something silly, but I can't figure out my problem here.
You can access object properties by dot notation or by bracket notation.
var x = {'test': 'hi'};
alert(x.test); // alerts hi
alert(x['test']); // alerts hi
When you have a dynamic value, you have to use the latter:
var property = 'test';
alert(x.property); // looks for x.property, undefined if it doesn't exist
alert(x[property]); // looks for x['test'], alerts hi
So what you actually want is:
alert(data[bsID][0].time);
EDIT:
Not sure what you're doing wrong, but this is working for me on Firebug's console:
var data = {"A5A50000":[{"bsid":"A5A50000","chanCount":17,"time":"2009-05-27 16:36:45","avgInterference":1.711765,"maxInterference":4.97,"avgHandsets":205.1176,"maxHandsets":315,"avgCalls":6.4118,"maxCalls":13,"avgCBA":3868.98059,"maxCBA":7463,"sumSuccessCBA":197318,"sumTimeoutHandoff":133,"sumAttemptHandoff":1028,"sumDeniedHandoff":216,"sumConfirmHandoff":679,"sumHandoffNetwork":61873,"sumJoinNetwork":96888,"sumLeaveNetwork":93754,"sumRcvdKeepalive":98773,"sumTimeoutKeepalive":19748,"sumAttemptUplink":93689,"sumBlockedUplink":62453}]};
var bsID = 'A5A50000';
alert(data[bsID][0].time);
In Javascript, you can use either object or array-style notation to look up an attribute. The following are equivalent:
data.A5A50000
data['A5A50000']
With the second syntax, you can use a variable in place of an object string:
data[bsID][0]
I experienced the same problem with a nested JSON API-response:
[
{
"bj_code": "2019",
"BJ_PERIODE": [
{
"nummer": 1
},
{
"nummer": 2
}
]
}
]
I could evaluate:
pm.expect(pm.response.json()[0].BJ_PERIODE[1].nummer).to.eql(2);
But working with BJ_PERIODE and nummer through a variable didn't work.
Writing it with the bracket method did work, even in this nested JSON, like this:
const periode = "BJ_PERIODE";
const nr = "nummer";
pm.expect(pm.response.json()[0][periode][1][nr]).to.eql(2);

Categories

Resources