Appending objects to JSON lists - javascript

There is an exception occurring and I am not sure why because I am new to JS. As soon as I reach the line testData["beacons"].append(beacon); My code jumps to catch(e). I am assuming I cant append objects to other arrays?
JS:
$(document).ready(function() {
// Data to describe what kind of test
var testData = {
"timestamp": "",
"hive": 0,
"hdfs": 0,
// Contains a list of testData objects
"beacons":[]
};
var testRun = document.getElementById("test-form");
testRun.addEventListener('submit', function(event) {
event.preventDefault();
var selectedTest = document.querySelector('input[name=test-select]:checked');
alert(selectedTest);
var testType = selectedTest.id;
if (testType == "hdfs-test") {
testData["hdfs"] = 1;
testData["hive"] = 0;
} else if (testType == "hive-test") {
testData["hdfs"] = 0;
testData["hive"] = 1;
} else if (testType == "hdfs-hive-test") {
testData["hdfs"] = 1;
testData["hive"] = 1;
} else {
// null
}
var events = document.getElementById("event-textarea").value;
// check in valid input
var eventSource = events.replace("],[","],,,,[");
// beaconLists allows users to submit --> [{beacon1}, {beacon2}, ...], [{beacon3}, {beacon4}, ...]
var beaconLists = eventSource.split(",,,,");
for (var i = 0; i < beaconLists.length; i++) {
// inspect one list in beaconLists [{beacon1}, {beacon2}, ...]
var beaconList = beaconLists[i];
try {
// list of JSON objects
var beaconObjList = JSON.parse(beaconList);
for (var j = 0; j < beaconObjList.length; j++) {
var beaconObj = beaconObjList[j];
if (beaconObj["data"] && beaconObj["application"]) {
// successful parse to find events
// describe beacon being tested
alert("yes");
var beacon = {
"app_name": beaconObj["application"]["app_name"],
"device": beaconObj["application"]["device"],
"device_id": beaconObj["application"]["device_id"],
"os": beaconObj["application"]["os"],
"os_version": beaconObj["application"]["os_version"],
"browser": beaconObj["application"]["browser"],
"beacon": beaconObj
};
// append to testData
testData["beacons"].append(beacon);
// reset beacon so we can append new beacon later
beacon = {};
} else {
// notify event isn't in the correct format?
alert("no");
}
}
} catch (e) {
// notify bad JSON
alert("failed");
}
}
console.log(testData);
//$.ajax({
// type: "POST",
// url: "/test/",
// data: testData,
// success: function () {
// alert("yay");
// },
// failure: function () {
// alert("boo");
// }
//});
});
});

There is nothing wrong with having an array of objects. JavaScript handles that just fine. The main issue is that append is a jQuery API method for adding elements (psuedo native appendChild). push is how you add to an array.
testData["beacons"].push(beacon);
Further, this part of your code is problematic.
// reset beacon so we can append new beacon later
beacon = {};
Both the variable beacon and the one added here testData["beacons"] are the same. In JavaScript, the value of testData["beacons"]'s recent beacon is the same as the variable beacon. When the value in the variable beacon is set to {}, so is the array's value. This line of code simply needs to be removed. Inside of the variable environment set up, the use of var will set up a new variable for beacon each iteration.

You should use the push method, like:
testData["beacons"].push(beacon);

Related

How to update JavaScript array dynamically

