Determine the last element of JSON object - javascript

My server(PHP) response JSON object like this data:
{
"0": {
"action_id": "80",
"action_transaction_id": "5743",
"action_matched_email": "test_1#gmail.com",
"action_by_user": "user1",
"action_count": "0",
"action_date": "2017-07-19 15:01:26"
},
"1": {
"action_id": "1",
"action_transaction_id": "1",
"action_matched_email": "Admin#email.com",
"action_by_user": "ADMIN",
"action_count": "4",
"action_date": "2017-07-19 15:10:08"
},
"new_count": {
"action_count": "4"
}
}
The data are not limited, sometimes server throws many data. It depends on what the condition is.
This is my ajax did after success:
success: function(data, status, jqXHR) {
$.each(data, function(i, row) {
document.getElementById("hidden_counter").value = "";//new_count value here
var allRows =window.parent.document.getElementsByClassName('row'+row.action_transaction_id+'');
for (var i = 0; i < allRows.length; i++) {
allRows[i].style.backgroundColor = '#008e00';
allRows[i].style.color = '#f0fff0';
//should exclude the last array when updating the bgcolor and style color of the row
}
});
}
I have 2 things to know and do.
How can I get the last object?
"new_count": {
"action_count": "4"
}
so that I can update my hidden input value to it.
How can I exclude the last object when updating the styles of rows?

You shouldn't mixup pure js with jquery:
success: function(data, status, jqXHR) {
$('#hidden_counter').val(data.new_count.action_count);
$.each(data, function(i, row) {
if (row.action_transaction_id === undefined) {
return;
}
$('.row' + row.action_transaction_id).css({
backgroundColor: '#008e00',
color: '#f0fff0'
});
});
}

If your object name is lets say jsondata then for accesing new_count you can get it using,
jsondata.new_count
If you want to access last element then you can access it through ,
jsondata.new_count.action_count

How can I get the last object?
Object keys are not sorted and are retrieved in an order specific to browsers. So you can try to do is, get list of keys and take the maximum value.
As commented before, this should do the trick:
var lastIndex = Math.max.apply(null, Object.keys(object).map(Number))
How can I exclude the last object when updating the styles of rows?
You can either stop loop at length - 1
or you can try to use CSS selectors:
var selector = '.row' + row.action_transaction_id + ':not(:last-child)';
var allRows = window.parent.document.querySelectorAll(selector);
// OR since you are using jQuery
var allRows = $(window).parent().find(selector)
// OR
var selector = '.row' + row.action_transaction_id;
var allRows = $(window).parent().find(selector).not(':last-child')

