Grabbing data from JSON using Javascript - javascript

Ok so I have a json output that looks like this:
{"Result" : [
{
"Id" : "5214",
"ParentReasonId" : "0",
"Description" : "Billing & Payment",
"SysName" : "Billing & Payment",
"SysCategory" : "Billing & Payment",
"ClientId" : "924",
"DispositionCount" : "6",
"IsActive" : true,
"ChildReasonCount" : "8",
"Attributes" : [],
"SortOrder" : "0",
"CreatedBy" : null
}
]
}
And I would like to pull the data for id and description out of this.
jQuery("#chained_child").cascade("#chained", {
ajax: { url: 'Customhandler.ashx?List=MyList' },
template: commonTemplate,
match: commonMatch
});
function commonTemplate(item) {
return "<option Value='" + item.Result.Id + "'>"
+ item.Result.Description + "</option>";
};
But for the life of me I can't get it to return the value I am looking for. I know this is something noobish but I am hitting a wall. Can anyone help?

If you examine your JSON string, your Result object is actually an array of size 1 containing an object, not just an object. You should remove the extra brackets or refer to your variable using:
item.Result[0].Id
In order to reference your variable using item.Result.Id you would need the following JSON string:
{
"Result" :
{
"Id" : "5214",
"ParentReasonId" : "0",
"Description" : "Billing & Payment",
"SysName" : "Billing & Payment",
"SysCategory" : "Billing & Payment",
"ClientId" : "924",
"DispositionCount" : "6",
"IsActive" : true,
"ChildReasonCount" : "8",
"Attributes" : [],
"SortOrder" : "0",
"CreatedBy" : null
}
}

One thing that has helped me immensely with JSON funkyness has been setting breakpoints in Firebug, which let's you step through the resulting object, and view its structure.

item.Result[0].Id works as Sebastian mentioned - however it only works if "item" is actually assigned a value. My guess is it's not.
In your commonTemplate function try doing console.log(item) and seeing what the result is.

As far as I see it on the plugin page, the argument send to the template callback is an
item from the JSON response, which is an Array. Your JSON response is an Object. I guess you're not sending the correct JSON response. But take that with a grain of salt, as I've never used this plugin.
Anyway, if I'm right, you're response should be:
[
{
"Result" :
{
"Id" : "5214",
"ParentReasonId" : "0",
"Description" : "Billing & Payment",
"SysName" : "Billing & Payment",
"SysCategory" : "Billing & Payment",
"ClientId" : "924",
"DispositionCount" : "6",
"IsActive" : true,
"ChildReasonCount" : "8",
"Attributes" : [],
"SortOrder" : "0",
"CreatedBy" : null
}
}
]

Ionut G. Stan's answer is correct. Your json output is not the correct format for the cascade plugin.
If you don't want to change your json, you can use the dataFilter option in the ajax settings to augment the data.
I've set up a working demo here: http://jsbin.com/ebohe (editable via http://jsbin.com/ebohe/edit )
Here's the pertinent javascript:
$(function(){
$('#chained_child').cascade(
'#chained',
{
ajax: {
url: 'Customhandler.ashx?List=MyList',
dataFilter: extractResult
},
template: customTemplate,
match: customMatch
}
);
function extractResult(data) {
return eval('(' + data + ')').Result;
}
function customTemplate(item) {
return $('<option />')
.val(item.Id)
.text(item.Description);
}
function customMatch(selectedValue) {
return this.ParentReasonId == selectedValue;
}
});

You might want to take a look at this JSON tutorial from IBM:
Mastering Ajax, Part 10: Using JSON for data transfer

Related

Firebase realtime database - orderByChild not returning any result