I have an empty javascript array(matrix) that I created to achieve refresh of divs. I created a function to dynamically put data in it. Then I created a function to update the Array (which I have issues).
The Data populated in the Array are data attributes that I put in a JSON file.
To better undertand, here are my data attributes which i put in json file:
var currentAge = $(this).data("age");
var currentDate = $(this).data("date");
var currentFullName = $(this).data("fullname");
var currentIDPerson = $(this).data("idPerson");
var currentGender = $(this).data("gender");
Creation of the array:
var arrayData = [];
Here is the function a created to initiate and addind element to the Array :
function initMatrix(p_currentIDPerson, p_currentGender, p_currentFullName, p_currentDate, p_currentAge) {
var isFound = false;
// search if the unique index match the ID of the HTML one
for (var i = 0; i < arrayData.length; i++) {
if(arrayData[i].idPerson== p_currentIDPerson) {
isFound = true;
}
}
// If it doesn't exist we add elements
if(isFound == false) {
var tempArray = [
{
currentIDPerson: p_currentIDPerson,
currentGender: p_currentGender,
currentFullName: p_currentFullName,
currentDate: p_currentDate, currentAge: p_currentAge
}
];
arrayData.push(tempArray);
}
}
The update function here is what I tried, but it doesn't work, maybe I'm not coding it the right way. If you can help please.
function updateMatrix(p_currentIDPerson, p_currentGender, p_currentFullName, p_currentDate, p_currentAge) {
for (var i = 0; i < arguments.length; i++) {
for (var key in arguments[i]) {
arrayData[i] = arguments[i][key];
}
}
}
To understand the '$this' and elm: elm is the clickableDivs where I put click event:
(function( $ ) {
// Plugin to manage clickable divs
$.fn.infoClickable = function() {
this.each(function() {
var elm = $( this );
//Call init function
initMatrixRefresh(elm.attr("idPerson"), elm.data("gender"), elm.data("fullname"), elm.data("date"), elm.data("age"));
//call function update
updateMatrix("idTest", "Alarme", "none", "10-02-17 08:20", 10);
// Définition de l'evenement click
elm.on("click", function(){});
});
}
$('.clickableDiv').infoClickable();
}( jQuery ));
Thank you in advance
Well... I would recommend you to use an object in which each key is a person id for keeping this list, instead of an array. This way you can write cleaner code that achieves the same results but with improved performance. For example:
var myDataCollection = {};
function initMatrix(p_currentIDPerson, p_currentGender, p_currentFullName, p_currentDate, p_currentAge) {
if (!myDataCollection[p_currentIDPerson]) {
myDataCollection[p_currentIDPerson] = {
currentIDPerson: p_currentIDPerson,
currentGender: p_currentGender,
currentFullName: p_currentFullName,
currentDate: p_currentDate,
currentAge: p_currentAge
};
}
}
function updateMatrix(p_currentIDPerson, p_currentGender, p_currentFullName, p_currentDate, p_currentAge) {
if (myDataCollection[p_currentIDPerson]) {
myDataCollection[p_currentIDPerson] = {
currentGender: p_currentGender,
currentFullName: p_currentFullName,
currentDate: p_currentDate,
currentAge: p_currentAge
};
}
}
Depending on your business logic, you can remove the if statements and keep only one function that adds the object when there is no object with the specified id and updates the object when there is one.
I think the shape of the resulting matrix is different than you think. Specifically, the matrix after init looks like [ [ {id, ...} ] ]. Your update function isn't looping enough. It seems like you are trying to create a data structure for storing and updating a list of users. I would recommend a flat list or an object indexed by userID since thats your lookup.
var userStorage = {}
// add/update users
userStorage[id] = {id:u_id};
// list of users
var users = Object.keys(users);

How long should I let a javascript function run before manually ending it?

