Parsing the Freebase Topic HTTP API - JSON & Javascript - javascript

I am trying to parse a JSON output:
http://www.freebase.com/experimental/topic/standard?id=/en/colonel_sanders
I'd like to put the basic data into an array using Javascript. In the "properties" object I'd like to grab any "text" element one level under "properties" as a label and grab the "text" under the "values" object to match the label.
For the above I would get:
"description": "Harland David
Sanders, better known as Colonel
Sanders...
"Organizations founded": KFC
"Cause of death": Leukemia
"Date of death": Dec 16, 1980
"Place of
death": Louisville
"Date of birth":
Sep 9, 1890
"Gender": Male
etc...
I have some code which recursively runs through the JSON but I am a novice with javascript and JSON and am having a lot trouble in step one:
Firstly, grabbing the "text" trying by identifying an element as being "an element of" the main properties object; then
Secondly grabbing from the associated values array any text element (if the value is a collection then I would like to concatenate the strings from the text or otherwise ignore it).
I hope that make sense.
nb. the code I use is similar to here:
http://tlrobinson.net/projects/javascript-fun/jsondiff/

This should get you started:
<script>
function cb(response) {
var props = {};
var properties = response['/en/colonel_sanders'].result.properties;
for (var p_id in properties) {
var prop = properties[p_id];
props[prop.text]=prop.values[0].text;
}
console.log(props);
}
</script>
<script src="http://www.freebase.com/experimental/topic/standard?id=/en/colonel_sanders&callback=cb"></script>

Related

How can I create an object or array of array data in JS with key named elements?

I have an array called values. At present, I'm appending new data to this array as such:
values.push(guests);
The result of my array is something like this:
["123456789", "Joe", "Bloggs", "Test Corp", "fiji", true, "guest, guest 2, guest 3", true]
I have now realised that in its present state this data is useless to me as I cannot tell what each element is. In my example above, the first long number is an account number and the second element is a first name but these are liable to change. E.g the company name Test Corp may not always exist in the data. This means I cannot use the numerical key [3] to target it because it may not be present.
Therefore I need to code this data into something that I can assign both a label for the data, and the data value. I'm guessing the best way to do this would be with an JSON object.
How can I create a key->value pair object? I would need to replace my .push() code above to instead add the value of COMPANY NAME -> Test Corp so that it can be deciphered later.
For reference, I am then stringifying this data and using an AJAX request to POST it to a PHP script where it will need to be arranged into variables e.g $company_name = 'Test Corp';
You're talking about a plain JavaScript object. JSON is a transfer format inspired by JavaScript syntax.
To make an object, just initialize a variable:
var values = {};
And add properties:
values.accountNumber = "123456789";
values.firstName = "Joe";
etc. If you know the properties up front and have values available, you can make the object in one step:
var values = {
accountNumber: "12345678",
firstName: "Joe",
// ...
};

Issue retrieving JSON data in javascript

