How to get records from object without knowing keyname? - javascript

I am struggling with the following:
I have a JSON feed with my data (https://api.myjson.com/bins/1sz7s). I iterate through all ReportItems in this object through javascript / jquery.
Problem I am having is I want to fetch 'records' that contain a specific value, but without knowing the key's name. Basically some kind of if_exists(ID):
$.each(tabledata.ReportItems, function (key, val){
var ID = "value";
if (ID in ReportItems) {
alert("Found!");
};
It's easy when you know the keyname:
$.each(tabledata.ReportItems, function (key, val){
var ID = "value";
if (ID == val.keyname) {
alert("Found!");
};

I guess this is what you are asking for:
var a = {"ReportItems":[{"Id":"cf92aefb-b857-49ce-b568-722329377e5d","CampaignId":"384f5c87-f8c7-43a6-9deb-76340dcf4cd4","CompanyId":"3ae13b97-7a09-4342-8953-c1d5a55687db","Name":"Item_7699","Price":1577.0,"Enabled":true,"Start":"2015-06-03T16:55:27.1388252+02:00","End":"2015-06-08T16:55:27.1388252","PublicationId":"19031fa7-2288-4466-94d6-6909d2ed2aa1","MediaId":"91089a91-a4d3-436a-b853-9370972006f3","ItemType":1,"DateStatistics":[{"Date":"2015-06-03T16:55:27.1388252","ScanCount":1138,"ResponseCount":8530},{"Date":"2015-06-04T16:55:27.1388252","ScanCount":4429,"ResponseCount":3556},{"Date":"2015-06-05T16:55:27.1388252","ScanCount":9822,"ResponseCount":121},{"Date":"2015-06-06T16:55:27.1388252","ScanCount":3791,"ResponseCount":3569},{"Date":"2015-06-07T16:55:27.1388252","ScanCount":7275,"ResponseCount":1922},{"Date":"2015-06-08T16:55:27.1388252","ScanCount":7243,"ResponseCount":141}]},{"Id":"47de9aaa-8424-4461-ba72-ae2922777650","CampaignId":"384f5c87-f8c7-43a6-9deb-76340dcf4cd4","CompanyId":"50ede412-4eb0-429b-8d73-a1bfef41ebbc","Name":"Item_7699","Price":1577.0,"Enabled":true,"Start":"2015-06-03T16:55:27.1418263+02:00","End":"2015-06-08T16:55:27.1418263","PublicationId":"19031fa7-2288-4466-94d6-6909d2ed2aa1","MediaId":"91089a91-a4d3-436a-b853-9370972006f3","ItemType":1,"DateStatistics":[{"Date":"2015-06-03T16:55:27.1418263","ScanCount":1138,"ResponseCount":8530},{"Date":"2015-06-04T16:55:27.1418263","ScanCount":4429,"ResponseCount":3556},{"Date":"2015-06-05T16:55:27.1418263","ScanCount":9822,"ResponseCount":121},{"Date":"2015-06-06T16:55:27.1418263","ScanCount":3791,"ResponseCount":3569},{"Date":"2015-06-07T16:55:27.1418263","ScanCount":7275,"ResponseCount":1922},{"Date":"2015-06-08T16:55:27.1418263","ScanCount":7243,"ResponseCount":141}]}],"Companies":{"8df135f4-db42-486c-8d8c-fbbdd561c25e":"Phillips","47d946e3-56db-4bc7-8472-3809eb48506d":"Bauknecht","3ae13b97-7a09-4342-8953-c1d5a55687db":"Capitol","fb017214-dbc1-4b71-8080-4f9b530f4b49":"Bosch","50ede412-4eb0-429b-8d73-a1bfef41ebbc":"LG Corp"},"Campaigns":{"0950aea6-69f3-42c1-99e5-25342c6262ae":"Campagne A","384f5c87-f8c7-43a6-9deb-76340dcf4cd4":"Campagne B"},"Media":[{"Id":"5999703b-a12e-49ad-b054-46875b88ff3a","Name":"Krant","Publications":{"e63f1212-5a21-4546-861c-640007989f08":"Telegraaf","13c3caa6-fcb8-4247-9cf7-8bfe0a0b5056":"Metro","3ddb7f5d-5e28-48ba-8345-5c4e3c7f76c0":"De Volkskrant"}},{"Id":"91089a91-a4d3-436a-b853-9370972006f3","Name":"Televisie","Publications":{"2eac3fd8-b8ed-47b7-8f14-664c3c55425a":"Rtl 4","defab016-d28e-4cf4-b814-0002169cf4cb":"MTV","19031fa7-2288-4466-94d6-6909d2ed2aa1":"Discovery Channel"}},{"Id":"e8610914-52b2-4b38-bc91-bf1bd6d63035","Name":"Radio","Publications":{"3585993c-56b4-4f7d-ac9c-a325eae2e78f":"SkyRadio","15e40597-e479-4a8f-9b25-f39ba90f2c19":"Radio 538","638e1141-f21c-42f1-acd1-652d265c32a1":"Slam FM"}}]};
var result = [];
$.each(a.ReportItems[0], function(k,v){
var specificValue = "cf92aefb-b857-49ce-b568-722329377e5d";
if(v == specificValue){
result[k]=v;
}
})
console.log(result);

Since you don't already know keynames, you can iterate through val properties to match value
$.each(tabledata.ReportItems, function (key, val){
var ID = "value";
for (var keyname in val) {
if (ID == val[keyname]) {
alert("Found!");
}
}
});

Related

Split string then merge and remove duplicate value in array

I have an API and retrieve the data using jQuery.JSON. I use split to split the locations by "|". And now I'm trying to merge arrays that I've split using each in jQuery and remove the duplicates. I already tried concat. Is there a array_merge then array_filter function for javascript/jquery?
Here is my sample code below.
jQuery(document).ready(function($) {
let get_json = 'https://boards-api.greenhouse.io/v1/boards/frequence/departments/';
$.getJSON(get_json, function(data) {
let dept_arr = new Array();
let arr = new Array();
let i = 0;
$.each(data.departments, function(key, value) {
if (value.jobs.length > 0) {
$.each(value.jobs, function(key, value) {
dept_arr[i] = (value.location.name.split('|'));
i++;
});
}
});
console.log(dept_arr);
});
});
You need to loop over all the elements in the array returned by split(). And the easiest way to get rid of duplicates is with a Set.
jQuery(document).ready(function($) {
let get_json = 'https://boards-api.greenhouse.io/v1/boards/frequence/departments/';
$.getJSON(get_json, function(data) {
let dept_set = new Set();
$.each(data.departments, function(key, dept) {
$.each(dept.jobs, function(key, job) {
let locations = job.location.name.split('|');
$.each(locations, (i, loc) => dept_set.add(loc));
});
});
let dept_arr = [...dept_set]; // convert set to array
console.log(dept_arr);
});
});

How to get form data with multi select in checkboxs - javascript

I have a form that I want to get all his values, and convert them to json object.
the problem is that I not get the multiselect fields, just one field.
this is my code
what I am missing?
let reportDropDowns = $('#getReport').serialize();
reportDropDowns = decodeURI(reportDropDowns);
let reportDropDownsJson = {};
reportDropDownsJson = JSON.parse('{"' + reportDropDowns.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) });
this is my html
Instead of serializing the data directly via .serialize(), you should instead use .serializeArray() to get the data as an array. You can then manipulate the array into an object/JSON. Try this
let reportDropDownsJson = {};
$('#getReport').serializeArray().forEach(({name, value}) => {
if( reportDropDownsJson.hasOwnProperty(name) ){
if( !Array.isArray(reportDropDownsJson[name]) ){
reportDropDownsJson[name] = [reportDropDownsJson[name]];
}
reportDropDownsJson[name].push(value);
}else{
reportDropDownsJson[name] = value;
}
});

Jquery - get the name of an array item in an array

How do you reference the name of an array within an array?
var jon_count = [0,6,7,9]
var sue_count = [9,7,6,8]
var rob_count = [7,8,6,3]
var name_list = {jon_count, sue_count, rob_count}
I'm trying to get the name of each variable within the "name_list" not the values of each item.
$.each(name_list, function (index, value) {
$.each(value, function(ind, obj) {
console.log(value[ind]);
});
});
I know that's garbage, I want to see:
jon_countsue_countrob_count
But I keep getting the numbers.
You can just use the index variable:
$.each(name_list, function (index, value) {
alert(index);
});
Here is a fiddle.
i think you need this:
var name_list = {jon_count:"item 1", sue_count:"item 2", rob_count:"item 3"}
var keys = Object.keys(name_list)
keys.forEach((item) => {
console.log(item)
})

FInd object in array by value and update entire object

I have a list of objects and sometimes I receive an update from the API for one of those objects and what I need to do is to find the object with the id of the one to update and update the entire object...
I was trying to avoid a for loop because the list could be very very long.
So what I was trying to use is $.grep but it doesn't seem to work as expected.
Here is what I tried so far:
// item is the response data from the API
var item = res.item;
var index = $.grep(arrayOfItems, function (e, i) {
if (e.id === item.id) {
return i;
}
});
arrayOfItems[index] = item;
the item is not updated unfortunately...
If it's speed you're after, especially with a long list, you may consider indexing your list by id when you first retrieve it, making updates later quicker than having to loop the entire array to find an index.
To demonstrate, assume you have retrieved an array of objects
var data = [
{id:1,data:'hello'},
{id:2,data:'world'},
{id:3,data:'foo'},
{id:4,data:'bar'}];
now create an object which represents your data where the property is the Id (object properties cannot start with a number, so if id is numeric, prefix it) and the value is the index back into the original array. So, the above data would be transformed to
var dataIndex = {
id1:0,
id2:1,
id3:2,
id4:3
};
This can be done trivially with a function
function indexDataById(data)
{
var index = {};
$.each(data, function(e,i){
index['id' + e.id] = i;
});
return index;
}
var dataIndex = indexDataById(data);
Now, when it comes to your update, you can find the index instantly using the id
var updateId = 2;
var elementIdx = dataIndex ['id' + updateId];
data[elementIdx] = myNewData;
The one complication is that you need to go back and update the index if the id of the new data has changed:
var updateId = 2;
var elementIdx = dataIndex [`id` + updateId];
data[elementIdx] = myNewData;
delete dataIndex[elementIdx]
dataIndex['id' + myNewData.id] = elementIdx;
This should be easy enough to handle atomically with your update.
$.map and $.grep return both an array so you will never get the index.
Inside $.map or $.grep function you need to return true or false based
on your filter logic. They re not useful in your case.
if your structure is not ordered you can only loop trough it and stop the loop when you find your element... like that:
var item = res.item;
var index = "";
$.each(arrayOfItems, function(i,v){
if(item.id == v.id){
index = i;
return true;
}
});
arrayOfItems[index] = item;
if you wanna order your structure before loop use this:
arrayOfItems.sort(function(a, b) {
return a.id > b.id;
});
i ve made a fiddle with an example https://jsfiddle.net/L08rk0u3/
try this way using $.grep
var arrList = [
{name :11,id :11},{name :12,id :12},{name :111,id :111},
{name :13,id :13},{name :15,id :15},{name :11,id :11},
{name :41,id :41},{name :31,id :31},{name :81,id :81},
{name :91,id :91},{name :13,id :13},{name :17,id :17},
{name :1111,id :1111}
]
console.log(arrList);
var respItem ={name :1111000,id:1111};
var intSearchedIndex;
$.grep(arrList,function(oneItem,index){
if(respItem.id==oneItem.id){
return intSearchedIndex = index;
}
})
arrList[intSearchedIndex] =respItem;
console.log(intSearchedIndex,arrList);
Try with map method like this.
Code snippets:
// item is the response data from the API
var item = res.item;
var index = $.map(arrayOfItems, function (e, i) {
if (e.id === item.id) {
return i;
}
});
if(index.length)
arrayOfItems[index[0]] = item;
Update:
arrayOfItems[index] = item;
This will work if index array has an single element. See fiddle
But,
arrayOfItems[index[0]] = item;
This is the appropriate way since it is an array.

what is the right way to set input fields and labels from the properties of the same object in jquery?

I have an object with a bunch of properties. Some properties are to be displayed in input elements, some in labels.
So, my code looks like this:
var data = getMyData();
var propNames = Object.keys(data);
var i, propName, elem;
for (i = 0; i < propNames.length; ++i) {
propName = propNames[i];
elem = $("#" + propName);
if (elem.is('input')) {
elem.val(data[propName]);
} else {
elem.html(data[propName]);
}
}
Is it the right way to do it in jquery? Cause it looks kinda ugly...
Thanks.
I find it easier to store the method name in a variable (text/val), so that we don't have so much code repetition (the conditional in your code makes for unnecessary repetition).
Also, since you're anyhow using jQuery, you might as well use each. It simplifies all of it into this:
$.each(getMyData(), function (key, val)
{
var el = $("#" + key),
method = el.is('input') ? 'val' : 'text';
el[method](val);
});
Here's the fiddle: http://jsfiddle.net/pFbSf/
If you don't like storing the method name in a variable, use this instead:
$.each(getMyData(), function (key, val)
{
var el = $("#" + key);
el.is('input') ? el.val(val) : el.text(val);
});
Here's the fiddle: http://jsfiddle.net/GQTZv/
If you worry about jQuery not using hasOwnProperty, you can run the check yourself:
var data = getMyData();
$.each(data, function (key, val)
{
if ( ! data.hasOwnProperty(key) ) return;
var el = $("#" + key);
el.is('input') ? el.val(val) : el.text(val);
});
Here's the fiddle: http://jsfiddle.net/GQTZv/1/
I think you can rewrite that for-loop with the jQuery .each() function, which can iterate over any array or object. It takes a callback function, which is given the index (or key) and the value of each item.
In your example it would be something like:
jQuery.each(data, function(key, value) {
elem = jQuery("#" + value);
if (elem.is('input')) {...
Check out the docs for jQuery.each()
Assuming you're trying to fill either an input or a textarea, you should be able to replace this with:
var data = getMyData();
var propNames = Object.keys(data);
for (i = 0; i < propNames.length; ++i) {
$("input#"+propNames[i]).val(data[propNames[i]);
$("textarea#"+propNames[i]).html(data[propNames[i]);
}
You might even get away with replacing the two jQuery selectors with:
$("input#"+propNames[i]).val(data[propNames[i]).html(data[propNames[i]);
Since input elements don't have innerHTML and textarea elements don't have val, this should work as-is. Hackish, but it's succinct.
I don't see how that looks ugly but I don't understand why you need Object.keys... You can simplify it a bit with a regular for...in:
var data = getMyData(),
d, $el;
for (d in data) {
$el = $('#'+ d);
if ($el.is('input')) {
$el.val(data[d]);
} else {
$el.html(data[d]);
}
}
Everything looks fine to me Mark. The one thing I would highly advise against is using a new Object prototype method like Object.keys, which is only available in IE9+ and other newer browsers. Instead either create the prototype for it before all of your JS (something I actually don't like doing) or instead have a replica work-around global function / namespace method that takes care of it like function getkeys() at the bottom.
http://jsfiddle.net/WJ24q/1/
for (i = 0; i < propNames.length; ++i) {
var el = $("#" + propNames[i]),
_d = data[propNames[i]];
// you could also use a simple ternary instead of the if/else
el.is('input') ? el.val(_d) : el.html(_d);
}
Function instead of Object.keys:
function getKeys (obj){
var keys = [];
for(var key in obj){
keys.push(key);
}
return keys;
}
​ ​

Categories

Resources