I have a javascript function that has about 4 ajax requests in it. It typically takes less than a second to run. However, I'm working on the error handling now and was wondering. How long, in seconds, should I allow my javascript function to try to keep working until I manually cancel it and allow the user to try again?
Here's what the function in question looks like. (not everything is there, but it could potentially have (1000*5000*3)+(70)+(1000)+(6)+(2500) bytes being sent)
function saveChanges(bypassDeckSave){
// bypassDeckSave = undefined - does not bypass
showSavedNotification_check = 1;
if(userid != 0){
//values in database
var subjectID = $('.lib_folder_id').val(),
folderID = $('.lib_subject_id').val();
if(subjectID == 0 || folderID == 0){//if database values null, ask for some
console.log("db deck location not saved, asked for it");
//values to set to
var setFolderID = $('.libDeckLocationModifierDiv .folders li.on').val(),
setSubjectID = $('.libDeckLocationModifierDiv .subjects li.on').val();
if(isNaN(setFolderID) || isNaN(setSubjectID) ||
setFolderID == 0 || setSubjectID == 0)
{
openDeckLocationDiv();
showSavedNotification_check = 0;
return;
}
}
}
var deck_id = $('.deck_id').val();
if(deck_id == 0){
// create a new deck
createDeckThenSave();
return;
}
if(userid != 0){
//values in database
var subjectID = $('.lib_folder_id').val(),
folderID = $('.lib_subject_id').val();
if(subjectID == 0 || folderID == 0){//if database values null, ask for some
//values to set to
saveDeckLocation();
}
}
// removes empty rows
$('.editMain li').each(function(){
var one = $(this).find('.text1').val(),
two = $(this).find('.text2').val();
if(one == "" && two == ""){
//remove this row and remove value from updateSaveArray + add to delete array
var currentval = $(this).val();
var rowid = ".row_"+currentval;
updateSaveArray = jQuery.grep(updateSaveArray, function(value) {
return value != currentval;
});
$(rowid).remove();
updateDeleteArray[updateDeleteArray.length] = currentval;
}
});
if(bypassDeckSave == undefined){
// save deck info to db
var deckname = $('.editDeckNameInput').val(),
cardCount = $('.editMain li.mainLi:visible').length,
deckTermLanguage = $('.selector.one select').val(),
deckDefinitionLanguage = $('.selector.two select').val(),
deckThirdBoxLanguage = $('.selector.three select').val(),
deckDescription = $('.editMoreDeckOptionsDiv textarea').val();
if($('.editMoreDeckOptionsSelector .onlyme').hasClass("on")){
var viewPreferences = 1;
}else{
var viewPreferences = 0;
}
if($('.editUseThirdboxDiv').hasClass('on')){ var thirdbox = 1;
}else{ var thirdbox = 2; }
// console.log("deckInfoSave called");
$.ajax({
type: "POST",
url: "/edit/deckInfoSave.php",
data: { pDeckid: deck_id, pDeckname: deckname, pCardCount: cardCount,
pDeckTermLanguage: deckTermLanguage, pDeckDefinitionLanguage: deckDefinitionLanguage,
pDeckThirdBoxLanguage: deckThirdBoxLanguage, pThirdbox: thirdbox,
pDeckDescription: deckDescription, pViewPreferences: viewPreferences
}
})
.done(function(data){
// console.log(data);
// decksaved = 1;
saveDeckInfoHasFinished = 1;
});
}else{
saveDeckInfoHasFinished = 1;
}
// prepares edited card array
// gets all needed values and stores in holdSaveCardArray
var holdSaveCardArray = [];
for (i = 0; i < updateSaveArray.length; ++i) {
var currentCard_id = updateSaveArray[i],
rowidClass = ".row_"+currentCard_id,
text1val = $(rowidClass+" .text1").val(),
text2val = $(rowidClass+" .text2").val(),
text3val = $(rowidClass+" .text3").val();
cardOrder = $(".editMain li.mainLi:visible").index($(rowidClass)) + 1;
holdSaveCardArray[holdSaveCardArray.length] = {
"card_id": currentCard_id,
"text1val": text1val,
"text2val": text2val,
"text3val": text3val,
"cardOrder": cardOrder
};
}
// console.log(print_r(holdSaveCardArray));
// delete cards start
// deletes any card with an id in updateDeleteArray
$.ajax({
type: "POST",
url: "/edit/deleteCards.php",
data: { pDeck_id: deck_id, pDeleteArray: updateDeleteArray }
})
.done(function( msg ) {
// $('.temp').append(msg);
updateDeleteArray = [];
deleteCardsHasFinished = 1;
});
// save cards to database
// loops through each card that had changes made to it
$.ajax({
type: "POST",
url: "/edit/saveCardsArray.php",
dataType: "JSON",
data: { pDeck_id: deck_id, pCardArray: holdSaveCardArray}
}).done(function(data){
for (var i = 0; i < data.length; i++) {
var temp_id = data[i]["temp_id"], // new id
card_key = data[i]["card_key"], // old id
currentClassName = 'row_'+temp_id,
currentClass = '.row_'+temp_id,
nextClassName = 'row_'+card_key;
$(currentClass).val(card_key);
$(currentClass).removeClass(currentClassName).addClass(nextClassName);
}
saveCardsHasFinished = 1;
});
updateSaveArray = [];
// update order start // uses li value
updateOrderArray = [];
$('.editMain').find(".mainLi").each(function(){
var temp = $(this).val();
updateOrderArray[updateOrderArray.length] = temp;
});
$.ajax({
type: "POST",
url: "/edit/orderCards.php",
data: { pUpdateOrderArray: updateOrderArray }
})
.done(function( msg ) {
updateOrder = 0;
updateOrdersHasFinished = 1;
});
closeLibDLM(); console.log("closeLibDLM1");
changeSaveStudyButton(1);
} //saveChanges function end
So you could totally set an arbitrary timeout, or even a timeout that should encompass everything finishing on time? But, what happens when it doesn't? What happens when it takes longer to finish?
At that point, you're going to be in quite a pickle. I did not thoroughly read your code, but I would highly advise trying to use a callback() or Promise to end your function. And, not set a timeout. - This is a cleaner solution in that things happen when you want them, and after some defined has happened. Time is a relative, and finicky attribute of our world (Einstein proved this =P) that would be best be used as your friend, and not your enemy.
The counter argument would be, well sometimes things just hang. And, that is totally valid. For that case, you could set a timeout for a long period of time. But, again, that is still a 'hacky' way to handle things. In this case, I would try to create some handling to detect errors, or timeouts. i.e you could periodically check the page for a status. You could check to see which events are in existence that you could hook into.
If you could share in what instances our program hangs, I could better suggest a solution. Otherwise this question may end up being opinionated based on coding styles.
Hope this helps in some regard :)
I've worked in the Aerospace Aviation Industry and have asked a similar question when working with Microcontrollers. It seems you are looking for an appropriate timeout value based on calculation, but this may not be necessary in your case. Often times timeout values are more or less arbitrary. If your function executes in an average of roughly 1 second, maybe your timeout value should be set to 3 seconds. You should come to a conclusion based on testing.