I am using the Firebase Realtime Database functions .orderByChild() and .equalTo() to fetch data nodes to be updated. However, I cannot seem to get any results back from my queries.
My database structure
{
"4QEg0TWDbESiMX8Cu8cvUCm17so2" : {
"-LmGtXsgJbAvVS8gv5-E" : {
"createdAt" : 1565815876803,
"message" : "Hello",
"isSender" : false,
"sender" : {
"alias" : "",
"name" : "Person A",
"sid" : "mUO3DtYY2yRw3zkv4EmTlfldB3S2"
},
"sysStatus" : 0
},
"-LmGtt4nyuygG9B4s6__" : {
"createdAt" : 1565815967746,
"message" : "Hej!",
"isSender" : true,
"sender" : {
"alias" : "",
"name" : "Person B",
"sid" : "4QEg0TWDbESiMX8Cu8cvUCm17so2"
},
"sysStatus" : 0
},
"-LmJxcvL_Y7JmojxPiiK" : {
"createdAt" : 1565867281849,
"isSender" : true,
"message" : "111",
"sender" : {
"alias" : "",
"name" : "Person B",
"sid" : "4QEg0TWDbESiMX8Cu8cvUCm17so2"
},
"sysStatus" : 0
}
},
"mUO3DtYY2yRw3zkv4EmTlfldB3S2" : {
"222" : {
"createdAt" : 1565867281849,
"isSender" : true,
"message" : "Test",
"sender" : {
"alias" : "",
"name" : "Person A",
"sid" : "mUO3DtYY2yRw3zkv4EmTlfldB3S2"
},
"sysStatus" : 0
},
"333" : { <-- This is one node I wish to fetch
"createdAt" : 1565815967746,
"isSender" : false,
"message" : "123",
"sender" : {
"alias" : "",
"name" : "Person B",
"sid" : "4QEg0TWDbESiMX8Cu8cvUCm17so2" <-- This is the value I am trying to match
},
"sysStatus" : 0
}
},
"rKNUGgdKqdP68T0ne6wmgJzcCE82" : {
"-Lm_GTmNHyxqCqQl4D4Z" : { <-- This is one node I wish to fetch
"createdAt" : 1566140917160,
"isSender" : false,
"message" : "Sesame",
"sender" : {
"alias" : "",
"name" : "Person B",
"sid" : "4QEg0TWDbESiMX8Cu8cvUCm17so2" <-- This is the value I am trying to match
},
"sysStatus" : 5
}
}
}
My code
dbRoot.child('messages')
.orderByChild('sid')
.equalTo(userId)
.once('value', (senderSnapshot) => {
console.log('senderSnapshot', senderSnapshot.val())
console.log('senderSnapshot amount', senderSnapshot.numChildren())
senderSnapshot.forEach((sender)=>{
//Do the work!
})
})
The code logs
senderSnapshot null
senderSnapshot amount 0
I have manually checked that there are several nodes where "sid" is set to the "userId" I am looking for.
Why am I not getting any results back from my query?
It seems like I have to search dbRoot.child('messages/rKNUGgdKqdP68T0ne6wmgJzcCE82') to get my value. :/ (And then repeat the search for each user)
How much extra data overhead would it be to download/collect all contacts and then loop thru each users contact?
Firebase Database queries allow you to search through the direct child nodes at a certain location for a value at a fixed path under each child. So: if you know the user whose message you want to search through, you can do:
dbRoot
.child('messages')
.child('mUO3DtYY2yRw3zkv4EmTlfldB3S2') // the user ID
.orderByChild('sender/sid')
.equalTo(userId)
Note the two changes I made here from your code:
We now start the search from messages/mUO3DtYY2yRw3zkv4EmTlfldB3S2, so that it only searches the messages for that one user.
We now order/filter on the sender/sid property for each child under messages/mUO3DtYY2yRw3zkv4EmTlfldB3S2.
By combining these we are essentially searching a flat list of child nodes, for a specific matching value at a path under each child node.
There is no way in your current data structure to find all messages for a specific sender/sid value across all users. To allow that you'll have to add an additional data structure, where you essentially invert the current data.
"sender_messages": {
"mUO3DtYY2yRw3zkv4EmTlfldB3S2": {
"4QEg0TWDbESiMX8Cu8cvUCm17so2/-LmGtXsgJbAvVS8gv5-E": true,
},
"4QEg0TWDbESiMX8Cu8cvUCm17so2": {
"4QEg0TWDbESiMX8Cu8cvUCm17so2/-LmGtXsgJbAvVS8gv5-E": true,
"4QEg0TWDbESiMX8Cu8cvUCm17so2/-LmGtt4nyuygG9B4s6__": true,
"4QEg0TWDbESiMX8Cu8cvUCm17so2/-LmJxcvL_Y7JmojxPiiK": true,
"mUO3DtYY2yRw3zkv4EmTlfldB3S2/333": true,
"rKNUGgdKqdP68T0ne6wmgJzcCE82/Lm_GTmNHyxqCqQl4D4Z": true
},
"mUO3DtYY2yRw3zkv4EmTlfldB3S2": {
"mUO3DtYY2yRw3zkv4EmTlfldB3S2/222": true,
}
}
Now you can find the messages for a specific sender/sid by reading:
dbRoot
.child('sender_messages')
.child('4QEg0TWDbESiMX8Cu8cvUCm17so2') // the sender ID
And then looping over the results, and loading the individual messages from each path as needed.
This is quite common in NoSQL databases: you'll often have to modify your data structure to allow the use-cases you want to add to your app.
See also:
Firebase query if child of child contains a value
Firebase Query Double Nested
Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly (to learn why loading the additional messages is not nearly as slow as you may initially think)

