Im using the following code,
jQuery.each(aDataSel, function(index, oData) {
oPushedObject = {};
aSelectedDataSet.push(fnCreateEnt(aProp, oData, oPushedObject));
});
This is aSelectedDataSet values
and this is the values of OData
What I need is that before I do the push is to fill the listTypeGroup & listTypeGroupDescription (with the red arrow ) with values that Are inside the oData -> ListTypeGroupAssigment -> result (listTypeGroup & listTypeGroupDescription) , The index is relevant since I want to add just the value of the index in each iteration (since this code is called inside outer loop and the index determine the current step of the loop) ,How it can be done nicely?
The result contain 100 entries (always) and the a selected data will have 100 entries at the end...
Update :)
Just to be clear In the pic I show the values which is hardcoded for this run but the values can be any values, we just need to find the match between the both objects values...
I mean to find a match between to_ListTypeGroupAssigment in both object (which in this case exist ) and if in oData there is result bigger then one entry start with the matching ...
UPDATE2 - when I try Dave code the following happen for each entry,
This happen in the Jquery.extend line...any idea how to overcome this?
The following hard-coded of Dave:-) work perfect but I need generic code which doesnt refer to specific field name
jQuery.each(aDataSet, function(index, oData) {
oPushedObject = {};
fnCreatePushedEntry(aProperties, oData, oPushedObject);
var result = oData.to_ListTypeGroupAssignment.results[index];
oPushedObject.to_ListTypeGroupAssignment = {
ListTypeGroup: result.ListTypeGroup,
ListTypeGroupDescription: result.ListTypeGroupDescription
};
aSelectedDataSet.push(oPushedObject);
});
Im stuck :(any idea how to proceed here ?what can be wrong with the extend ?
should I use something else ? Im new to jQuery...:)
I think that this happen(in Dave answer) because the oData[key] is contain the results and not the specified key (the keyValue = to_ListTypeGroupAssignment ) which is correct but we need the value inside the object result per index...
var needValuesForMatch = {
ListTypeGroup: 'undefined',
ListTypeGroupDescription: 'undefined',
}
//Just to show that oPushedObject can contain additional values just for simulation
var temp = {
test: 1
};
//------------------This object to_ListTypeGroupAssigment should be filled (in generic way :) ------
var oPushedObject = {
temp: temp,
to_ListTypeGroupAssignment: needValuesForMatch
};
oPushedObject is one instance in aSelectedDataSet
and after the matching I need to do the follwing:
aSelectedDataSet.push(oPushedObject);
Is this what you're after:
OPTION ONE - DEEP CLONE FROM oData TO aSelectedDataSet
aSelectedDataSet.forEach(function(currentObject,index){
for (var childObject in currentObject) {
if (! currentObject.hasOwnProperty(childObject))
continue;
var objectToClone = oData[childObject]['results'][index];
if(objectToClone)
$.extend(true,currentObject[childObject],objectToClone);
}
});
Here is your data in a fiddle with the function applied: https://jsfiddle.net/hyz0s5fe/
OPTION TWO - DEEP CLONE FROM oData ONLY WHERE PROPERTY EXISTS IN aSelectedDataSet
aSelectedDataSet.forEach(function(currentObject,index){
for (var childObject in currentObject) {
if (! currentObject.hasOwnProperty(childObject))
continue;
if(typeof currentObject[childObject] !== 'object')
continue;
for(var grandChildObject in currentObject[childObject]) {
var objectToClone = oData[childObject]['results'][index][grandChildObject];
if(typeof objectToClone === 'object') {
$.extend(true,currentObject[childObject][grandChildObject],objectToClone);
} else {
currentObject[childObject][grandChildObject] = objectToClone;
}
}
}
Fiddle for option 2: https://jsfiddle.net/4rh6tt25/
If I am understanding you correctly this should just be a small change:
jQuery.each(aDataSel, function(index, oData) {
oPushedObject = {};
fnCreateEnt(aProp, oData, oPushObj);
//get all the properties of oData and clone into matching properties of oPushObj
Object.getOwnPropertyNames(oData).forEach(function(key) {
if (oPushObj.hasOwnProperty(key)) {
//oPushObj has a matching property, start creating destination object
oPushObj[key] = {};
var source = oData[key];
var destination = oPushObj[key];
//can safely assume we are copying an object. iterate through source properties
Object.getOwnPropertyNames(source).forEach(function(sourceKey) {
var sourceItem = source[sourceKey];
//handle property differently for arrays
if (Array.isArray(sourceItem)) {
//just copy the array item from the appropriate index
destination[sourceKey] = sourceItem.slice(index, index + 1);
} else {
//use jQuery to make a full clone of sourceItem
destination[sourceKey] = $.extend(true, {}, sourceItem);
}
});
}
});
aSelectedDataSet.push(oPushedObject);
});
It is unclear what exactly your fnCreateEnt() function returns though. I am assuming it is the populated oPushObj but it's not entirely clear from your question.
Related
I have a main object consisting of two main properties, data which contains messages and included which contains the senders of the messages. I want to create a new Array called messages which will contain all the values of both objects but in a way that every object inside this array will consist of the data values adding the correct sender as property to each of them.
I am able to separate the main object to two different ones, one containing the data and the other containing the senders.
if (jsonAPI.data) {
$.each(jsonAPI.data, function(index, value) {
dataObj[index] = value;
});
}
if (jsonAPI.included) {
$.each(jsonAPI.included, function(index, value) {
senders[value.id] = value;
});
}
I guess I have to make an iteration for every value of the dataObj and check if the relationships.sender.data.id is equal to senders.id then add the new property to dataObj, but I don't know how to write it.
What I say can be more clear in this fiddle https://jsfiddle.net/mosmic/f2dzduse/
Working jsfiddle: https://jsfiddle.net/f2dzduse/5/
var jsonAPI = {<snip>};
var dataObj = {};
if (jsonAPI.data) {
$.each(jsonAPI.data, function(index, value) {
dataObj[index] = value;
});
}
$.each(dataObj, function(index, value) {
//Prevent error if there is no sender data in included
if(jsonAPI.included.length - 1 >= index) {
//check if ids are equal
if(value.relationships.sender.data.id == jsonAPI.included[index].id) {
value.sender = jsonAPI.included[index];
}
}
});
console.log(dataObj);
This code assumes that jsonAPI.data.relationships.sender.data.id and jsonAPI.included.id are both in the same order!
If this is not always the case let me know and I'll rewrite the code to loop trough each jsonAPI.data and then loop trough jsonAPI.include to check for an equal id. This code will be slower since it will loop a total of jsonAPI.data.length X jsonAPI.include times.
Here's the updated code: https://jsfiddle.net/f2dzduse/6/
var jsonAPI = {<snip>};
var dataObj = [];
$.each(jsonAPI.data, function(x, data) {
dataObj[x] = data;
$.each(jsonAPI.included, function(y, included) {
if(data.relationships.sender.data.id == included.id) {
dataObj[x].sender = included;
}
});
});
console.log(dataObj);
I program a function that give me all values of some input checkboxes and include them into an array.
Function:
$('#area_tbl .checkbox').each(function(){
/*for(var i = 0; i < test.length; i++){
if(test[i].PLZ === $(this).find('.area-checkbox').val()){
alert('Gleich');
}else{
alert('nicht gleich');
}
}*/
test.push({PLZ:$(this).find('.area-checkbox').val()});
});
My array looks like this:
[Object { PLZ="42799"}]
That's fine!
Now I include automatically more checkboxes with more values. After that my function is refreshing and I include the 'new' values.
Now my problem is that my array looks like this:
[Object { PLZ="42799"}, Object { PLZ="42799"}, Object { PLZ="51399"}]
You can see PLZ='42799' is twice.
I want to find the duplicate values and delete them from my array. I try it with the if clause in my function. But nothing works for me.
Assuming that value of each checkbox is unique, you need to reset the test value before running this each iterator
test = [];
$('#area_tbl .checkbox').each(function(){
test.push({PLZ:$(this).find('.area-checkbox').val()});
});
You could use a memory
// The memory will be a simple list with the already added elements. Firstly empty
memory = []
// we loop over ther checboxes
$('#area_tbl .checkbox').each(function(){
// we store the value
var v = $(this).find('.area-checkbox').val();
// If memory doesn't content the value... (its position is -1)
if(memory.indexOf(v) == -1){
// we store the object and we update the memory
test.push({PLZ:v});
memory.push(v);
}
});
You could use a temporary object and look up with accessing the property:
var object= {};
$('#area_tbl .checkbox').each(function() {
var v = $(this).find('.area-checkbox').val();
if (!object[v]) {
test.push({PLZ: v});
object[v] = true;
}
});
I'm parsing a fairly large JSON file and doing some key:value pairs within an object. Issue I'm having is if I find a key I need to actually add another object to it INSTEAD of writing over it.
Example:
var collection = {};
angular.forEach(things, function(thing) {
collection[thing.Id] = thing.stuff;
//thing.stuff is an object
});
Came to a conclusion after some of the comments I've received in the first post:
var collection = {};
angular.forEach(things, function(thing) {
if(collection[thing.Id]){
//Key Exists push into array
collection[thing.Id].push(thing.stuff);
}else{
//Key doesn't exist create array for object
collection[thing.Id] = [thing.stuff];
}
});
In Modern way: maybe someone will come in handy
var collection = {};
angular.forEach(things, function(thing) {
if(!collection[thing.Id]){
collection[thing.Id] = [];
}
collection[thing.Id] = [...collection[thing.Id], thing.stuff];
// or ----------------------------------------------------
// add item at start
// collection[thing.Id] = [thing.stuff, ...collection[thing.Id]];
// or ---------------------------------------------
// if you doesn't want to change referrance every time
// collection[thing.Id].push(thing.stuff);
});
I have a data with certain rule. I want to create a json object to manage the rule. There is problem to create a json object as my need. Here my array data.
$scope.data = ["Crust^Pan^Medium=NA", "Crust^Pan^Large=NA", "Crust^Thin Crust^Medium=10.50"]
I want a output like this:
{
"Pan": {
"Medium": NaN,
"Large": NaN,
},
"Thin Crust": {
"Medium": 10.50
}
}
Here my code,
$scope.crustRule = {};
for(var i=0; i<$scope.data.length; i++) {
var tempCrust = {};
var trimOne = $scope.data[i].split('^');
var trimTwo = trimOne[2].split('=');
if(trimOne[0] == 'Crust') {
tempCrust[trimTwo[0]]=parseFloat(trimTwo[1]);
$scope.crustRule[trimOne[1]].push(tempCrust);
}
}
console.log($scope.crustRule);
You first need to create an object $scope.crustRule[trimOne[1]] before you can push objects into it. Something like
$scope.crustRule[trimOne[1]] = {};
$scope.crustRule[trimOne[1]].push(tempCrust);
the push function has to exist. you can grab it from the Array property if you want.
only do this if it has to be in an object structure
var x = {length:0,push:Array.prototype.push};
x.push("jump");
console.log(x);//Object {0: "jump", length: 1}
I go over the mininmum requirement for some array functions to work on an object:
Mimic the structure of a javascript array object
EDIT:
I noticed your reuirements are need an object without a length and string index based instead of number index based. going to test something
darn I was hoping something wild was already there and tried
var x = {};
x += {"BadGuy": "Joker"};
console.log(x)//[object Object][object Object] //:(
so I made my own push function
var x = {push:ObjPush};
x.push("jump");//Object cannot add (string) yet Coming soon
y = {"BadGuy": "Joker"};
x.push(y);
console.log(x);//{"BadGuy": "Joker"};
function ObjPush(obj)
{
if ((typeof obj).toLowerCase() == "object")
{
for (var i in obj)
{
this[i] = obj[i];
}
}
else
{
console.log("Object cannot add (" + typeof obj + ") yet\n Coming soon");
}
}
Note:
I haven't added any handling to check for same properties. so any properties with the same name will override original properties.
EDIT:
I integrated my code with yours and got a strange output unfortunately.
for some reason instead of adding medium and large as properties to the inner objects it only adds the last 1 for example i get the output
{"Pan":{"Large":null},"Thin Crust":{"Medium":10.5}}
EDIT:
OK I found where my issue was. I get the expected output now. added a check to make sure that $scope.crustRule[trimOne[1]] is only initialized if it doesnt exist yet.
if(typeof $scope.crustRule[trimOne[1]] == "undefined")
$scope.crustRule[trimOne[1]] = {push:ObjPush};
In my Notes Database, I perform an audit when the document is saved. Pretty easy in LotusScript. I grab the original document (oDoc) from the server, then in the document I modified (mDoc), I do a Forall loop that gets the names of each item; forall item in mDoc.items. Grab the same item from oDoc, execute a function with the new item as an argument that will run down a case statement that will see if its a field we care about. if so, I update a set of list values in the document with "When", "Who", "What field", and the "New Value".
I'm doing this in a server side script. In trying this, I discovered a couple of interesting things;
currentDocument is the NotesXSPDocument that contains everything that was just changed.
currentDocument.getDocument() contains the pre-change values. It also returns a NotesDocument which has the "items" field that I can run through.
Thing is, I need something similar in the NotesXSPDocument. Is there a way in an iterative loop to grab the names and values of all items from there?
Here's the broken code. (Currently it's walking through the NotesDocument items, but those are the old values. I'd rather walk down the XSP document items)
function FInvoice_beginAudit() {
var original_doc:NotesDocument = currentDocument.getDocument();
var oItem:NotesItem;
var oItems:java.util.Vector = original_doc.getItems();
var iterator = oItems.iterator();
while (iterator.hasNext()) {
var oItem:NotesItem = iterator.next();
item = currentDocument.getItemValue(oItem.getName());
if (oItem == undefined) {
var MasterItem = ScreenAudit(doc,item,True)
if (MasterItem) { return true }
} else {
if (item.getValueString() != oItem.getValueString()) {
var MasterItem = ScreenAudit(doc,Item,True);
if (MasterItem) { return true }
}
}
}
}
You can get both versions of a document after submit - the original and the one with changed/new values:
original: var original_doc:NotesDocument = currentDocument.getDocument();
changed: var changed_doc:NotesDocument = currentDocument.getDocument(true);
This way you can compare the items for changes.
But, there is a pitfall: after assigning "changed_doc" to currentDocument.getDocument(true) the "original_doc" has the changed values too because both variables point to the same document. That's why we have to copy all items from currentDocument.getDocument() to a new temporary document first and only after get the changed values with currentDocument.getDocument(true). As an alternative you could read the original document from server like you do in LotusScript.
This is a code for detecting changed items as a starting point:
var original_doc:NotesDocument = database.createDocument();
currentDocument.getDocument().copyAllItems(original_doc, true);
var changed_doc:NotesDocument = currentDocument.getDocument(true);
var oItems:java.util.Vector = original_doc.getItems();
var iterator = oItems.iterator();
while (iterator.hasNext()) {
var oItem:NotesItem = iterator.next();
var itemName = oItem.getName();
var cItem:NotesItem = changed_doc.getFirstItem(itemName);
if (cItem.getText() !== oItem.getText()) {
print("changed: " + itemName);
}
oItem.recycle();
cItem.recycle();
}
original_doc.remove(true);
original_doc.recycle();