Javascript array shows in console, but i cant access any properties in loops

I really try my damndest not to ask, but i have to at this point before I tear my hair out.
By the time the js interpreter gets to this particular method, I can print it to the console no problem, it is an array of "event" objects. From FireBug I can see it, but when I try to set a loop to do anything with this array its as if it doesn't exist. I am absolutely baffled......
A few things:
I am a newbie, I have tried a for(var index in list) loop, to no avail, I have also tried a regular old for(var i = 0; i < listIn.length; i++), and I also tried to get the size of the local variable by setting var size = listIn.length.
As soon as I try to loop through it I get nothing, but I can access all the objects inside it from the FireBug console no problem. Please help, even just giving me a little hint on where I should be looking would be great.
As for the array itself, I have no problems with getting an array back from PHP in the form of: [{"Event_Id":"9", "Title":"none"}, etc etc ]
Here is my code from my main launcher JavaScript file. I will also post a sample of the JSON data that is returned. I fear that I may be overextending myself by creating a massive object in the first place called content, which is meant to hold properties such as DOM strings, settings, and common methods, but so far everything else is working.
The init() function is called when the body onload is called on the corresponding html page, and during the call to setAllEvents and setEventNavigation I am lost.
And just to add, I am trying to learn JavaScript fundamentals before I ever touch jQuery.
Thanks
var dom, S, M, currentArray, buttonArray, typesArray, topicsArray;
content = {
domElements: {},
settings: {
allContent: {},
urlList: {
allURL: "../PHP/getEventsListView.php",
typesURL: "../PHP/getTypes.php",
topicsURL: "../PHP/getTopics.php"
},
eventObjArray: [],
buttonObjArray: [],
eventTypesArray: [],
eventTopicsArray: []
},
methods: {
allCallBack: function (j) {
S.allContent = JSON.parse(j);
var list = S.allContent;
for (var index in list) {
var event = new Event(list[index]);
S.eventObjArray.push(event);
}
},
topicsCallBack: function(j) {
S.eventTopicsArray = j;
var list = JSON.parse(S.eventTopicsArray);
topicsArray = list;
M.populateTopicsDropDown(list);
},
typesCallBack: function(j) {
S.eventTypesArray = j;
var list = JSON.parse(S.eventTypesArray);
typesArray = list;
M.populateTypesDropDown(list);
},
ajax: function (url, callback) {
getAjax(url, callback);
},
testList: function (listIn) {
// test method
},
setAllEvents: function (listIn) {
// HERE IS THE PROBLEM WITH THIS ARRAY
console.log("shall we?");
for(var index in listIn) {
console.log(listIn[index]);
}
},
getAllEvents: function () {
return currentArray;
},
setAllButtons: function (listIn) {
buttonArray = listIn;
},
getAllButtons: function () {
return buttonArray;
},
setEventNavigation: function(current) {
// SAME ISSUE AS ABOVE
var l = current.length;
//console.log("length " + l);
var counter = 0;
var endIndex = l - 1;
if (current.length < 4) {
switch (l) {
case 2:
var first = current[0];
var second = current[1];
first.setNextEvent(second);
second.setPreviousEvent(first);
break;
case 3:
var first = current[0];
var second = current[1];
var third = current[2];
first.setNextEvent(second);
second.setPreviousEvent(first);
second.setNextEvent(third);
third.setPreviousEvent(second);
break;
default:
break;
}
} else {
// do something
}
},
populateTopicsDropDown: function(listTopics) {
//console.log("inside topics drop");
//console.log(listTopics);
var topicsDropDown = document.getElementById("eventTopicListBox");
for(var index in listTopics) {
var op = document.createElement("option");
op.setAttribute("id", "dd" + index);
op.innerHTML = listTopics[index].Main_Topic;
topicsDropDown.appendChild(op);
}
},
populateTypesDropDown: function(listTypes) {
//console.log("inside types drodown");
//console.log(listTypes);
var typesDropDown = document.getElementById("eventTypeListBox");
for(var index2 in listTypes) {
var op2 = document.createElement("option");
op2.setAttribute("id", "dd2" + index2);
op2.innerHTML = listTypes[index2].Main_Type;
typesDropDown.appendChild(op2);
}
}
},
init: function() {
dom = this.domElements;
S = this.settings;
M = this.methods;
currentArray = S.eventObjArray;
buttonArray = S.buttonObjArray;
topicsArray = S.eventTopicsArray;
typesArray = S.eventTypesArray;
M.ajax(S.urlList.allURL, M.allCallBack);
//var tempList = currentArray;
//console.log("temp array length: " + tempList.length);
M.setAllEvents(currentArray);
M.testList(currentArray);
M.setEventNavigation(currentArray);
//M.setEventNavigation();
M.ajax(S.urlList.topicsURL, M.topicsCallBack);
M.ajax(S.urlList.typesURL, M.typesCallBack);
}
};
The problem you have is that currentArray gets its value asynchronously, which means you are calling setAllEvents too soon. At that moment the allCallBack function has not yet been executed. That happens only after the current running code has completed (until call stack becomes emtpy), and the ajax request triggers the callback.
So you should call setAllEvents and any other code that depends on currentArray only when the Ajax call has completed.
NB: The reason that it works in the console is that by the time you request the value from the console, the ajax call has already returned the response.
Without having looked at the rest of your code, and any other problems that it might have, this solves the issue you have:
init: function() {
dom = this.domElements;
S = this.settings;
M = this.methods;
currentArray = S.eventObjArray;
buttonArray = S.buttonObjArray;
topicsArray = S.eventTopicsArray;
typesArray = S.eventTypesArray;
M.ajax(S.urlList.allURL, function (j) {
// Note that all the rest of the code is moved in this call back
// function, so that it only executes when the Ajax response is
// available:
M.allCallBack(j);
//var tempList = currentArray;
//console.log("temp array length: " + tempList.length);
M.setAllEvents(currentArray);
M.testList(currentArray);
M.setEventNavigation(currentArray);
//M.setEventNavigation();
// Note that you will need to take care with the following asynchronous
// calls as well: their effect is only available when the Ajax
// callback is triggered:
M.ajax(S.urlList.topicsURL, M.topicsCallBack); //
M.ajax(S.urlList.typesURL, M.typesCallBack);
});
}