Firebase query taking forever

My firebase data looks like this...
In JSON down below...
I've been trying to use what I've found in their docs to query the db so that I end up with of all the terms and their keys. How do I query just the term property and key for every node under vocab? I'm using this to populate an autosuggest. Also, the 0 and 1 under the vocab node are keys... they showed up that way when I imported the data as a JSON file. Any new vocab goes in with unique long key values though.
I've tried both .on() and .equalTo()... But I have had no luck whatsoever. It always seems to be grabbing everything in the entire vocab node of the database and taking on the order of 7 whole seconds to do it each time. Here is an example of one of my attempts where I try to put just the terms into an array...
let termList = [];
const termsRef = firebase.database().ref('vocab/');
termsRef.on('child_added', snap => termList.push(snap.val().term));
This doesn't even get the keys (which I need) and it still takes around 7 seconds to do it. I've seen videos where people do things like this in one line and it goes quick... not my luck. Any help would be much appreciated.
As requested here is a JSON sample of one of the database nodes... there are over 400 like this... the relevant property is term... all the way at the bottom. I need an array of terms and firebase database keys. How do I get them with a query?
{
"date" : "2016-07-26T14:50:10.906Z",
"defs" : [ {
"AddedBy" : "",
"date" : "2016-07-26T14:50:10.906Z",
"def" : "it's your need to fulfill or to obtain your full potential, and have meaningful goals.",
"image" : ""
}, {
"AddedBy" : "",
"date" : "2016-07-26T14:50:10.906Z",
"def" : "the very last stage in priority in order to be happy.",
"image" : ""
}, {
"AddedBy" : "",
"date" : "2016-07-26T14:50:10.906Z",
"def" : "the need to be able to set goals and reach them and be able to accept one's self.",
"image" : ""
} ],
"examples" : [ {
"AddedBy" : "",
"addDate" : "2016-07-26T14:50:10.906Z",
"approved" : true,
"checkDate" : "2016-07-26T14:50:10.906Z",
"example" : "a self-actualizing person is a person who accepts themselves, sets realistic and meaningful goals and accepts change.",
"feedback" : {
"comment" : "",
"grammarTrouble" : false,
"incorrect" : false,
"moreSpecific" : false,
"noContext" : false
},
"nonExample" : false,
"seenRecently" : [ {
"sawOn" : "",
"user" : ""
} ]
}, {
"AddedBy" : "",
"addDate" : "2016-07-26T14:50:10.906Z",
"approved" : true,
"checkDate" : "2016-07-26T14:50:10.906Z",
"example" : "who is not self-actualizing is a person who dislikes themselves, has no goals in life, and refuses to accept change.",
"feedback" : {
"comment" : "",
"grammarTrouble" : false,
"incorrect" : false,
"moreSpecific" : false,
"noContext" : false
},
"nonExample" : false,
"seenRecently" : [ {
"sawOn" : "",
"user" : ""
} ]
}, {
"AddedBy" : "",
"addDate" : "2016-07-26T14:50:10.906Z",
"approved" : true,
"checkDate" : "2016-07-26T14:50:10.906Z",
"example" : "Someone who achieves to their best personal ability and faces every situation head on.",
"feedback" : {
"comment" : "",
"grammarTrouble" : false,
"incorrect" : false,
"moreSpecific" : false,
"noContext" : false
},
"nonExample" : false,
"seenRecently" : [ {
"sawOn" : "",
"user" : ""
} ]
} ],
"term" : "Self Actualization",
"unit" : 0
},

trouble parsing json string

