I'm having trouble producing a script to match an object's value in object array based on an object's value in a separate array, and retrieve a separate value from that object.
I have used standard for-loops and the current iteration in jQuery each.
I have also tried setting the if statement to look for the two values as ==, but it always produces non matches (or -1).
Can anyone steer me in the right direction here?
transfers = [
{Package: "1", Origin_Facility = "a"},
{Package: "2", Origin_Facility = "b"}
];
storeData = [
{fromPackage: "1,6,26"}
]
var storeDataEach = function( sx, sxv ) {
var transfersEach = function( sy, syv ) {
if(storeData[sx].fromPackage.indexOf(transfers[sy].Package) > -1){
var facilityStore = transfers[sx].Origin_Facility;
storeData[sx].origin = facilityStore + " + " + transfers[sy].Package + ' + ' + storeData[sx].fromPackage;
return false;
} else {storeData[sx].origin = 'error' + transfers[sy].Package + " + " + storeData[sx].fromPackage;return false;}
};
jQuery.each(transfers, transfersEach);
}
jQuery.each(storeData, storeDataEach);
The main problem is you are returning false from the $.each loop which will stop the iteration
A crude fix is to remove the return from else block
var storeDataEach = function(sx, sxv) {
var transfersEach = function(sy, syv) {
if (storeData[sx].fromPackage.indexOf(transfers[sy].Package) > -1) {
var facilityStore = transfers[sx].Origin_Facility;
storeData[sx].origin = facilityStore + " + " + transfers[sy].Package + ' + ' + storeData[sx].fromPackage;
return false;
} else {
storeData[sx].origin = 'error' + transfers[sy].Package + " + " + storeData[sx].fromPackage;
}
};
jQuery.each(transfers, transfersEach);
}
But this still have problems with the data structure, in your example you have 26 in the fromPackage, now if you have a package value of 2 that also will return a positive result
i have a json object that has item type and id, i need to create new object
var data = {
"items":[
{"type":"generator","id":"item_1","x":200,"y":200},
{"type":"battery","id":"item_2","x":50,"y":300},
{"type":"generator","id":"item_3","x":200,"y":280},
{"type":"battery","id":"item_4","x":100,"y":400}
]
};
and i need to run for each item in items
jQuery.each(data.items, function(index,value) {
eval("var " + value.id + " = new " + value.type + "(" + (index + 1) + ");");
eval(value.id + ".id = '" + value.id + "';");
eval(value.id + ".draw(" + value.x + "," + value.y + ");")
});
this is not a good practice, but what else can i do?
i need then to have the control on the items
something like
item_1.moveto(300,700);
but i always get item_1 is undefind
You can create a factory method which allows to generate concrete types out of an abstract data structure:
var createItem = (function () {
var types = {};
function createItem(index, data) {
data = data || {};
var ctor = types[data.type], item;
if (!ctor) throw new Error("'" + data.type + "' is not a registered item type.");
item = new ctor(index);
item.id = data.id;
return item;
}
createItem.registerType = function (type, ctor) {
types[type] = ctor;
};
return createItem;
})();
Then register item types to the factory:
function Generator(index) {/*...*/}
createItem.registerType('generator', Generator);
And finally create an object map to lookup your items by id (you could use a specialized object like ItemsMap instead of a plain object), loop through your items and add them to the map.
var itemsMap = {};
data.items.forEach(function (itemData, i) {
var item = itemsMap[itemData.id] = createItem(i + 1, itemData);
//you can also draw them at this point
item.draw(itemData.x, itemData.y);
});
You can now lookup objects by id like:
var item1 = itemsMap['item_1'];
var objects = {};
objects[value.id] = new window[value.type](index + 1);
This is the code that I currently have, one problem that is happening is I cannot use test() because presets[index].name and value are not visible outside of their function scope, how should I declare my array of objects in the global scope in order for me to be able to access these two variables in other functions?
var presets = [];
var index;
function CreatePresetArray(AMib, AVar) {
var parentpresetStringOID = snmp.getOID(AMib, AVar);
var presetStringOID = parentpresetStringOID;
parentpresetStringOID = parentpresetStringOID.substring(0, parentpresetStringOID.length - 2);
log.error("parentpresetStringOID is " + parentpresetStringOID);
var presetswitches = {};
for (var i = 1; i < 41; i++) {
presets.push(presetswitches);
try {
log.error("presetStringOID before getNextVB= " + presetStringOID);
vb = snmp.getNextVB(presetStringOID);
presetStringOID = vb.oid;
log.error("presetStringOID after getnextVB= " + presetStringOID);
var presetStringVal = snmp.get(presetStringOID);
log.error("presetStringVal= " + presetStringVal);
index = i - 1;
presets[index].name = presetStringOID;
presets[index].value = presetStringVal;
log.error("preset array's OID at position [" + index + "] is" + presets[index].name + " and the value stored is " + presets[index].value);
//log.error("presets Array value ["+index+"] = "+presets[index].configs);
if (presetStringOID.indexOf(parentpresetStringOID) != 0) {
break;
}
} catch (ie) {
log.error("couldn't load preset array " + index);
};
};
}
CreatePresetArray(presetMib, "presetString");
function test() {
for (i = 1; i < 41; i++) {
log.error("test" + presets[index].name + " " + presets[index].value);
};
}
test();
The for loop in your function test iterates over i but uses index inside the loop. Perhaps you meant to use
for (i = 0; i < 40; i++) { // 1 lower as you were using `index = i - 1` before
log.error("test" + presets[i].name + " " + presets[i].value);
}
Re-wrote your code. I don't think I made that much by way of change. If this doesn't clear up your problem, consider: Is the catch happening each iteration? Is the problem actually coming from a different method which is only visible here? Also, consider logging the whole presets Array when debugging to see what it looks like.
var presets = [];
function CreatePresetArray(AMib, AVar) {
var parentPresetOID, presetOID, presetValue, preset, vb, i;
parentPresetOID = snmp.getOID(AMib, AVar);
presetOID = parentPresetOID; // initial
parentPresetOID = parentPresetOID.substring(0, parentPresetOID.length - 2);
log.error("parentPresetOID is " + parentPresetOID);
presets = []; // empty array in case not already empty
for (i = 0; i < 40; ++i) {
try {
preset = {}; // new object
// new presetOID
vb = snmp.getNextVB(presetOID);
presetOID = vb.oid;
log.error("presetOID after getnextVB= " + presetOID);
// new value
presetValue = snmp.get(presetOID);
log.error("presetValue= " + presetValue);
// append data to object
preset.name = presetOID;
preset.value = presetValue;
// append object to array
presets.push(preset);
// more logging
log.error(
"preset array's OID at position [" + i + "]" +
" is" + presets[i].name + " and " +
"the value stored is " + presets[i].value
);
if (presetOID.indexOf(parentPresetOID) !== 0) {
break;
}
} catch (ie) {
log.error("couldn't load preset array " + i);
if (presets.length !== i + 1) { // enter dummy for failed item
presets.push(null);
}
}
}
}
Two options come to mind immediately:
you could pass the preset array as a argument to test().
You could put both CreatePresetArray() and test() inside a wrapper function and declare preset array at the top of your wrapper. That would give them both access to the variable.
It's generally considered Bad Form to declare globals if it can be avoided. Pollutes the namespace.
Yes there are a number of threads questioning similar issues to the following, but I found very few and very little help regarding dynamic keys and pulling single values from jsons holding multiple values per key.
I have a json in which the keys are dynamic and I need to be able to call upon each separate value.
Any ideas?
json example below:
{"AppliedPrepaidBundle":{"id":["14","15","24","25","26","27","28","29","30","31"],"prepaid_bundle_id":["5","5","5","5","5","5","5","5","5","5"]},"Device":{"id":["77","77","91","91","117","117","117","117","117","124"]}}
I have played around with the following code, but currently only managed to spit out a string of values rather than individual ones:
$.each(data, function (key1, value1) {
$.each(value1, function (key, value) {
$('body').append('<li id="' + key + '">' + key1 +' ' + key +' ' + value + '</li>');
});
});
Solved with this:
json = JSON.parse(data);
for (var index in json) {
$.each(json[index], function(key,value) {
for(var i = 0; i< json[index][key].length; i++){
$('body').append('<li>' + index +' ' + key +' ' + json[index][key][i] + '</li>');
}
});
}
JSON returns an object in JavaScript. So you could do something like this:
var json = {"AppliedPrepaidBundle":{"id":["14","15","24","25","26","27","28","29","30","31"],"prepaid_bundle_id":["5","5","5","5","5","5","5","5","5","5"]},"Device":{"id":["77","77","91","91","117","117","117","117","117","124"]}};
for (var i=0; i<json.AppliedPrepaidBundle.id.length; i++) {
console.log("id"+i+": "+json.AppliedPrepaidBundle.id[i]);
}
This prints out all the values of the ID object: 14, 15, 24, 25, etc
Use JSON.parse to create an object. (See How to parse JSON in JavaScript). Then loop through the properties with for (x in yourObject) { ... }.
var jsonObject = JSON.parse('your JSON-String');
for (property in jsonObject) {
// do something with jsonObject[property]
console.log(property + ' ' + jsonObject[property]);
}
you can work with the javascript basic functionality:
http://jsfiddle.net/taUng/
var data = {"AppliedPrepaidBundle":{"id":["14","15","24","25","26","27","28","29","30","31"],"prepaid_bundle_id":["5","5","5","5","5","5","5","5","5","5"]},"Device":{"id":["77","77","91","91","117","117","117","117","117","124"]}};
for (var dataIndex in data) {
console.log(dataIndex, data[dataIndex]);
var subData = data[dataIndex];
for (var subDataIndex in subData) {
console.log(subDataIndex, subData[subDataIndex]);
}
}
And so on...
When your a fit in javascript you can also work with Recursion to don't repeat yourself. (http://en.wikipedia.org/wiki/Dont_repeat_yourself)
From this example you can access all elements
var json = {"AppliedPrepaidBundle":{"id":["14","15","24","25","26","27","28","29","30","31"],"prepaid_bundle_id":["5","5","5","5","5","5","5","5","5","5"]},"Device":{"id":["77","77","91","91","117","117","117","117","117","124"]}};
for (var i=0; i<json.AppliedPrepaidBundle.id.length; i++) {
$('body').append("<li>AppliedPrepaidBundle id"+i+": "+json.AppliedPrepaidBundle.id[i]+'</li>');
}
for (var i=0; i<json.AppliedPrepaidBundle.prepaid_bundle_id.length; i++) {
$('body').append("<li>PrepaidBundleid"+i+":"+json.AppliedPrepaidBundle.prepaid_bundle_id[i]+'</li>');
}
for (var i=0; i<json.Device.id.length; i++) {
$('body').append("<li>Device id"+i+": "+json.Device.id[i]+'</li>');
}
Here is the fiddle
Unfortunately I can't easily paste the whole script that generates the variable, but I don't see it would be relevant either. Please instruct for more details, if necessary.
Javascript shows this:
console.log(gl.boxes);
shows:
[{element:{0:{jQuery19104057279333682955:9}, context:{jQuery19104057279333682955:9}, length:1}, boxName:"testi1", boxX:1, boxY:"180"}]
so gl.boxes[0] should exist, right? Still...
console.log(gl.boxes[0])
shows: undefined.
So what can I be missing here?
EDIT:
I will paste some more code about the generation of gl.boxes. Should be mostly about creating the variable as array first:
gl.boxes = [];
Then there is a function that handles creating and pushing new objects:
this.addBox = function (box) {
var retBox = {};
retBox.element = $(document.createElement('div'));
retBox.boxName = box.boxName;
retBox.boxX = box.boxX ? box.boxX : rootParent.defaultX;
retBox.boxY = box.boxY ? box.boxY : rootParent.defaultY;
retBox.element
.html(retBox.boxName)
.addClass(rootParent.boxClass)
.offset({ left: retBox.boxX, top: retBox.boxY })
.draggable({
stop: gl.URLs.dragStopDiv(retBox)
});
retBox.element.appendTo(rootParent.containerDiv);
gl.boxes.push(retBox);
return retBox;
};
The objects are created based on URL. Ie. in this test I have inline JS:
gl.objects.addBox({"boxName":"testi1","boxX":"50","boxY":"180"});
Only other place where the gl.boxes is being used is generating a URL based on the objects:
for(key in gl.boxes) {
var position = gl.boxes[key].element.position();
uri +=
"boxName["+key+"]="+gl.boxes[key].boxName+"&"+
"boxX["+key+"]="+position.left+"&"+
"boxY["+key+"]="+position.top+"&";
}
Maybe you need to change your loop to use indexes:
var i = 0,
position = {};
for (i = 0; i < gl.box.length; i += 1) {
position = gl.boxes[i].element.position();
uri += "boxName[" + i + "]=" + gl.boxes[i].boxName + "&" + "boxX[" + i + "]=" + position.left + "&" + "boxY[" + i + "]=" + position.top + "&";
}