Format returned table data in json

I'm fairly new to javascript. I retreive data from a sql server database that looks like this :
[Object { shortcode="0013A2004031AC9A", latest_measurement=1067, keyid="6801"},
Object { shortcode="0013A2004031AC9A", latest_measurement=7, keyid="6802"},
Object { shortcode="0013A2004031AC9A", latest_measurement=8598838, keyid="6803"}]
I want to format this in a json like this :
{mac : 0013A2004031AC9A, keys : {6801:1067, 6802:7, 6803:8598838}}
but I just don't get to that.
I have
var jsonDataPerMac = {};
I loop over the json object above and for every new mac I find I do :
jsonDataPerMac[i]={"mac": device.shortcode, "keys":[]};
but how do I get to fill the keys?
Any hints would be appreciated.enter code here
var macs = [];
var jsonDataPerMac = {};
var i = 0;
$.ajax({
url: "/bmmeasurements",
type: "GET",
data: {"unitid" : unitid},
async: false,
success: function (data) {
console.log(data);
initializeTable();
$.each(data, function (index,device) {
//add all distinct macs in an array, to use them as a column header
if($.inArray(device.shortcode, macs) == -1) {
macs.push(device.shortcode);
jsonDataPerMac[i]={"mac": device.shortcode, "keys":[]};
i++;
//create a table cell for each possible key. id = 'mac-key'
createTableGrid(device.shortcode);
}
//add the measurement data to the correct cell in the grid
$('#' + device.shortcode + '-' + device.keyid).html(device.latest_measurement);
});
}});
Here is my proposition. I would rather avoid using jQuery to perform such a simple operations. In this particular example, we use forEach and for..in loop.
//new output array
var newArray = [];
//we traverse the array received from AJAX call
array.forEach(function(el) {
var added = false; // it's false by default
// we check if the mac is already in newArray, if yes - just add the key
for(var i in newArray) {
if(newArray[i].mac == el.shortcode) {
newArray[i].keys.push(el.keyid+":"+el.latest_measurement);
added = true; // tells us whether the key has been added or not
}
}
// if key hasn't been added - create a new entry
if(!added) {
newArray.push({"mac": el.shortcode, "keys":[el.keyid+":"+el.latest_measurement]});
}
});
console.log(newArray);
You can transform above code to a function and then, reuse it in your ajax onSuccess method. Remember to pass the array as an argument and to return newArray.
JSFiddle:
http://jsfiddle.net/2d5Vq/2/
You need to combine the entries first...
var reducedData = {};
$.each(macs, function(index,macitem){
if (reducedData.hasOwnProperty(macitem.shortcode)) {
reducedData[macitem.shortcode].push(macitem.key);
} else {
reducedData[macitem.shortcode] = [ macitem.key ];
}
});
And then map to your desired format inside an array...
var jsonDataPerMac = [],
i = 0;
$.map(reducedData, function(keys,mac){
jsonDataPerMac[i++] = {"mac": mac, "keys": keys};
// your other code goes here
});
Also your usage of jsonDataPerMac suggests that you want it to be an array.

