Iterating through json api dictionary field - json

Is there a way to iterate through an api using an ajax "GET" method on a given url? I have a series of ranks with data contained therein and I'm trying to use a for loop to access the data. The api is structured as such:
{
"top_5":{
"rank_1": [
123,
456,
],
"rank_2": [
123,
456,
],
}
}
And my ajax call in the html is written like so:
<script>
for (let i = 1; i < 6; i++) {
$.ajax({
method: "GET",
url: '/refunds/api',
success: function(data){
metric = data.top_5.rank_1
myDiv = 'myChart'+i
barChart()
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
}
</script>
The loop works for generating a unique div id, but now I'm stuck trying to engineer the metric variable so that is dynamic and iterates to data.top_5.rank_i+1 on each loop. I think I need to use the map function, but I'm not sure how'd I'd implement it. Any help would be appreciated.

I believe
metric = data.top_5["rank_"+i]
could work. It's called bracket notation, can be useful when you need to access dicts/objects with variable names.
metric = data["top_5"]["rank_"+i]
would also work for example.
metric = data.top_5."rank_"+i
doesn't work because the interpreter doesn't know what to do with that. For the dot notation it needs it to be typed out like
metric = data.top_5.rank_0
Additionally I noticed you are making 6 api calls where I belive you can make only 1 api call (should improve performance). This would be the modification for that:
<script>
$.ajax({
method: "GET",
url: '/refunds/api',
success: function(data){
for (let i = 1; i < 6; i++) {
metric = data.top_5["rank_"+i];
myDiv = 'myChart'+i;
barChart();
}
},
error: function(error_data){
console.log("error");
console.log(error_data);
}
});
</script>

Related

Unable to retrieve JSON array with AngularJS $resource

I've been trying retrieve values from JSON and so far, been unsuccessful. It does get called on the front-end when I refresh the page, but the information is not passing to the next method. I think the issue might be down to the promises.push... line, as I've tried to debug the method underneath and the information is not being passed on at all.
AngularJS:
var promises = [];
promises.push(SpringDataRestService.get({"collection": "subjects"}).$promise);
// Require each of these queries to complete before continuing
$q.all(promises).then(function (data) {
// Grab the first result
$scope.available = data[0].subjects;
$scope.selected = [];
// If this is an update, get the second result in set
if (data.length > 1) {
// For each permission that is assigned to this role, add ID (name) to selected
for (var i = 0; i < data[1].data.subjects.length; i++) {
var perm = data[1].data.subjects[i];
$scope.selected.push(perm.name);
}
}
$scope.tableEditOptions = new NgTableParams({}, {
dataset: $scope.available
});
$scope.available, 'name');
}).catch(function (data) {
// ERROR
});
JSON:
[
{
"name": "FWGWG",
"description": "WGWGWG",
"lockId": 0
},
{
"name": "QFQFQF",
"description": "QFQFQFQ",
"lockId": 0
}
]
I'm confident as well my for loop is wrong due to assigning the values as well, since I don't think it should be data.subjects, but I understand these threads are only 1 issue per question. Any help would be greatly appreicated.
Use the query method for arrays:
var promise = SpringDataRestService.query({"collection": "subjects"}).$promise;
promise.then(function (dataArr) {
console.log(dataArr);
//...
}).catch(function (errorResponse) {
console.log(errorResponse);
});
With the REST services, the get method returns a JavaScript object and the query method returns a JavaScript array.
From the Docs:
$resource Returns
A resource "class" object with methods for the default set of resource actions optionally extended with custom actions. The default set contains these actions:
{
'get': {method: 'GET'},
'save': {method: 'POST'},
'query': {method: 'GET', isArray: true},
'remove': {method: 'DELETE'},
'delete': {method: 'DELETE'}
}
...
It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data.
For more information, see
AngularJS $resource Service API Reference

Backbone: fetching from URL in router gets undefined, but it works when collection gets JSON from a variable

From a JSON stored in a variable I can get the name of the current id from a router function called show: function(id). However, when I fetch collection from an URL instead of using a JSON variable I get an undefined TypeError.
console.log(this.collection.get(id).get('name'));
What I have seen is that when I use a JSON variable the show function works fine, but when I fetch from URL, show function executes after fetch succeed.
What I am doing wrong? Why fetching from URL gets undefined? How can I make it work?
The following code is fictional, it only shows the relevant part of my code. See the two cases at the end of the code block.
jsFiddle here
// Data 1 with variable
var heroes = [
{"id": "1", "name": "Batman"},
{"id": "2", "name": "Superman"},
];
// Data 2 from url: http://example.com/heroes.json
[
{"id": "1", "name": "Batman"},
{"id": "2", "name": "Superman"},
];
HeroesCollection = Backbone.Collection.extend({
model: HeroesModel,
url: 'http://example.com/heroes.json'
});
HeroesRouter = Backbone.Router.extend({
// I use two shows to graphic this example
routes: {
'': 'index',
':id': 'show'
},
initialize: function(options) {
this.collection = options.collection;
this.collection.fetch();
// this.collection.fetch({async:false}); this fixes my problem, but I heard it is a bad practice
},
index: function() {
},
show: function(id) {
console.log(this.collection.get(id).get('name'));
// Case #1: When Collection loads from a Variable
// id 1 returns: 'Batman'
// Case #2: When Collection fetchs from URL, id 1 returns:
// TypeError: this.collection.get(...) is undefined
}
});
// Case #1: collection loads JSON from a variable
var heroesCollection = new HeroesCollection(heroes);
// Case #2: collection loads JSON with fetch in router's initialize
// var heroesCollection = new HeroesCollection();
var heroesRouter = new HeroesRouter({collection: heroesCollection});
How about this? It's been awhile, but this seems like a better approach to what you are trying to achieve. The basic concept is that once you navigate to your show route, it will execute show. This method will create a new, empty collection, and then fetch the data for it. Along with that, we pass in a success method (as François illustrated) which will execute when the request is finished with the JSON (which creates a collection of Heros).
I believe the reason you were running into the issue with the remote data is that you were trying to access this.collection before it was populated with data from the request.
You have to remember the request is asynchronous, which mean code execution continues while the request is processing.
HeroesCollection = Backbone.Collection.extend({
model: HeroesModel,
url: 'http://example.com/heroes.json'
});
HeroesRouter = Backbone.Router.extend({
routes: {
'': 'index',
':id': 'show'
},
index: function() {
},
show: function(id) {
this.herosCollection = new HerosCollection();
this.herosCollection.fetch({
success: function(collection, response, options) {
console.log(this.get(id).get('name'));
}
});
}
});
you need to trigger the router 'show' function when the collection has ended to load.
this.collection.fetch({async:false}); fixes your problem because the whole javascript code is waiting (async:false) the ajax call to be ended before going further.
The other and best solution is to wait that your collection is fetched before you try to use the results.
Basically:
MyCollection.fetch({
success: function(model, reponse) {
// do wtv you want with the result here or trigger router show method...
}
});

Pass fancytree data as JSON data

I want to pass the data from a fancytree to a generic handler so that I can save it for future use.
If I use this code:
function SaveTree() {
var tree = $('#TopTree').fancytree("getTree");
$.ajax({
cache: false,
url: "SaveTree.ashx",
data: { 'treeData': tree },
contentType: "application/json; charset=utf-8"
});
}
Then I get the following error from jquery.js:
JavaScript runtime error: Argument not optional
I have also tried:
var tree = $('#TopTree').fancytree("getTree").rootNode.children;
This gives the same error. I understand it is because 'tree' is not JSON. How can I convert the data to a JSON object?
EDIT:
If I use this code:
function SaveTree() {
var data = [];
var tree = $('#TopTree').fancytree("getTree").rootNode.children;
for (var i = 0; i < tree.length; i++) {
data.push(tree[i].title)
}
data = JSON.parse(JSON.stringify(data))
$.ajax({
cache: false,
url: "SaveTree.ashx",
data: { 'treeData': data },
contentType: "application/json; charset=utf-8"
});
}
I can get it to accomplish what I need, but is there not a built-in function for this in fancytree?
Okay, I don't really know a lot about FancyTree; however, I did some investigation and found this page http://wwwendt.de/tech/fancytree/demo/sample-api.html.
Try the tree.ToDict() option to see if that is what you're looking for.
This is the source code.
// Convert the whole tree into an dictionary
var tree = $("#tree").fancytree("getTree");
var d = tree.toDict(true);
alert(JSON.stringify(d));

Parse JSON from JQuery.ajax success data

I am having trouble getting the contents of JSON object from a JQery.ajax call. My call:
$('#Search').click(function () {
var query = $('#query').valueOf();
$.ajax({
url: '/Products/Search',
type: "POST",
data: query,
dataType: 'application/json; charset=utf-8',
success: function (data) {
alert(data);
for (var x = 0; x < data.length; x++) {
content = data[x].Id;
content += "<br>";
content += data[x].Name;
content += "<br>";
$(content).appendTo("#ProductList");
// updateListing(data[x]);
}
}
});
});
It seems that the JSON object is being returned correctly because "alert(data)" displays the following
[{"Id": "1", "Name": "Shirt"}, {"Id": "2", "Name":"Pants"}]
but when I try displaying the Id or Name to the page using:
content = data[x].Id;
content += "<br>";
content += data[x].Name;
content += "<br>";
it returns "undefined" to the page. What am I doing wrong?
Thanks for the help.
The data is coming back as the string representation of the JSON and you aren't converting it back to a JavaScript object. Set the dataType to just 'json' to have it converted automatically.
I recommend you use:
var returnedData = JSON.parse(response);
to convert the JSON string (if it is just text) to a JavaScript object.
It works fine,
Ex :
$.ajax({
url: "http://localhost:11141/Search/BasicSearchContent?ContentTitle=" + "تهران",
type: 'GET',
cache: false,
success: function(result) {
// alert(jQuery.dataType);
if (result) {
// var dd = JSON.parse(result);
alert(result[0].Id)
}
},
error: function() {
alert("No");
}
});
Finally, you need to use this statement ...
result[0].Whatever
One of the way you can ensure that this type of mistake (using string instead of json) doesn't happen is to see what gets printed in the alert. When you do
alert(data)
if data is a string, it will print everything that is contains. However if you print is json object. you will get the following response in the alert
[object Object]
If this the response then you can be sure that you can use this as an object (json in this case).
Thus, you need to convert your string into json first, before using it by doing this:
JSON.parse(data)
Well... you are about 3/4 of the way there... you already have your JSON as text.
The problem is that you appear to be handling this string as if it was already a JavaScript object with properties relating to the fields that were transmitted.
It isn't... its just a string.
Queries like "content = data[x].Id;" are bound to fail because JavaScript is not finding these properties attached to the string that it is looking at... again, its JUST a string.
You should be able to simply parse the data as JSON through... yup... the parse method of the JSON object.
myResult = JSON.parse(request.responseText);
Now myResult is a javascript object containing the properties that were transmitted through AJAX.
That should allow you to handle it the way you appear to be trying to.
Looks like JSON.parse was added when ECMA5 was added, so anything fairly modern should be able to handle this natively... if you have to handle fossils, you could also try external libraries to handle this, such as jQuery or JSON2.
For the record, this was already answered by Andy E for someone else HERE.
edit - Saw the request for 'official or credible sources', and probably one of the coders that I find the most credible would be John Resig ~ ECMA5 JSON ~ i would have linked to the actual ECMA5 spec regarding native JSON support, but I would rather refer someone to a master like Resig than a dry specification.
Try the jquery each function to walk through your json object:
$.each(data,function(i,j){
content ='<span>'+j[i].Id+'<br />'+j[i].Name+'<br /></span>';
$('#ProductList').append(content);
});
you can use the jQuery parseJSON method:
var Data = $.parseJSON(response);
input type Button
<input type="button" Id="update" value="Update">
I've successfully posted a form with AJAX in perl. After posting the form, controller returns a JSON response as below
$(function() {
$('#Search').click(function() {
var query = $('#query').val();
var update = $('#update').val();
$.ajax({
type: 'POST',
url: '/Products/Search/',
data: {
'insert': update,
'query': address,
},
success: function(res) {
$('#ProductList').empty('');
console.log(res);
json = JSON.parse(res);
for (var i in json) {
var row = $('<tr>');
row.append($('<td id=' + json[i].Id + '>').html(json[i].Id));
row.append($('<td id=' + json[i].Name + '>').html(json[i].Name));
$('</tr>');
$('#ProductList').append(row);
}
},
error: function() {
alert("did not work");
location.reload(true);
}
});
});
});
I'm not sure whats going wrong with your set up. Maybe the server is not setting the headers properly. Not sure. As a long shot, you can try this
$.ajax({
url : url,
dataType : 'json'
})
.done(function(data, statusText, resObject) {
var jsonData = resObject.responseJSON
})
From the jQuery API: with the setting of dataType, If none is specified, jQuery will try to infer it with $.parseJSON() based on the MIME type (the MIME type for JSON text is "application/json") of the response (in 1.4 JSON will yield a JavaScript object).
Or you can set the dataType to json to convert it automatically.
parse and convert it to js object that's it.
success: function(response) {
var content = "";
var jsondata = JSON.parse(response);
for (var x = 0; x < jsonData.length; x++) {
content += jsondata[x].Id;
content += "<br>";
content += jsondata[x].Name;
content += "<br>";
}
$("#ProductList").append(content);
}
Use
dataType: 'json'
In .NET you could also return Json(yourModel) in your action method/API controller.
And parse the returned JSON as follows in the Jquery .ajax:
if you've a complex object: navigate to it directly.
success: function (res) {
$.each(res.YourObject, function (index, element) {
console.log(element.text);
console.log(element.value);
});
});

parsing json in jquery autocomplete

I've used Simon Whatley's code for the autocomplete plugin. Now, I need help in parsing a jSON data. Here is my code:
$("#country").autocomplete("data/country.cfm",{
minChars:1,
delay:0,
autoFill:false,
matchSubset:false,
matchContains:1,
cacheLength:10,
selectOnly:1,
dataType: 'json',
extraParams: {
format: 'json'
},
parse: function(data) {
var parsed = [];
for (var i = 0; i < data.length; i++) {
parsed[parsed.length] = {
data: data[i],
value: data[i].NAME,
result: data[i].NAME
};
}
return parsed;
},
formatItem: function(item) {
return item.NAME;
}
});
For example, I get this as my jSON string:
[{"name":"country1"},{"name":"country2"},{"name":"country3"}]
What I like to get as results, of course, are the values country1, country2, country3. However, what I get right now in the textbox when I type (e.g. I type "cou") is "undefined". If I click that, what shows in the textfield is the whole string [{"name":"country1"},{"name":"country2"},{"name":"country3"}].
I've also tried these but still not working:
jquery autocomplete, how to parse a json request with url info?
jquery autocomplete with json response
Help please. Thanks!
You can just simply use
var countries = JSON.parse(data);
Since you're using jQuery though, it's a bit safer to use jQuery.parseJSON() in case the browser doesn't have a native parser:
var countries = jQuery.parseJSON(data);