I have a JSON Object, that i need to loop through and delete some elements. However after I delete an element I end up with an undefined element instead, this is causing me issues, as I am unable to use this "new JSON" (I am trying to use it within datatables)
the following is what I am currently doing
function dTable(presId){
var allregos = '[{"presId": "a09N0000004UbBnIAK","name": "Something","id": "001N000000Mw7knIAB"},{"presId": "a09N0000004UbBnIAK","name": "test catty","id": "001N000000O98IoIAJ"},{"presId": "a09N0000004UbBnIAK","name": "Something","id": "001N000000Mw7knIAB"}]';
var newJson;
var regoValue;
for (var ke in allregos) {
if (allregos.hasOwnProperty(ke)) {
regoValue = allregos[ke].presId;
if(regoValue != presId){
delete allregos[ke];
}else{
//INstead of delete I could maybe create a new JSON by adding the whole node?
//but I am unable to add the node
//newJson = newJson.allregos[ke];
}
}
}
console.log(allregos);
console.log(newJson);
j$('#myRegos').dataTable( {
"data": newJson,
"destroy": true,
"columns": [
{ "title":"Name", "mData": "name", "class": "center" },
]
} );
}
my console log shows me something like:
[undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, Object { presId="a09N0000004W3YLIA0", name="name 1", id="001N000000Mw7knIAB"}, Object { presId="a09N0000004W3YLIA0", name="Call Centre", id="001N000000MvDaMIAV"}, Object { presId="a09N0000004W3YLIA0", name="Who Is", id="001N000000MvIiaIAF"}]
is there a way to get rid of the undefiend elements?
The other work around that I was thinking was instead of deleting the elements add the appropiate ones into a new JSON however I am not able to do this. I was trying something like:
newJson = newJson.allregos[ke];
Here we have allRegos as an array of objects so a better way to use it is to take advantage of the standard for without using for (var ke in allregos) and then
if (allregos.hasOwnProperty(ke))
and also i'm converting the json string to a real json data by calling JSON.parse(allregos)
below is the enhanced dTable function
note also that i added another object with presId='a09N0000004UbBnIAz' just to see if we are getting the right answer when we call the dTable('a09N0000004UbBnIAK');
function dTable(presId){
allregos = '[{"presId": "a09N0000004UbBnIAK","name": "Something","id": "001N000000Mw7knIAB"}, {"presId": "a09N0000004UbBnIAK","name": "test catty","id": "001N000000O98IoIAJ"}, {"presId": "a09N0000004UbBnIAK","name": "Something","id": "001N000000Mw7knIAB"},{"presId": "a09N0000004UbBnIAz","name": "Something","id": "001N000000Mw7knIAB"}]';
oldJson = allregos;
var regoValue;
allregos = JSON.parse(allregos);
oldJson = JSON.parse(oldJson);
newJson = [];
for( i=0;i<allregos.length;i++){
regoValue = allregos[i].presId;
if(regoValue != presId){
delete allregos[i];
}else{
newJson.push(allregos[i]);
}
}
console.log('allregos before:');
console.log(oldJson);
console.log('allregos after:')
console.log(allregos);
console.log('newJson after:')
console.log(newJson);
}
You can get rid of the elements by completely overwriting the object.
Say you have
var myObject = {
"keyFoo" : "valueFoo",
"keyBar" : "valueBar",
"keyBaz" : undefined
};
in order to find out which values are not undefined, you can gothrough your object, and only set values which return true. In this scenario, you can isolate "keyBaz", because
(x.keyBaz) returns false when coerced into a boolean context, whereas
(x.keyFoo) and (x.KeyBar) both return true when coerced into a boolean context. You can do also do this within an array.
You can then overwrite the object by doing:
myObject = {
"keyFoo" : "valueFoo",
"keyBar" : "valueBar"
};
Related
I'm trying to append results in an object as options in a datalist dropdown, and it works but the problem is not all elements have a certain level in the object always which affects what results get appended to the list.
$("#returnedProducts").append($("<option/>",
{
"srindex": i,
"data-details": JSON.stringify(result[i]._source.name.family),
//I want to say if result[i]._source.fabric exists, then do this next line else, just move to "value"
"data-fabric":JSON.stringify(result[i]._source.fabric[1]),
"value": result[i]._source.category,
"html": result[i]._source.category,
}
));
How can I make this say "Only set data-fabric if result[i]._source.fabric exists,else don't set it and move to "value"?
Use a ternary operator:
{
"srindex": i,
"data-details": JSON.stringify(result[i]._source.name.family),
"data-fabric": result[i]._source.fabric ? JSON.stringify(result[i]._source.fabric[1]) : undefined,
"value": result[i]._source.category,
"html": result[i]._source.category,
}
Let me know if this needs more clarification
You really can't do something like that inside an object initializer, but you can easily do it if you assemble your options object in a function:
$("#returnedProducts").append($("<option/>", function() {
var object = {
"srindex": i,
"data-details": JSON.stringify(result[i]._source.name.family),
"value": result[i]._source.category,
"html": result[i]._source.category,
};
if (result[i]._source.fabric) {
object["data-fabric"] = JSON.stringify(result[i]._source.fabric[1]);
}
return object;
)() ); // note that the function is called here
I am trying to wrap my head around how I might accomplish something like this, structurally:
var keywordDataProducts =
[
{"keyword" : "keyword1", "list" : [ "DP1", "DP2" ] },
{"keyword" : "keyword2", "list" : [ "DP1" ] }
];
But of course, without the values being hard coded. For instance, we currently loop through all the DP values (DP1, DP2, DP3, etc..) - which all have 0-M keywords. I'm trying to create an inverse lookup of that, where you can get all DPs that use a particular keyword. I have code that uses the structure above perfectly, but I just need the data to get populated more dynamically.
Do I initialize the var keywordDataProducts = []; declaration with anything in it, or define the structure of it having a keyword and a list (which is an array)? Or do you leave it as an array with nothing about it, and define that when you're adding items?
I've heard associative arrays can be used for a situation like this, but I'm not quite wrapping my head around that at the moment. I've also seen objects with {} usages, but there is no push there and I need an array of keywords, which also contains arrays of DPs (list). Thoughts?
You would do something like this, but you didn't clearly describe what the input look like and what output you're looking for.
function fn (input) {
var ouput = {};
input.forEach( function (DP) {
for (prop in DP) {
if (DP.hasOwnProperty(prop) {
if (output[prop]) {
output[prop].push(DP);
} else {
output[prop] = [DP];
}
}
}
});
return output;
}
This takes this kind of input
[{"alpha":...}, {"beta":..., "delta":...}, {"alpha":..., "gamma":...}]
and returns
{"alpha":[{"alpha":...}, {"alpha":..., "gamma":...}]}, "beta":{"beta":..., "delta":...}, "delta":{"beta":..., "delta":...}, "gamma":{"alpha":..., "gamma":...}}
I don't know how you want your output so I just made an object with each keyword as its own key for the DP values.
var data = [{dp: "dp1", keys: ["key1", "key2", "key3"]}, {dp: "dp2", keys: ["key1", "key2", "key3"]}, {dp: "dp3", keys: ["key1", "key2", "key3"]},];
function keyWordArray(arr) {
var newObj = {};
arr.forEach((obj) => {
obj.keys.forEach((keyVal) => {
if(newObj.hasOwnProperty(keyVal)){
newObj[keyVal].dp.push(obj.dp);
} else {
newObj[keyVal] = {dp:[obj.dp],};
}
});
});
return newObj;
}
document.getElementById("data").innerHTML = JSON.stringify(keyWordArray(data));
<div id="data">
</div>
You can treat objects as associative arrays, and you don't have to use "push" to add a new element.
// Create your object like this
var keywordDataProducts =
{
"keyword1" : { "list" : [ "DP1", "DP2"] },
"keyword2" : { "list" : [ "DP1" ] }
};
// Treat it like an associative array
var keyword1 = keywordDataProducts["keyword1"];
alert("keyword1 = " + keyword1.list.join(", "));
// Add to it like this
keywordDataProducts["keyword3"] = { "list" : ["DP3", "DP4"] };
// See the new object includes your new keyword
alert(JSON.stringify(keywordDataProducts));
// To iterate the keys of your object, you can do something like this
for(var item in keywordDataProducts)
{
if(keywordDataProducts.hasOwnProperty(item))
{
alert(item);
}
}
You can see the fiddle here;
https://jsfiddle.net/gksjtwr6/2/
I am creating objects when textbox having some values (using ng-blur and textbox.value!==undefined) and then putting these objects in an array (all working fine here).
When I click on checkbox (checkbox model bind with textbox ng-required) I need to delete that particular object having that textbox value.
I am using:
arr.splice(index,1);
to remove that particular object from array (by matching it's name like "monthly" or "quarterly" etc.), but it is creating null at that particular position.
for e.g. [object,object,object]
[
{name:"monthly",
amount:1000 },
{name:"quarterly",
amount:1200 },
{name:"yearly",
amount:1300 }
]
after removing all element it shows [] and when I add another new object it displays [3:object] and it's content as [null,null,null,object];
or
if I remove middle object say name:"quarterly", it shows [object,object] but after adding a new object it display array as [object,object,null,object] with length of array as 4.
Why is there null and how can I remove that from array. (don't want to iterate again to check null).
It is difficult to say why your code creates the null values without have a look to it.
But I can say you that it is not the expected behaviour.
You can see this example to get some inspiration:
var data = [
{name:"monthly",
amount:1000 },
{name:"quarterly",
amount:1200 },
{name:"yearly",
amount:1300 }
];
var newObjectToBeAdded = { name: "daily", amount:"100" }
function showObjects()
{
document.body.innerHTML += data + '<hr>';
}
function deleteObjectByName( objectName )
{
for( var i = 0; i < data.length; i++ )
{
if( data[ i ].name == objectName )
{
data.splice(i, 1);
}
}
}
function addObjectToData( newObject )
{
data.push( newObject );
}
showObjects();
deleteObjectByName( "quarterly" );
showObjects();
addObjectToData( newObjectToBeAdded );
showObjects();
Just to throw a guess out, maybe you are accidentally duplicating the array. Maybe in some point of your code you are doing something like this:
var new_array = original_array.splice( index );
Or creating the new array in the loop you use to find the target object, or using some kind of intermediate array, etc.
Hope it helps!
var arrayWithoutNulls = myArray.filter(function(val) {
if (val) {
return val;
}
});
Can I add Jquery Object to the blank object as key. For example:-
var obj = {};//blank object
var myId = $("#myId");//jQuery Object
var myId2 = $("#myId2");//another jQuery Object
obj[myId] = "Trying to add myId as a key";
obj[myId2] = "Trying to add myId2 as a key";
But the output of the obj contains only one key. Is the above thing is possible in JS or not?
Thanks in advance.
You have to use a string as property name (e.g. the id of the jquery object?).
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
If you want to keep the reference to object you can use an array of objects instead of an object:
[
{
"jQueryElement": myId1,
"note": "Trying to add myId as a key"
},
{
"jQueryElement": myId2,
"note": "Trying to add myId2 as a key"
}
]
Then you will be able to do:
function getNoteOfJqueryObj(element) {
element = $(element);
for (var i in array) {
if (array[i].jQueryElement[0] == element[0]) {
return array[i].note;
}
}
return undefined;
}
I guess that this is one of the best ways you can choose.
JSFIDDLE
I'm clueless. I have a JSON string like this which I need to check for a supplied "property" (postsome in the following example):
var index_file =
[{
"indexAB":[
{ "postsome": ["keyword_abc", "keyword_def"] },
{ "testsome": ["keyword_111", "keyword_222"] }
]
},{
"index_random": [
{ "postsome": ["keyword_abc"] }
]
}]
There my be any number of indices ("indexAB", "index_random") with n objects inside.
I need to "find" my property postsome but I cannot get it to work, because I'm struggling with the correct way of accessing the object.
So:
for (var i = 0, l = indices.length; i < l; i += 1) {
doc._id = "postsome",
index_name = "indexAB";
indices[i]["indexAB"]; // ok, returns object on correct iteration
indices[i][index_name]; // undefined
indices[i].indexAB[0][doc._id] // ok, returns undefined or keywords
indices[i][index_name][0][doc._id] // undefined
}
Question:
How can I access a nested object in loop using a variable name index_name?
This is not a direct answer to your question but I believe that it may actually help you more than giving you a complicated way to access values in your object.
If instead of this JSON object:
var index_file =
[{
"indexAB":[
{ "postsome": ["keyword_abc", "keyword_def"] },
{ "testsome": ["keyword_111", "keyword_222"] }
]
},{
"index_random": [
{ "postsome": ["keyword_abc"] }
]
}];
you would have this much simpler data structure:
var index_file =
{
"indexAB": {
"postsome": ["keyword_abc", "keyword_def"],
"testsome": ["keyword_111", "keyword_222"]
},
"index_random": {
"postsome": ["keyword_abc"]
}
};
then it would be much easier to access, using just:
var value = index_file.indexAB.postsome[0]; // no loops, no nothing
// value == "keyword_abc"
See: DEMO
I think that what you should change is your data model because currently it is something that is very far from the idea of JSON and it will always be very hard do access data in it.
A couple of issues
"indexAB" only exists on the first element in the array
you cannot have dots inside variable names.
I suggest you test whether indexAB is a property of the object before deferencing it further. See example below:
Fixed
var indices = index_file;
for (var i = 0, l = indices.length; i < l; i++) {
var doc_id = "postsome";
var index_name = "indexAB";
indices[i]["indexAB"]; // ok, returns object on correct iteration
indices[i][index_name]; // undefined
if ("indexAB" in indices[i]) {
indices[i].indexAB[0][doc_id] // ok, returns undefined or keywords
indices[i][index_name][0][doc_id] // undefined
}
}
index_name is undefined because the line prior to that raises an error
doc._id = "postname" // this causes an error
Just use a simple string
doc = "postname"