Advanced search/queue array collection question

I have a pretty large number of objects "usrSession" I store them in my ArrayCollection usrSessionCollection.
I'M looking for a function that returns the latest userSessions added with a unique userID. So something like this:
1.
search the usrSessionCollection and only return one userSessions per userID.
2.
When it has returned x number of userSessions then deleted them from the usrSessionCollection
I'M stuck - would really love some code that can help me with that.
function ArrayCollection() {
var myArray = new Array;
return {
empty: function () {
myArray.splice(0, myArray.length);
},
add: function (myElement) {
myArray.push(myElement);
}
}
}
function usrSession(userID, cords, color) {
this.UserID = userID;
this.Cords = cords;
this.Color = color;
}
usrSessionCollection = new ArrayCollection();
$.getJSON(dataurl, function (data) {
for (var x = 0; x < data.length; x++) {
usrSessionCollection.add(new usrSession(data[x].usrID.toString(), data[x].usrcords.toString() ,data[x].color.toString());
}
});
Thanks.
The biggest issue is that you have made the array private to the outside world. Only methods through which the array can be interacted with are add and empty. To be able to search the array, you need to either add that functionality in the returned object, or expose the array. Here is a modified ArrayCollection:
function ArrayCollection() {
var myArray = new Array;
return {
empty: function () {
myArray.splice(0, myArray.length);
},
add: function (myElement) {
myArray.push(myElement);
},
getAll: function() {
return myArray;
}
}
}
Now to get the last N unique session objects in usrSessionCollection, traverse the sessions array backwards. Maintain a hash of all userID's seen so far, so if a repeated userID comes along, that can be ignored. Once you've collected N such user sessions or reached the beginning of the array, return all collected sessions.
usrSessionCollection.getLast = function(n) {
var sessions = this.getAll();
var uniqueSessions = [];
var addedUserIDs = {}, session, count, userID;
for(var i = sessions.length - 1; i >= 0, uniqueSessions.length < n; i--) {
session = sessions[i];
userID = session.userID;
if(!addedUserIDs[userID]) {
uniqueSessions.push(session);
addedUserIDs[userID] = true;
}
}
return uniqueSessions;
}
I wouldn't combine the delete step with the traversal step, just to keep things simple. So here's the remove method that removes the given session from the array. Again, it's better to modify the interface returned by ArrayCollection rather than tampering with the sessions array directly.
function ArrayCollection(..) {
return {
..,
remove: function(item) {
for(var i = 0; i < myArray.length; i++) {
if(item == myArray[i]) {
return myArray.splice(i, 1);
}
}
return null;
}
};
}
Example: Get the last 10 unique sessions and delete them:
var sessions = usrSessionCollection.getLast(10);
for(var i = 0; i < sessions.length; i++) {
console.log(sessions[i].UserID); // don't need dummy variable, log directly
usrSessionCollection.remove(sessions[i]);
}
See a working example.
You made your array private, so you can't access the data, except adding a new element or removing them all. You need to make the array public, or provide a public interface to access the data. Like first(), next() or item(index).
Then you can add a search(userID) method to the usrSessionCollection, which uses this interface to go through the elements and search by userID.
UPDATE: this is how I would do it: - See it in action. (click preview)
// user session
function userSession(userID, cords, color) {
this.UserID = userID;
this.Cords = cords;
this.Color = color;
}
// a collection of user sessionions
// a decorated array basically, with
// tons of great methods available
var userSessionCollection = Array;
userSessionCollection.prototype.lastById = function( userID ) {
for ( var i = this.length; i--; ) {
if ( this[i].UserID === userID ) {
return this[i];
}
}
// NOTE: returns undefined by default
// which is good. means: no match
};
// we can have aliases for basic functions
userSessionCollection.prototype.add = Array.prototype.push;
// or make new ones
userSessionCollection.prototype.empty = function() {
return this.splice(0, this.length);
};
//////////////////////////////////////////////////////
// make a new collection
var coll = new userSessionCollection();
// put elements in (push and add are also available)
coll.add ( new userSession(134, [112, 443], "#fffff") );
coll.push( new userSession(23, [32, -32], "#fe233") );
coll.push( new userSession(324, [1, 53], "#ddddd") );
// search by id (custom method)
var search = coll.lastById(134);
if( search ) {
console.log(search.UserID);
} else {
console.log("there is no match");
}
// empty and search again
coll.empty();
search = coll.lastById(134);
if( search ) {
console.log(search.UserID);
} else {
console.log("there is no match");
}

Categories

Resources