You can use Object.keys
success: function(data, status, jqXHR) {
var lastKey = Object.keys(data)[Object.keys(data).length-1];
$.each(data, function(i, row) {
if (i== lastKey) { /* It's the last key */ }
...
Note that for older browsers you may need to use the polyfill included in that link.

try this:
$.each(data, function(i, row) {
if(row["action_count"])
{
document.getElementById("hidden_counter").value = row["action_count"];
}
else
{
var allRows =window.parent.document.getElementsByClassName('row'+row.action_transaction_id+'');
for (var i = 0; i < allRows.length; i++) {
allRows[i].style.backgroundColor = '#008e00';
allRows[i].style.color = '#f0fff0';
}
}
});

first piece: get the element with greatest index (=length - 1)
second: loop all elements from index 0 until index < length-1
var lastArrayElement = allRows[allRows.length - 1];
var action_count = lastArrayElement.action_count;
// loop all but last element:
for(var i=0; i<allRows.length-1;i++){
do_something(allRows[i]); //custom function
}
assumption:
the index is correct and not resorted in the process of creating json object
the index is indeed a range from 0 to some integer, without values left out
edit
indeed the allRows.length will not work as it is an object (containing pure numeric values as properties).
Object.keys(allRows).length will give you the count van properties. However it will give you 3 as the last textual index is taken in the count as well.
var max = 0;
for(i = 0; i < Object.keys(allRows).length;i++) {
if(parseInt(Object.keys(allRows)[i]) > max) {
max = Object.keys(allRows)[i];
}
}
the last element then will be in
var lastArrayElement = allRows[max];

Related

How to get localStorage array data.

I am new to localStorage. I set array in localstorage so how can get this value. My code as below.
$scope.lineItemID = data.id;
var itemtemp={
"itemid": data.id,
"qty": $scope.quantity
};
var itemqty=JSON.parse(localStorage.getItem("itemqty")) || [];
itemqty.push(itemtemp);
localStorage.setItem("itemqty", JSON.stringify(itemqty));
So my question is how can I get itemqty.qty as per itemid from localstorage
try Below code
$.each(data.itemqty, function(index, item) {
// append data using html //use item.name
});
OR try below
$.each(data, function(idx, item){
// append data using html
//
});
You are quite simply creating an array of objects itemqty and saving it in the browser's storage. When you do this:
var itemqty=JSON.parse(localStorage.getItem("itemqty")) || [];
//itemqty is available to you as an array of objects.
Suppose you are looking for the associated quantity for some itemid stored in the variable foo. You just need to traverse the parsed itemqty like so:
$.each(itemqty, function( index, value ) {
if(value.itemid == foo)
{
console.log(value.qty);
// value.qty is the required quantity
}
});
items=JSON.parse(localStorage.getItem('itemqty'));
for (var i = 0; i < items.length; i++) {
if(items[i].itemid === itmId) {
return items[i].qty;
}
}
I am using it & it's working

Sort JSON array based on value with jQuery

I've got two dropdown select dropdowns: one for regions and one for cities in the selected region. The result is loaded by AJAX and in my response i get all cities in an JSON array:
{
1709: "Geertruidenberg",
1710: "Netersel",
1711: "Macharen",
1712: "Beers",
1713: "Hank",
1714: "Oudemolen",
1715: "Nistelrode"
}
I'm using this small plugin to load the data in the select dropdown:
(function($, window) {
$.fn.replaceOptions = function(options) {
var self, $option;
this.empty();
self = this;
$.each(options, function(index, option) {
$option = $("<option></option>")
.attr("value", index)
.text(option);
self.append($option);
});
};
})(jQuery, window);
And this piece of javascript to do the AJAX request:
$('select#Profile_regionId').change(function() {
$.post('/ajax/getcities', {regionid: $(this).val()}, function(data){
//console.log(data.cities);
$("select#Profile_cityId").replaceOptions(data.cities);
}, 'json');
});
All works totally fine, except the city dropdown is automatically sorted on the JSON array key. I tried to use the sort() method for this, but it won't work because it's an Object and not an array. Then i tried to create an array of it:
var values = [];
$.each(data.cities, function(index,value)) {
values[index] = value;
}
But for some reason, the dropdown list fills itself up from 1 to the first found id (key of array) of the city, and i don't know why it's doing that (array itself looks fine).
How can i sort the thing so my cities are ordered alphabetically in the dropdown list?
It needs to be converted to an array so that it can be sorted. Let's assume this is your object. Note that I rearranged it to be unsorted, to prove this works.
originalData = {
1712: "Beers",
1709: "Geertruidenberg",
1710: "Netersel",
1713: "Hank",
1714: "Oudemolen",
1711: "Macharen",
1715: "Nistelrode"
};
Now to create an array version we need to create an array, and insert objects into it. I'm calling the keys "year". Note that we're calling parseInt on the keys. Keys in JavaScript (except for arrays) are always strings. For example, {foo: "bar"} has a string key "foo". This also applies to numerical looking keys.
var dataArray = [];
for (year in originalData) {
var word = originalData[year];
dataArray.push({year: parseInt(year), word: word});
}
There's a chance that we have our data out of sort right now, so we manually sort it. Note that this is a case sensitive sort. For example, "Qux" comes before "foo".
dataArray.sort(function(a, b){
if (a.word < b.word) return -1;
if (b.word < a.word) return 1;
return 0;
});
The function now just pulls option.year and option.word from our array.
$.fn.replaceOptions = function(options) {
var self, $option;
this.empty();
self = this;
$.each(options, function(index, option) {
$option = $("<option></option>")
.attr("value", option.year)
.text(option.word);
self.append($option);
});
};
And then you finally use the plugin, passing the array. You can put all of this code in the plugin, if that works best for you.
$('#mylist').replaceOptions(dataArray);
fiddle
This will do what you want and take care of the empty ids/undefined values:
var data = {
1709: "Geertruidenberg",
1710: "Netersel",
1711: "Macharen",
1712: "Beers",
1713: "Hank",
1714: "Oudemolen",
1715: "Nistelrode"
};
var values = [];
$.each(data, function(index, value) {
values[index] = value;
});
values.sort();
$.each(values, function(index, value) {
if(value != undefined) {
$("#Profile_cityId").append("<option>"+ value +"</option");
}
});
Just replace the append I put in with your own function because jsFiddle was giving me trouble using that. Demo: http://jsfiddle.net/R4jBT/3/
So here is how I would do it. I assume that you are getting an AJAX response that comes like:
results: [
{year: 1709, city: "Geertruidenberg"},
{year: 1710, city: "Netersel"},
{year: ..., city: ...}
]
And, in a standard AJAX call, you would run through them like this, in a success function:
success: function(data) {
var results = data.results;
if (results.length > 0) {
for (i=0; i < results.length; i++) {
dataArrayOrig.push({
"id" : results[i].year,
"label" : results[i].city
});
}
}
},
I saw you say you do your call like this:
$.post('/ajax/getcities', {regionid: $(this).val()}, function(data){
//console.log(data.cities);
$("select#Profile_cityId").replaceOptions(data.cities);}, 'json');
You're not doing anything tests on data to see if it has results (ex. if (data.length > 0) { ... }), and you would need to push those results to an original array that stays pristine and another that can be sorted, then a final one that can get back the original year to the label, that the dropdown can then receive.
If you do it as I showed, above, you can integrate the lines I gave into the function(data){ ... } area.
Right after the push to the dataArrayOrig object, you can push to a new array you can use to sort with, using a comparison function to determine if the label (city) should come before or after the previous entry:
var results = data.results;
if (results.length > 0) {
for (i=0; i < results.length; i++) {
dataArrayOrig.push({
"id" : results[i].year,
"label" : results[i].city
});
dataArraySorting.push({
"id" : results[i].year,
"label" : results[i].city
});
dataArraySorting.sort(compare);
JSON.stringify(dataArraySorting); // sorted cities, but will be mismatched to the years
}
}
The comparison function:
function compare (a, b) {
if (a.label < b.label)
return -1;
if (b.label < a.label)
return 1;
return 0;
});
You could also do this inline:
dataArraySorting.sort(function(a, b){
if (a.label < b.label) return -1;
if (b.label < a.label) return 1;
return 0;
});
I prefer the function approach since then it can be re-used. We will see the usefulness of that in a minute.
For your arrays, declare them at the top, before your functions:
var dataArrayOrig = [];
var dataArraySorting = [];
var dataArraySorted = [];
So after that loop that goes through the results, start another one that goes through the "sorting" array and compares its label against the one in the original array we pushed to and pulls out the original ID (Year):
for (var j=0; j < dataArraySorting.length; j++) {
for (var k=0; k < dataArrayOrig.length; k++) {
if (dataArraySorting[j].label == dataArrayOrig[k].label) {
dataArraySorted.push({
"id" : dataArrayOrig[k].id,
"label" : dataArraySorting[j].label
});
console.log("Sorted ID: " + dataArrayOrig[k].id + ", Sorted label: " + dataArraySorting[j].label);
dataArraySorted.sort(compare);
JSON.stringify(dataArraySorted); // array of sorted cities, matched to year
}
}
}
You would go on to apply that dataArraySorted array to your dropdown as normal. I tested to see if I got more than 0 items from the original AJAX call, then I appended the options using id and label from the array's property names:
if (dataArraySorted.length > 0) {
$.each(dataArraySorted, function() {
$("#combobox").empty().append($("<option></option>").val(this['id']).html(this['label'));
});
}
JSFiddle with the results.

Manipulation of Javascript objects

I have an object in my javascript which looks like this:
{"data":[{"t":{
"level":"35",
"longtitude":"121.050321666667",
"latitude":"14.6215366666667",
"color":"#040098"}},
{"t":{
"level":"31",
"longtitude":"121.050316666667",
"latitude":"14.621545",
"color":"#040098"}},
{"t":{
"level":"29",
"longtitude":"121.050323333333",
"latitude":"14.62153",
"color":"#040098"}},
// .....
What I would like to do is to iterate thru the contents of my object so that I will be able to push them to their respective arrays independently.
I have an array for longitude, latitude, color and level.
So I have tried the following:
var size = 0, key;
for (key in result) {
if (result.hasOwnProperty(key)) size++;
alert(result.data[size]);
}
-->But this only alerts me "[object Object]"
success: function(result){
var size = 0, key;
for (key in result) {
for(var attr in key){
alert(attr['latitude']);
}
}
}
-->This gives me Undefined result[key]
I have checked that the size of my object is only 1 thru these codes
var size = 0, key;
for (key in result) {
if (result.hasOwnProperty(key)) size++;
}
alert(size);
I believe that only "data" is being read. And others that are inside "data" are disregarded.
I have read this, this, enter link description here, and this but they sall seem to deal with a different structure of objects. Thanks for the help in advanced.
UPDATE
Using the console.log(), I have confirmed, if im not mistaken that only the first attribute is being fetched
t
Object { level="35", longtitude="121.0508", latitude="14.6204083333333", more...}
color "#040098"
latitude "14.6204083333333"
level "35"
longtitude "121.0508"
I tried this
for (key in result) {
if (result.hasOwnProperty(key)) size++;
console.log(result.data[size]['level']);
}
--> but it says undefined
based on the structure of my object which is
data:[{"t":{'others'},'others'...]
How am I to read everything inside "data"? Each "data" has "t".
Update: Using the for...in construct for iterating over arrays isn't recommended. The alternative is a regular for loop (each method of course having their respective advantages):
for(var i=0; i<results.data.length; i++){
alert(results.data[i]['t']['latitude']);
// etc...
}
Be careful with the structure of your JSON. Also note that the javascript foreach loop iterates over keys/indices -- not values. See demo: http://jsfiddle.net/g76tN/
success: function(result){
var latitudes = [];
// and so on...
for (var idx in result.data ) {
if( result.data.hasOwnProperty(idx) ){
alert( result.data[idx]['t']['latitude'] );
// So you would do something like this:
latitudes.push ( result.data[idx]['t']['latitude'] );
// and so on...
}
}
}​
Note for collecting properties of objects in an array, jQuery $.map() -- or native js array map for that matter -- is a neat, useful alternative.
var latitudes = $.map( result.data, function(n){
return n['t']['latitude'];
});
// and so on...
Assuming result is your object, this should just be a matter of iterating over your data array:
for (var i = 0; i < result.data.length; ++i) {
console.log(result.data[i].t.latitude);
...
}
It's not hard to do, as shown below. But why would you want to take useful objects like your t's and turn them into such arrays?
var levels = [], longitudes= [], latitudes = [], colors = [];
var result = {"data":[{"t":{
"level":"35",
"longtitude":"121.050321666667",
"latitude":"14.6215366666667",
"color":"#040098"}},
{"t":{
"level":"31",
"longtitude":"121.050316666667",
"latitude":"14.621545",
"color":"#040098"}},
{"t":{
"level":"29",
"longtitude":"121.050323333333",
"latitude":"14.62153",
"color":"#040098"}}
]};
var data = result.data;
var i, len, t;
for (i = 0, len = data.length; i < len; i++) {
t = data[length].t;
levels[i] = t.level;
longitudes[i] = t.longtitude;
latitudes[i] = t.latitude;
colors[i] = t.color;
}
See http://jsfiddle.net/VGmee/, which keeps the hasOWnProperty (which is important), and your misspelling of "longitude", which is not.
var data = input.data,
result = {level: [], longtitude: [], latitude: [], color: []};
for (var i = 0, n = data.length; i < n; i += 1) {
var info = data[i].t;
for (var property in info) {
if (info.hasOwnProperty(property)) {
result[property].push(info[property]);
}
}
}
console.log(result.level);
console.log(result.latitude);
console.log(result.longtitude);
console.log(result.color);
This requires the result arrays to actually have the properties in your input array, but you can add error handling as desired.

Get Length of json Data

i have this json data and i want to get length of this json data and also of css
my json data is shown here
jso({tag:"div",css:{backgroundColor:"red"},html:"abc"})
i have pass this in function
function jso(data){
alert(data.length)
}
Your JSON is not a valid JSON object
{
"tag": "div",
"css": {
"backgroundColor":"red"
},
"html":"abc"
}
However proper JSON object don't have a length attribute, so you need to iterate over them to calculate the length.
i know what u mean u just need to loop over your object with a counter variable
var x = {tag:"div",css:{backgroundColor:"red"},html:"abc"}
function objectLength(obj){
var counter = 0;
for(var i in obj)
{
counter +=1;
}
return counter
}
use it like this
alert(objectLength(x))
To iterate over the data using jQuery counting how many iterations you did do the following:
var data = {tag:"div",css:{backgroundColor:"red"},html:"abc"};
var count = 0;
$.each(data, function(key, value) {
count++;
});
See jsFiddle here.
To iterate over the data using JavaScript only counting how many iterations you did do the following:
var data = {tag:"div",css:{backgroundColor:"red"},html:"abc"};
var count = 0;
var key;
for(key in data)
{
var value = data[key];
count++;
}
​See jsFiddle here.

Loop through JSON object List

I am returning a List<> from a webservice as a List of JSON objects. I am trying to use a for loop to iterate through the list and grab the values out of the properties. This is a sample of the returning JSON:
{"d":[{"__type":"FluentWeb.DTO.EmployeeOrder",
"EmployeeName":"Janet Leverling",
"EmployeeTitle":"Sales Representative",
"RequiredDate":"\/Date(839224800000)\/",
"OrderedProducts":null}]}
So I am trying to extract the contents using something like this:
function PrintResults(result) {
for (var i = 0; i < result.length; i++) {
alert(result.employeename);
}
How should this be done?
Be careful, d is the list.
for (var i = 0; i < result.d.length; i++) {
alert(result.d[i].employeename);
}
had same problem today, Your topic helped me so here goes solution ;)
alert(result.d[0].EmployeeTitle);
It's close! Try this:
for (var prop in result) {
if (result.hasOwnProperty(prop)) {
alert(result[prop]);
}
}
Update:
If your result is truly is an array of one object, then you might have to do this:
for (var prop in result[0]) {
if (result[0].hasOwnProperty(prop)) {
alert(result[0][prop]);
}
}
Or if you want to loop through each result in the array if there are more, try:
for (var i = 0; i < results.length; i++) {
for (var prop in result[i]) {
if (result[i].hasOwnProperty(prop)) {
alert(result[i][prop]);
}
}
}
Here it is:
success:
function(data) {
$.each(data, function(i, item){
alert("Mine is " + i + "|" + item.title + "|" + item.key);
});
}
Sample JSON text:
{"title": "camp crowhouse",
"key": "agtnZW90YWdkZXYyMXIKCxIEUG9zdBgUDA"}
Since you are using jQuery, you might as well use the each method... Also, it seems like everything is a value of the property 'd' in this JS Object [Notation].
$.each(result.d,function(i) {
// In case there are several values in the array 'd'
$.each(this,function(j) {
// Apparently doesn't work...
alert(this.EmployeeName);
// What about this?
alert(result.d[i][j]['EmployeeName']);
// Or this?
alert(result.d[i][j].EmployeeName);
});
});
That should work. if not, then maybe you can give us a longer example of the JSON.
Edit: If none of this stuff works then I'm starting to think there might be something wrong with the syntax of your JSON.
var d = $.parseJSON(result.d);
for(var i =0;i<d.length;i++){
alert(d[i].EmployeeName);
}
This will work!
$(document).ready(function ()
{
$.ajax(
{
type: 'POST',
url: "/Home/MethodName",
success: function (data) {
//data is the string that the method returns in a json format, but in string
var jsonData = JSON.parse(data); //This converts the string to json
for (var i = 0; i < jsonData.length; i++) //The json object has lenght
{
var object = jsonData[i]; //You are in the current object
$('#olListId').append('<li class="someclass>' + object.Atributte + '</li>'); //now you access the property.
}
/* JSON EXAMPLE
[{ "Atributte": "value" },
{ "Atributte": "value" },
{ "Atributte": "value" }]
*/
}
});
});
The main thing about this is using the property exactly the same as the attribute of the JSON key-value pair.
I have the following call:
$('#select_box_id').change(function() {
var action = $('#my_form').attr('action');
$.get(action,{},function(response){
$.each(response.result,function(i) {
alert("key is: " + i + ", val is: " + response.result[i]);
});
}, 'json');
});
The structure coming back from the server look like:
{"result":{"1":"waterskiing","2":"canoeing","18":"windsurfing"}}

Categories