I have a Json schema like this:
{"THEMES":{
"CATEGORY":
["TEST1","TEST2","TEST3","DFSDFSDF"],
"OVER AGAIN":
["YOUNG","OLD","GRANPA"],
"AND AGAIN":
["AND","ANOTHER","WORD"],
"NEW CATEGORY":
["AGAIN","OOPS","CAN","REDBULL"]
}}
Well, I need to retrieve the keys values inside an AngularJs Controller and my code to retrieve it is like:
$http.get('json/word_bank.json')
.success(function (result) {
$scope.themes = Object.keys(result.TEMAS);
console.log($scope.themes);
And I get in my console:
["CATEGORY", "OVER AGAIN", "AND AGAIN", "NEW CATEGORY"]
So far so good, but I need to access the keys values like TEST1, TEST2, etc.
For this i've tried, for example:
console.log($scope.themes[0][0]);
And the console return the letter "C" or the first letter of the "CATEGORY" string. And this is happening with all of the rest, so the code is transforming my initial array into string elements, I guess. I already tried a lot of loops or iterations over the array, but I not works. Am I missing something?
$scope.themes Is referring to an array of the object keys in the result.THEMES object. When you call $scope.themes[0][0], you are getting the first item of the keys array "CATEGORY", and then the first character of that string "C".
You will need a reference to the actual themes object, then pass the name of the theme to get its values.
themesObject[$scope.themes[0]] -> ["TEST1","TEST2","TEST3","DFSDFSDF"]
Using your code:
$http.get('json/word_bank.json')
.success(function(result) {
$scope.themes = Object.keys(result.THEMES);
console.log(result.THEMES[$scope.themes[0]]);
});

Javascript, JSON - Create Table

I have a JSON Array like:
[{
"name": "abc", "month":"Jan-15","value":xyz
},{
"name": "bcd", "month":"Jan-15","value":xyz
},{
"name": "abc", "month":"Feb-15","value":xyz
},{
"name": "bcd", "month":"Feb-15","value":xyz
}]
No. of "names" may vary from month to month. But no. of "month" stays the same.
I need to create tabular overview:
Name Jan-15 Feb- 15 ...... Dec-15
abc value value ..... value
bcd value value ..... value
I'm new to Javascript and I really don't know how to get values in right columns and rows. Though I know how to dynamically add rows.
Shall I opted for "pure" solution or is better to check for a framework like e.g. AngularJS ?
Edit: I have extracted "Months" and "Names" from array and I need to do something like: value = check for this particular "name" in array and return corresponding "value".
How do I write this in JS?
It depends on the form of your data object. If you have an array object or a string object you need to use JSON.parse in order to be able to use indices and values.
If yes, then you will need to have JSON.parse(data).name to return your name values.
JSON.parse(data).month for your months and of course JSON.parse(data).value to return the xyz values.
If your data is already a JSON object then you will simply use data.name, data.month and data.value accordingly.
These links might help you get into the basics, follow the syntax and the examples.
http://www.w3schools.com/js/js_json.asp
http://www.w3schools.com/json/json_eval.asp
http://www.json.org/js.html and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

Querying/Searching for Values within JSON

For a web site I'm creating, I have to create a quote based on data provided as a JSON string from the server. I've been looking through this site (and various others) but still am unsure on the best way to query/search the data.
For example, I need to get the Area Name from the Area ID. I need to get the maximum age for an area and also the price for a given minimum/maximum age.
I also want to get an array of prices.
Is it best to create a Javascript object from the string using the eval method? Or should I be using jQuery.
Thanks for your help.
({"SkiPass":[{"Id":1,"Area":"Chamonix","Rates":[{"Id":1,"AgeMin":0,"AgeMax":2,"Price":2.5},{"Id":2,"AgeMin":3,"AgeMax":17,"Price":5.0},{"Id":3,"AgeMin":18,"AgeMax":30,"Price":6.2},{"Id":4,"AgeMin":31,"AgeMax":59,"Price":7.4}]},
{"Id":2,"Area":"Megeve","Rates":[{"Id":1,"AgeMin":0,"AgeMax":2,"Price":1},{"Id":2,"AgeMin":3,"AgeMax":17,"Price":2.0},{"Id":3,"AgeMin":18,"AgeMax":30,"Price":2.2},{"Id":4,"AgeMin":31,"AgeMax":59,"Price":4.4}]},
{"Id":3,"Area":"Verbier","Rates":[{"Id":1,"AgeMin":0,"AgeMax":2,"Price":1.5},{"Id":2,"AgeMin":3,"AgeMax":17,"Price":3.0},{"Id":3,"AgeMin":18,"AgeMax":30,"Price":4.2},{"Id":4,"AgeMin":31,"AgeMax":59,"Price":5.4}]}]})
Create a JavaScript object from the string, most definitely, but do it with legitimate JSON parsing facilities and not "eval()". You could use jQuery, but there are other solutions, such as the JSON tools available from json.org, which are small and simple.
Once it's a JavaScript object, well then your needs should guide you as to whether some query solution is necessary, or instead that it's just a simple matter of programming.
I think the best method is jLinq: http://hugoware.net/Projects/jLinq it's like doing a SQL query on JSON.
It doesn't needs jQuery.
I use it, and it's great.
Create the object from the JSON string using JSON.parse() or jQuery.parseJSON() if you are already using jQuery -- or just pass it as from the server side as JSON.
You can then iterate through the object to find the record you want. Or, you can use build your objects so that you can naturally grab data from them.
FloatLeft - as Dan points out, your task would be much easier if you could use XPath but there is no need to re-write your data in XML format. With DefiantJS (http://defiantjs.com) you can now query JSON structure with XPath expressions.
DefiantJS extends the global object JSON with the method "search", which enables XPath queries and returns an array with the matches (empty array if no matches were found). The returned array is equipped with aggregate functions as well; one of these "sortDesc".
Check out this working fiddle;
http://jsfiddle.net/hbi99/H3PR3/
var data = {
"SkiPass": [
...
{
"Id": 3,
"Area": "Verbier",
"Rates": [
{ "Id": 1, "AgeMin": 0, "AgeMax": 2, "Price": 1.5 },
{ "Id": 2, "AgeMin": 3, "AgeMax": 17, "Price": 3 },
{ "Id": 3, "AgeMin": 18, "AgeMax": 30, "Price": 4.2 },
{ "Id": 4, "AgeMin": 31, "AgeMax": 59, "Price": 5.4 }
]
}
]
},
res1 = JSON.search( data, '//SkiPass[Id=3]/Area' ),
res2 = JSON.search( data, '//*[Area and Id=3]/Rates' )
.sortDesc('AgeMax'); // <-- sorting descending by the value of "AgeMax"
document.getElementById('name').innerHTML = res1;
document.getElementById('max_age').innerHTML = res2[0].AgeMax;
document.getElementById('price').innerHTML = res2[0].Price;

Sort nested objects in Array in Javascript

I receive an object from MongoDB request.
Below is a snippet of it:
{
"Kost": "Kost1",
"Name": "Name1",
"inventar": [
{
"data": "A",
"name": "thefirst",
"ean": "802.0165.813",
},
{
"ean": "802.6725.277",
"name": "thesecond",
"data": "B",
},
{
"ean": "570.6761.483",
"name": "thethird",
"data": "C",
},
{
"ean": "570.6764.519",
"name": "thefourth",
"data": "D",
}
]
}
Later, I will create a table in Jade with this code:
table(border='1', cellspacing='3', cellpadding='4')
tr
th(align='center') ean
th(align='center') name
th(align='center') data
each obj in inventar
tr
each val in obj
td= val
The problem is, that the objects in the Array "inventar" are not sorted. The table has a wrong structure. The current output of the table looks like:
|ean | name | data
--------------------------------------------
|802.0165.813| thefirst | A
|B | thesecond | 802.6725.277
|C | thethird | 570.6761.483
|D | thefourth | 570.6764.519
The first column must be the ean, second the name and third the data. Only the first row is correct. I think its luck.
Its possible to sort the objects in the Array ("inventar") before iterating over it, to get the right structure?
I read somewhere that it is not possible to sort directly in mongoose.
thanks in advance
It appears you are asking about the property order in the object. In ES5 and earlier, properties have NO deterministic order by specification. There are some implementations that will maintain the order the properties were created in, but that was not guaranteed.
In ES6, the spec has been changed to say that properties will remain in the order they are created. But, there is no mechanism for reordering properties on an existing object. If you want to change the order, the work-around would be to create a new object, copy the properties over in the desired order and then replace the original object with the new one.
All that said, normal coding should not care what order the properties are in. You refer to a property on an object as in x.inventar[0].data and it should not matter whether data is the first or last property when you dump the object contents.
Given what you are showing in your sample table, it appears that some piece of code is grabbing the first property and putting it in the first column. That is the wrong way to build the table. Instead, it should grab a specific property name and then the order of the properties on the object simply will not matter. So, I think what you need to do is to fix your jade definition to refer to specific property names, not to just take them in order.
I don't know Jade very well myself, but I think you can do something like this:
table(border='1', cellspacing='3', cellpadding='4')
tr
th(align='center') ean
th(align='center') name
th(align='center') data
each obj in inventar
tr
//edited syntax
td= obj.ean
td= obj.name
td= obj.data

Categories