I am trying to parse this simple json string:
var dataJSON = {};
var data;
dataJSON = {
"status": "OK",
"messages" : [{
"user" : {
"id" : "4",
"status" : "offline",
"name" : "dummy",
"pictures" : ["pic.jpg"]
},
"message" : "Hey",
"timestamp" : 1395660658
}, {
"user" : {
"id" : "2",
"status" : "online",
"name" : "dummy1",
"pictures" : ["pic1.jpg"]
},
"message" : "hello",
"timestamp" : 1395660658
}]
};
console.log('test');
console.log(dataJSON);
//parse data
data = JSON.parse(dataJSON);
but I am getting the following error:
"unable to parse json string"
I have mo idea why, cheers.
You don't have to parse it at all; it's a JavaScript object already.
The acronym "JSON" stands for JavaScript Object Notation. It's a restricted form of the native syntax in JavaScript for creating objects "on the fly". To say that another way, JavaScript's native object literal syntax is a superset of JSON. What you've typed in there, as the value of your "dataJSON" variable, is a JavaScript object literal expression. The value of such an expression is a reference to an object. No parsing necessary, since the JavaScript parser itself has already done so.
edit — if you really do need a JSON string for testing purposes, then I think the easiest way to do that is to use JSON.stringify() to convert an object into a string, and then pass it into the test code. In your example, that'd look like:
dataJSON = JSON.stringify({
"status": "OK",
"messages" : [{
"user" : {
"id" : "4",
"status" : "offline",
"name" : "dummy",
"pictures" : ["pic.jpg"]
},
"message" : "Hey",
"timestamp" : 1395660658
}, {
"user" : {
"id" : "2",
"status" : "online",
"name" : "dummy1",
"pictures" : ["pic1.jpg"]
},
"message" : "hello",
"timestamp" : 1395660658
}]
});
It's a little easier than trying to construct the string by hand because of the "quote quoting" nuisance. Of course the object you pass in should be one that actually can be represented as JSON, but your sample above is definitely OK.

Unable to print BSON object from javascript

My mongoDB collection looks like this :
{
"_id" : ObjectId("5070310e0f3350482b00011d"),
"emails" : [
{
"_id" : ObjectId("5070310e0f3350482b000120"),
"_type" : "Email",
"name" : "work",
"email" : "peter.loescher#siemens.com",
"current" : true
}
]
}
and this is the .js code i use to print the contents :
c = db.contacts.findOne( { "emails.email" : { $ne : null } }, { "emails" : 1 } )
print(c._id.toString() + " " + c.emails[0]);
when I try to run this javascript file, it is just displaying the id but not the email array.
output:
5070310e0f3350482b00011d [object bson_object]
but when I try c.emails[0].email is is giving proper result. i.e. peter.loescher#siemens.com
All I need is I want to display the whole emails embedded object.
i.e.
"emails" : [
{
"_id" : ObjectId("5070310e0f3350482b000120"),
"_type" : "Email",
"name" : "work",
"email" : "peter.loescher#siemens.com",
"current" : true
}
]
Where I am going wrong?. Any help would be appreciated.
You need printjson to output a nicely formatted JSON:
printjson(c.emails[0]);
Here it is the documentation.

writing more complex json schemas that have dependencies upon other keys

I've been writing simple JSON schemas but I ran into an API input call that is a bit more complex. I have one restful end route that can take 3 very different types of JSON:
localhost/foo
can take:
{ "type" : "ice_cream", "cone" : "waffle" ...}
or
{"type" : "hot_dog", "bun" : "wheat" ...}
If the "type" key contains "ice_cream", I only ever want to see the key "cone" and not the key "bun". Similiarly if "type" contains "hot_dog" I only want to see "bun" and not "cone". I know I can pattern match to make sure I only ever see type "ice_cream" or type "hot_dog", but I don't know how to force the requirement of certain other fields if that key is set to that value. I see that there is a json schema field called "dependency" but I haven't found any good examples on how to use it.
BTW, I'm not sure if this input JSON is good form (overloading the type of JSON structure it takes, effectively), but I don't have the option of changing the api.
I finally got some information about this - it turns out you can make a union of several different objects that are valid like so:
{
"description" : "Food",
"type" : [
{
"type" : "object",
"additionalProperties" : false,
"properties" : {
"type" : {
"type" : "string",
"required" : true,
"enum": [
"hot_dog"
]
},
"bun" : {
"type" : "string",
"required" : true
},
"ketchup" : {
"type" : "string",
"required" : true
}
}
},
{
"type" : "object",
"additionalProperties" : false,
"properties" : {
"type" : {
"type" : "string",
"required" : true,
"enum": [
"ice_cream"
]
},
"cone" : {
"type" : "string",
"required" : true
},
"chocolate_sauce" : {
"type" : "string",
"required" : true
}
}
}
]
}
I'm still not sure if this is valid JSON, since my Schemavalidator dies on some invalid input, but it accepts the valid input as expected.

Categories