I’m requesting JSON from Wikipedia’s API at
http://en.wikipedia.org/w/api.php?action=query&prop=description&titles=WTO&prop=extracts&exsentences&explaintext&format=json
The response looks like this:
{
"query": {
"pages": {
"ramdom_number_here": {
"pageid": ramdom_number_here,
"ns": 0,
"title": "Hello",
"extract": "Hello world! Enchanté to meet you"
}
}
}
}
Given that ramdom_number_here changes each request (so we don't know it), how can extrac or title’s data be accessed?
Use Object.keys(data)[x] to replace the nominative pathway byt the the coordinate of your data.
Object.keys(data) -- give you the list of keys at that level.
Then use x=the numeral rang of your target data. For the first data point, then [x]=[0].
Solution> JSfiddle:
function WD(val) { // input
target_API_url = "http://zh.wikipedia.org/w/api.php?action=query&prop=description&titles=" + val.toString() + "&prop=extracts&exintro&explaintext&format=json&redirects&callback=?";
$.getJSON(target_API_url, function (json) {
trad = json.query.redirects[0].to; // no "var", variable is global
var item_id = Object.keys(json.query.pages)[0]; // THIS DO THE TRICK !
sent = JSON.stringify(json.query.pages[item_id].extract);
result = "<b>En:</b> "+val.toString() + ", <b>Zh: </b>"+trad.toString() + "<br /><b>⇒</b>" + sent.toString();
$('p').html(result); // transformation
});
};
WD("WTO");
Encouraging +1 welcome.
In javascript you can:
var a; // assume that a is your json
var title;
for (var obj in a["query"]["pages"])
{
if (a["query"]["pages"][obj].title != undefined)
{
title = a["query"]["pages"][obj].title;
break;
}
}
Related
I see there is a problem to get a String name from JSON object's name.
I need to parse this kind on JSON response from server.
var response = {
hopaopGmailsjIpW: {
GmailsjIpW_totalEmails_count: 133,
GmailsjIpW_state: 1
},
hopaopGmail4y4yu: {
Gmail4y4yu_totalEmails_count: 156,
Gmail4y4yu_state: 1
}
}
It is not an Array, but the object with inner objects.
i need to parse an inner ojects name and add additional values to each object.
i want be able to do something like this:
for(var i =0; i < response.length; i++){
response[i].username = parseUsernameFromString(response[i]);
response[i].service = parseServiceFromString(response[i]);
response[i].id = parseIdString(response[i]);
}
(and also state for each task)
So the question is:
What is the best way to make it?
UPDATE
this is exactly what i have for now:
for(var key in response){
if(stringContains(response[key], "Gmail")) { response[key].service = "Gmail";}
console.log("task name: "+ response[key].service);
}
function stringContains(originalString, searchString){
if(originalString.indexOf(searchString) > -1){
return true
}
else return false;
}
For walking through Objects, you need to use for ... in loop.
The real problem is: There's a , missing in your code. See the fixed working snippet:
Snippet
var response_Parsed = {
hopaopGmailsjIpW: {
GmailsjIpW_totalEmails_count: 133,
GmailsjIpW_state: 1,
service: 'Gmail',
username: 'hopaop',
id: 'sjIpW'
},
hopaopGmail4y4yu: {
Gmail4y4yu_totalEmails_count: 156,
Gmail4y4yu_state: 1,
service: 'Gmail',
username: 'hopaop',
id: '4y4yu'
}
};
for (id in response_Parsed) {
console.log("----");
if (id.indexOf("Gmail") > -1) {
console.log("We have Gmail: " + id);
console.log("UniqueName: " + id.replace("hopaopGmail", ""));
console.log("Username: " + response_Parsed[id].username);
console.log("Email Count: " + response_Parsed[id][id.replace("hopaop", "") + "_totalEmails_count"]);
}
else
console.log("We don't have Gmail: " + id);
}
And also the right way to enumerate the through the keys of the objects, is by using Object.keys.
If the response is a String like you wrote, you should first parse the JSON-String into an Object (if you're using a library like jQuery, it's probably already a JSON, as this conversion is done by jQuery automatically):
var obj = JSON.parse(responseString);
Afterwards you may iterate through it like posted above:
for (var key in obj) {
console.log("key", key, "value", obj[key]);
}
I have a bunch of log data which is stored in a variable. Each log value contains a camera name and system ip. I want to create an object which has names as all the distinct system ip's and corresponding value as an array which contains all the camera names corresponding to that system ip. Below is my code ---
$http(req).success(function(data){
$scope.logs = data;
$scope.cameras={};
var v =$scope.logs[0].systemIp;
$scope.cameras["v"]=[];
$scope.cameras["v"].push($scope.logs[0].cameraName);
for(i=1;i<$scope.logs.length;i++){
v=$scope.logs[i].systemIp;
var flag=0;
for(j in $scope.cameras){
if(j==="v")
{
flag=1;
break;
}
}
if(flag==0)
{
$scope.cameras["j"]=[];
$scope.cameras["j"].push($scope.logs[i].cameraName);
}
else if(flag==1)
{
$scope.cameras["v"].push($scope.logs[i].cameraName);
}
}});
And this is what my data looks like --
[{
"_id": "57683fd82c77bb5a1a49a2aa",
"cameraIp": "192.16.0.9",
"cameraName": "garage2",
"systemIp": "192.168.0.2"
},
{
"_id": "57683f8e2c77bb5a1a49a2a9",
"cameraIp": "192.16.0.8",
"cameraName": "garage1",
"systemIp": "192.168.0.2"
},
{
"_id": "57683f5e2c77bb5a1a49a2a8",
"cameraIp": "192.16.0.7",
"cameraName": "Back Door",
"systemIp": "192.168.0.4"
}]
When I print $scope.cameras on my console it gives this as the output -
Object { v: Array[3] }
I want by cameras object to look like this --
{ "192.168.0.2" : [ "garage1" , "garage2"] ,
"192.168.0.4" : [ "Back Door"] }
I am new to javascript, any help is appreciated.
If you are using the Lodash or Underscore library (which I highly recommend), you can just use the _.groupBy() function to do what you are after (along with some other functions to ensure all values are unique).
However, you can also easily implement it yourself:
function groupByDistinct(arr, prop, mapFn) {
mapFn = mapFn || function (x) { return x; };
var output = {};
arr.forEach(function (item) {
var key = item[prop],
val = mapFn(item);
if (!output[key]) {
output[key] = [val];
return;
}
if (output[key].indexOf(val) < 0) {
output[key].push(val);
}
});
return output;
}
Use it for your code like so:
$scope.cameras = groupByDistinct(data, 'cameraIp', function (logEntry) {
return logEntry.cameraName;
});
You are passing a string such as "v" or "j" as your object key, and this string are actually ending being your object key and not the value of this variables as you want. You can use something like this:
for(i=0; i < $scope.logs.length; i++){
var _sysIp = $scope.logs[i].systemIp,
_camName = $scope.logs[i].cameraName;
if(!$scope.cameras.hasOwnProperty(_sysIp)) {
$scope.cameras[_sysIp] = [_camName];
} else if ($scope.cameras[_sysIp].indexOf(_camName) < 0) {
$scope.cameras[_sysIp].push(_camName);
}
}
SITUATION:
I have dynamic json object data and need to use it to find element.
Example:
[
{ "tag": "article",
"id": "post-316",
"order": "0" },
{ "tag": "div",
"class": "entry-content",
"order": "0" }
]
Its length, keys and values can change anytime based on user request.
I need to use that data to dynamically find the specified element in a web page. The first set of strings will be the data for parent element, which will be used to initialize the search, and the last one will be the target children.
PURPOSE:
So, from json example above, I want to find an element with:
class name entry-content, tag name div, index 0 inside of parent with id post-316
by converting that json data in such kind of format or may be simpler and or better:
// because the parent already have attribute id, so no need to check other info of this element
var elem = $("#post-316").find(".entry-content");
if(elem.prop("tagName") == "div" ) {
elem.css("background", "#990000");
}
PROGRESS:
I tried using jquery $.each() method but can't discover myself the way to achieve that purpose.
Here is the code where I currently stuck on:
var json = $.parseJSON(theJSONData);
$.each(json, function(i, e){
$.each(e, function(key, data){
alert(i + " " + key + " " + data);
if(json.length - i == 1) {
alert("target " + data);
}
if(json.length - i == json.length) {
alert("parent " + data);
}
}
);
});
QUESTIONS:
Is it possible to achieve the PURPOSE from that kind of JSON data using iteration?
If it is possible, how to do it?
If not, what the way I can use?
You can use a format so the script knows what to get:
var data = {
'id': '#',
'class': '.'
};
var json = JSON.parse(theJSONData);
$.each(json, function (a) {
$.each(data, function (b) {
if (a[b]) {
$(data[b] + a[b])[+a['order']]; // Element
}
});
});
If you are sure about the data you are getting (As in it is class, or data, and it will have a tag name):
var json = JSON.parse(theJSONData),
last = document;
$.each(json, function (a) {
var selector = (a['id']) ? '#'+a['id'] : '.'+a['class'];
last = $(last).find(a['tag']+selector)[+a['order']]; // Element
});
I'm trying to wrap my brain around promises and I'm refactoring some nested callbacks into promises. I'm encountering something I don't understand and any help anyone could provide would be appreciated. There's definitely something wrong with my for-loop; I suppose that sort of structure is invalid but I'm not sure what to do about it. Also, the result coming back from insertTickersDb function appears to take my entire array and insert it as a single record - not what I was hoping for. I know I'm doing things wrong - please help me understand which things.
I have bound a function to mongoose like this:
var insertTickersDb = q.nfbind(db.tickers.insert.bind(db.tickers));
I have an insert function that looks like this:
function insertTickers(symbols) {
console.log("inserting tickers");
if (symbols) {
if (!(symbols instanceof Array)) {
symbols = [symbols];
}
var tickersToInsert = [];
symbols.map(function(symbol) {
tickersToInsert.push({
symbol: symbol
});
});
console.log("tickersToInsert = " + JSON.stringify(tickersToInsert));
return insertTickersDb(tickersToInsert);
}
}
and I have a test like this:
describe("tickerIntegrationTests internal testing tools", function() {
it("insertTickers should insert the provided tickers", function(done) {
var tickerList = ["A", "B", "C"];
insertTickers(tickerList).then(function(data) {
console.log("inside insertTickers, data = " + JSON.stringify(data));
for (var d = 0; d < data.length; d++) {
console.log("d = " + d + ",data[d].symbol = " + data[d].symbol);
assert.equal(data[d].symbol, tickerList[d]);
}
}).then(removeTickers(tickerList)).done(function(){done();});
});
});
My output is:
tickerIntegrationTests internal testing tools
inserting tickers
tickersToInsert = [{"symbol":"A"},{"symbol":"B"},{"symbol":"C"}]
inside insertTickers, data = [[{"symbol":"A","_id":"552faf5c0aac9578428320da"},{"symbol":"B","_id":"552faf5c0aac9578428320db"},{"symbol":"C","_id":"552faf5c0aac9578428320dc"}],{"n":0}]
d = 0,data[d].symbol = undefined
It might help if you expand out the json of the inner call
[
[
{
"symbol": "A",
"_id": "552faf5c0aac9578428320da"
},
{
"symbol": "B",
"_id": "552faf5c0aac9578428320db"
},
{
"symbol": "C",
"_id": "552faf5c0aac9578428320dc"
}
],
{
"n": 0
}
]
Now you can see the the data is an array whose first element is the data array you are expecting. If you looked at data[0] you would find the first ticker. d[0].symbol should contain what you are looking for. You might want to look at t
I have a function with a rather convoluted object in this format:
function getNBATeamsESPNByAbbrev(abbrev)
{
var json = {
"sports":[
{
"name":"basketball",
"id":40,
"uid":"s:40",
"leagues":[
{
"name":"National Basketball Assoc.",
"abbreviation":"nba",
"id":46,
"uid":"s:40~l:46",
"groupId":7,
"shortName":"NBA",
"teams":[
{
"id":1,
"uid":"s:40~l:46~t:1",
"location":"Atlanta",
"name":"Hawks",
"abbreviation":"ATL",
},
{
"id":2,
"uid":"s:40~l:46~t:2",
"location":"Boston",
"name":"Celtics",
"abbreviation":"BOS",
"color":"006532",
},
]
}
]
}
],
"resultsOffset":0,
"resultsLimit":50,
"resultsCount":30,
"timestamp":"2014-03-22T23:42:43Z",
"status":"success"
}
obj = _.find(json.sports[0].leagues[0].teams, function(obj) { return obj.abbreviation == abbrev })
if (obj !== undefined)
{
var team = new Object();
team.abbrev = abbrev;
team.location = obj.location;
team.nickname = obj.name;
return team;
}
}
It can be easier seen at this example JSFiddle. So I have the team abbreviation, and I want to pull back the team object as a whole (this is a stripped down version, leaving only the necessary details). This seems to work fine. However, another case has arisen, one in which I need to pull back the team object based on its location + " " + name. So I tried to do the same thing using underscore.js, passing in the parameter name, and changing the predicate in ._find to return obj.location + " " + obj.name == name. For example, I'd pass in Atalnta Hawks as name and expect to return the relevant team object. Here's a very similar JSFiddle demonstrating the change. But, now it can't seem to find the team object I want to pull. Is it because such a string concatenation isn't allowed in underscore.js, or is there something stupid I'm missing?
Line 50, you have:
team.abbrev = obj.abbrev;
and it should be
team.abbrev = obj.abbreviation;