Adding Objects to JS Array - javascript

I am trying to create an array of objects that contain two pieces of information relating to an order:
Product Stock Code
Product Quantity
Currently I am doing it like this:
$(".orderBtn").click(function(event){
//Show the order Box
$(".order-alert").show();
event.preventDefault();
//Create the Array
var productArray = [];
//Get reference to the product clicked
var stockCode = $(this).closest('li').find('.stock_code').html();
//Get reference to the quantity selected
var quantity = $(this).closest('li').find('.order_amount').val();
var key = "stockCode";
var obj = {
'stockCode' : stockCode,
'quantity' : quantity
};
productArray.push(obj);
$.cookie('order_cookie', JSON.stringify(productArray), { expires: 1, path: '/' });
console.log(productArray);
if(quantity == 0){
console.log("Quantity must be greater than 0")
}
I would expect that each time the order button is clicked that the new object would be added to the array of existing objects but instead It just outputs the array with 1 object, the object I've just added.
Is there something I am missing?

Move your array declaration outside of the function into the global scope.
What happens in your case is that each time you call the function a new array is created(function scope) and therefore only one result is produced.
Read this about scopes\hoistings.
var productArray = [];
$(".orderBtn").click(function(event){
//Show the order Box
$(".order-alert").show();
event.preventDefault();
//Create the Array
//Get reference to the product clicked
var stockCode = $(this).closest('li').find('.stock_code').html();
//Get reference to the quantity selected
var quantity = $(this).closest('li').find('.order_amount').val();
var key = "stockCode";
var obj = {
'stockCode' : stockCode,
'quantity' : quantity
};
productArray.push(obj);
$.cookie('order_cookie', JSON.stringify(productArray), { expires: 1, path: '/' });
console.log(productArray);
if(quantity == 0){
console.log("Quantity must be greater than 0")
}

declare as global variable
var productArray = [];
$(".orderBtn").click(function(event){
// do here
//productArray.push("anyObject");
});

You are recreating / overwriting the productArray every time the button is clicked. Try moving the var productArray = [] to outside of the click handler

Not so, because your
var productArray = [];
is within the function that sets the cookie, so it's getting defined afresh then having one element added each time the function is called.
You'd need to define productArray outside of the function (as a global variable?) so that it retains its previous value, and new objects are added to it

With var productArray = []; you're declaring a new array on every click. Move that line outside the click handler and the code should start working.

Related

Array.push is not working for local storage

I am creating a shopping cart where user can add an item to cart. Once user clicked the addtocart button, I want to save the product id, name, price and quantity to local storage and then retrieve them on the cart page. So I tried this
var cart = new Array;
if (cart != []) {
cart = JSON.parse(localStorage["cart"]);
}
$('#addtocart').on('click', function(e) {
var qty = document.getElementById("p-qty").value;
var li = $(this).parent();
var product = {};
product.id = productid;
product.name = document.getElementById("nomenclature").innerHTML;
product.price = document.getElementById("productprice").innerHTML;
product.quantity = qty;
addToCart(product);
});
function addToCart(product) {
// Retrieve the cart object from local storage
if (localStorage) {
var cart = JSON.parse(localStorage['cart']);
cart.push(product);
localStorage.setItem('cart', JSON.stringify(cart));
}
// window.location = "html/cart.html"
}
but I keep getting this error
Uncaught TypeError: cart.push is not a function
What am I doing wrongly and how can I fix it?
You don't check that localStorage['cart'] is defined and don't check that the deserialized variable is an array. I'd suggest doing something like this:
function addToCart(product) {
if (localStorage) {
var cart;
if (!localStorage['cart']) cart = [];
else cart = JSON.parse(localStorage['cart']);
if (!(cart instanceof Array)) cart = [];
cart.push(product);
localStorage.setItem('cart', JSON.stringify(cart));
}
}
Note, however, that if you have a serialized object or other non-array variable in localStorage['cart'], it will be overwritten with this method.
localStorage in HTML5 is Object, you can set item by using .setItem() and get item by .getItem()
Demo get old values, push new value and save values with localStorage
var Values = [];
//get olds values
Values = JSON.parse(localStorage.getItem('Storage'));
//push new value
Values.push(item);
//saved values
localStorage.setItem('Storage', JSON.stringify(Values));
Now with your edit, problem you have here is this makes no sense. First You set the array to be empty, so it will always be empty. Now second issue is [] will never equal new Array so it will always go into the if statement. And since you probably never set localStorage["cart"] with anything, it will be invalid.
var cart = new Array; // <-- you define an array?
if (cart != []) { // <- than you check the array you just created? How would it have a value if this check would actually work?
cart = JSON.parse(localStorage["cart"]);
}
So what you need to do is get rid of that if, since it does nothing. Next you just need to check localstorage if it has a value, if it does not, than set it to an emoty array. So add a conditional that if it is undefined, it uses a new array
Now what your codde should have been was
var cart = []; //define the array
if (localStorage["cart"]) { // Check that it has a value in storage
cart = JSON.parse(localStorage["cart"]); //If yes, parse it
}
or another way could be
var cart = JSON.parse(localStorage['cart'] || '[]');

Accessing outer scope from jQuery.each() function

I want to iterate over all elements of "shift" and update an outer array called new_requests, how do i do this ?, currently i get an undefined error on the line thats supposed to update the array. thanks.
$scope.save = function(){
var new_requests = [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]];
$("shift").each(function(){
var day = $("this").attr("day");
var shift = $("this").attr("shift");
var status = $("this").attr("status");
new_requests[day][shift]=status;
})
console.log(new_requests);
}
Assuming shift is a collection of elements with day, shift and status attributes, use:
$.each($(shift), function() {
var day = $(this).attr("day");
var shift = $(this).attr("shift");
var status = $(this).attr("status");
new_requests[day][shift]=status;
});
Note $(shift) instead of $("shift") and $(this) instead of $("this").

Items in array returning last one only

I am using this function to pass every element in an array to use it in an if statement The problem is that the function is always returning the last value of the array Please help.
function getQtyCheck()
{
var qty;
var id;
var checkQty = new Array()
if(localStorage.getItem("checkout")!=null || localStorage.getItem("checkout")!=""){
checkQty = JSON.parse(localStorage.getItem("checkout"));
for(var t =0; checkQty.length >t; t++){
id = checkQty[t];
t++;
qty = checkQty[t];
}//end for loop
return {ids:id,qtys:qty}
}//end checkout
}
Then in another part of the script I ma using these variables like this
var result = getQtyCheck();
var id = result.ids;
var qty = result.qtys;
if(this.id == id){
var tqty = this.quantity-qty;
Each loop iteration, you assign id and qty to the currently iterated item. Once the loop is over, you return an object with the LAST iterated item set to your variables. Since your return is immediately after the loop and using variables set within the loop, you will always get the last values.
I think I'm following what you are trying to do now. You want to return every element in the array as an array of objects right?
function getQtyCheck() {
var qty,
id,
checkQty = [],
returnValues = [];
if(localStorage.getItem("checkout")!=null && localStorage.getItem("checkout")!=""){
checkQty = JSON.parse(localStorage.getItem("checkout"));
for(var t =0, len = checkQty.length; len > t; t++){
id = checkQty[t];
t++;
qty = checkQty[t];
returnValues.push({ id: id, qty: qty });
}
return returnValues;
}
}
In the loop, build an array of the objects you want to return. After the loop, return the newly created array.
It's returning the last one every time because you're looping it which is adding it up, but then you're using return outside the loop, which is just going to get the last one that it ran.
You shouldn't return inside the for loop because it will try to return multiple times. What you can do though is push it to an array and then get it at the end.

IndexedDB: Retrieve item with max value

Suppose I have an IndexedDB collection with name items. All items have fields:
id
name
revision
revision field is a number field. I need to retrieve an item with max value of revision (or at least just retrive max revision value). What is the best way to do it?
First thing you need to do is create index on the revision field.
Then you need a search function which will use that index and open the index with inverse order of the objects. Then the first object will be the object you are looking for.
var index = objectStore.index('revision');
index.openCursor(null, 'prev');
The null states that you are searching for all values not a specific one, and the second parameter is the direction of the search.
Here is the sample code:
function getMaxNumber (callback) {
var openReq = indexedDB.open(baseName);
openReq.onsuccess = function() {
var db = openReq.result;
var transaction = db.transaction(objectStoreName, 'readonly');
var objectStore = transaction.objectStore(objectStoreName);
var index = objectStore.index('revision');
var openCursorRequest = index.openCursor(null, 'prev');
var maxRevisionObject = null;
openCursorRequest.onsuccess = function (event) {
if (event.target.result) {
maxRevisionObject = event.target.result.value; //the object with max revision
}
};
transaction.oncomplete = function (event) {
db.close();
if(callback) //you'll need a calback function to return to your code
callback(maxRevisionObject);
};
}
}
Since the IndexedDB api is async you would need a callback function to return the value to your code.

Not able to retrieve value from multidimensional array

I have a multidimensional array in which some values are present i
want to retrieve the [0][1] or [1][1] index value. I am getting
undefined as array, if i tried to directly try to get the array value
am able to get the value.
This what i want to achieve
I had a select drop down menu , According to the selected index i
need to retrieve a message from the array box. For say if the index is
1 then i had to get [1][1] array index value if it is zero then [0][1]
array index value
This is the fiddle what i have done. http://jsfiddle.net/hTQZ9/
see this update: http://jsfiddle.net/hTQZ9/1/
var MessagesObj = {
testName: []
}
MessagesObj["testName"].push(["testName_custom_message_Label1val","Custom message for label 1"]);
MessagesObj["testName"].push(["testName_custom_message_Label2val","Custom message for label 2"]);
alert(MessagesObj["testName"][1][1]);
var classChk = $(".customCheckEnabled").get(0);
var getClassindex = classChk.selectedIndex;
var getVarName = classChk.id
var getCstMsgName = MessagesObj[getVarName];
alert(getCstMsgName);
var getMessage = getCstMsgName[getClassindex][1];
alert(getMessage);
getCstMsgName is a string, not an array.
One way is to use this
$(document).ready(function () {
var testName_MessagesArray = new Array();
var cntr = 0;
testName_MessagesArray[cntr] = new Array("testName_custom_message_Label1val", "Custom message for label 1");
cntr++;
testName_MessagesArray[cntr] = new Array("testName_custom_message_Label2val", "Custom message for label 2");
cntr++;
alert(testName_MessagesArray[1][1]);
var classChk = $(".customCheckEnabled");
alert(classChk);
this.testName = testName_MessagesArray; //<-- set this with the name
var getClassindex = classChk.attr("selectedIndex");
alert(getClassindex);
var getVarName = classChk.attr("id");
alert(getVarName);
var getCstMsgName = this[getVarName]; //<-- reference it from this
alert(getCstMsgName);
var getMessage = getCstMsgName[getClassindex][1];
alert(getMessage);
});
​
If testName_MessagesArray is in global scope, you can do window["testName_MessagesArray"] to reference it. Your current example is local scope so that would not work.
You should really use an array literal instead of, er, cntrs:
var testName_MessagesArray = [
["testName_custom_message_Label1val", "Custom message for label 1"],
["testName_custom_message_Label2val", "Custom message for label 2"]
];
Then, if you want to retrieve a value from it, use testName_MessagesArray[x][y].
What you were doing:
var classChk=$(".customCheckEnabled");
// this is a jQuery element, alerted as [object Object]
var getClassindex=classChk.attr("selectedIndex");
// this is 0 or 1
var getVarName=classChk.attr("id");
// this will be the id of the first selected element, a string
var getCstMsgName=getVarName+"_MessagesArray".toString();
// this will create a string, from the "getVarName"-string and your string-literal-toString
var getMessage=getCstMsgName[getClassindex][1];
// as "getCstMsgName" is a string - not the twodimensional array,
// getCstMsgName[getClassindex] returns the character at the selected index (as a string)
// and getCstMsgName[getClassindex][1] results in the second character of the one-character-string - undefined

Categories