I'm trying to save a shopping cart to local storage but having trouble to save it as I the way I want it to be saved. For each added order with the same id, the amount should increase and not create another duplicate of the input. I've got this semi-working with the first item/order but when I order more items they lay in the first order. And when I put the first order in again, it puts itself at the back and increases the amount in a weird way. Thankful for any help as I tried to fix this a couple of days now and tried a lot of different stuff with different results.
From local storage:
Button with id 88 pressed 4 times:
[{"id":"88","amount":4}]
Button with id 79 pressed 4 times:
[{"id":"88","amount":4},{"id":"79","amount":5}
,{"id":"79","amount":4},{"id":"79","amount":3},{"id":"79","amount":2}]
Then I press the button with id 88 again ONE time:
[{"id":"88","amount":5},{"id":"79","amount":5},{"id":"79","amount":4},
{"id":"79","amount":3},{"id":"79","amount":2},{"id":"88","amount":5},
{"id":"88","amount":5},{"id":"88","amount":5},{"id":"88","amount":5}]
And here is my javascript:
$("#btnBuyMovie").on("click", function () {
var movieId = getParameterByName("productId");
var amount = 1;
if (localStorage.getItem("shoppingCart") !== null) {
shoppingCartFromLS = JSON.parse(localStorage.getItem("shoppingCart"));
var newShoppingCart = new ShoppingCart(movieId, amount);
for (var i = 0; i < shoppingCartFromLS.length; i++) {
if (movieId != shoppingCartFromLS[i].id) {
shoppingCartFromLS.push(newShoppingCart);
localStorage.setItem("shoppingCart", JSON.stringify(shoppingCartFromLS));
}
}
for (var i = 0; i < shoppingCartFromLS.length; i++) {
if (movieId == shoppingCartFromLS[i].id) {
shoppingCartFromLS[i].amount++;
}
}
localStorage.setItem("shoppingCart", JSON.stringify(shoppingCartFromLS));
} if (localStorage.getItem("shoppingCart") == null) {
var shoppingCartFromLS = [];
newShoppingCart = new ShoppingCart(movieId, amount);
shoppingCartFromLS.push(newShoppingCart);
localStorage.setItem("shoppingCart", JSON.stringify(shoppingCartFromLS));
}
Problem
Following for-loop has multiple problems
This line doesn't look correct.
Assuming you meant it to be this way, there is a semicolon at the end of it and it is pushing a shopping cart to the result of push function
if (movieId != shoppingCartFromLS[i].shoppingCartFromLS.push(newShoppingCart);
Assuming the above line is what you meant it to be, you are checking if every item is not the same item you are looking for.
So, if that item is not found on any iteration, you add that item again.
for (var i = 0; i < shoppingCartFromLS.length; i++) {
if (movieId != shoppingCartFromLS[i].shoppingCartFromLS.push(newShoppingCart);
localStorage.setItem("shoppingCart", JSON.stringify(shoppingCartFromLS)); //this will happen for every item except the item that matches
}
}
Finally, this for-loop isn't required
for (var i = 0; i < shoppingCartFromLS.length; i++) {
if (movieId == shoppingCartFromLS[i].id) {
shoppingCartFromLS[i].amount++;
}
}
Solution
You need to optimize your code this way
var isFound = shoppingCartFromLS.some( function( item ){
var isFound = item.id == movieId; //this line is updated
item.amount += isFound ? 1 : 0;
return isFound;
})
if (!isFound)
{
shoppingCartFromLS.push( { id : movieId, amount : 1 } )
}
localStorage.setItem("shoppingCart", JSON.stringify(shoppingCartFromLS));
Related
How to make to make it delete the rows that match a criteria and were pushed into an array?
So far, I got the following, but it gives me out of bounds error:
for (var i = 1; i < values.length; i++) {
if (values[i][0] == productCode) {
data.push([values[i][22],values[i][23],values[i][24],values[i][25]]); //This array is for a certain purpose.
headerData.push(headerValues[i]);//This array is for another certain purpose.
sheet.deleteRow(i+1); //This is the one I'm having trouble with.
}
}
On Source sheet, I got headers
I've seen that delete row actually works from bottom to top, but how I can re-reference i rows within that for loop?
Thanks!
Loop backwards:
for (var i = (values.length-1); i > 0; i--) {
if (values[i][0] == productCode) {
data.push([values[i][22],values[i][23],values[i][24],values[i][25]]); //This array is for a certain purpose.
headerData.push(headerValues[i]);//This array is for another certain purpose.
sheet.deleteRow(i+1); //This is the one I'm having trouble with.
}
}
I would try something like that:
let headerData = []
let data = [];
const headerSize = 1;
for (let i = values.length - 1; i > headerSize; i--) {
if (values[i][0] === productCode) {
let row = [values[i][22],values[i][23],values[i][24],values[i][25]]
data = [row, ...data]
headerData = [headerValues[i], ...headerData]
sheet.deleteRow(i+1);
}
}
use destructuring arrays to keep the values in order
So I have a few arrays
var item = [{
name : "somename",
type1 : "wood",
location : "some location",
desc : "some description"
}, {
name : "somename",
type1 : "metal",
location : "somelocation",
desc : "some description"
}];
and
var shopState = 0;
var hasInv = [];
var pickedItem = [];
I assume I have 2 empty arrays with that last one. Later on I attempt to make use of these in a function.
function shop() {
for (var i = 0; i < item.length; i++) {
if (item[i].location == "some location") {
//get all items at some location
hasInv[i] = item[i];
}
}
if (shopState == 1) {
var d = 1;
for (var i = 1; i < hasInv.length; i++) {
if (hasInv[i].type1 == 'wood') {
//get all wood items at some location
pickedItem[d] = hasInv[i];
d++;
console.log(pickedItem);
}
}
}
}
That last bit with pickedItem returned undefined unless I declare pickedItem = []; in shopState when I thought I already declared it at the start of the file. It works when I do but I'm trying to understand why it does not if i don't.
A couple of questions: Is your conditional for shopState passing? I don't see where you increment shopState. Also is there a reason you are setting to indexes directly instead of using .push or .unshift? Maybe for time complexity concerns? I'm assuming the purpose of the function is to iterate through store locations to find matching locations and then find all items of a certain type at that location? Is that correct? If that is true here is the solution:
function shop() {
for (var i = 0; i < item.length; i++) {
if (item[i].location == "some location") {
//get all items at some location
hasInv.push(item[i]);
//You weren't increment shopState
shopState++;
}
}
if (shopState == 1) {
//conditional now passes
//there is no need to set a additional index variable.
for (var i = 0; i < hasInv.length; i++) {
if (hasInv[i].type1 == 'wood') {
//get all wood items at some location
pickedItem.push(hasInv[i]);
console.log(pickedItem);
}
}
}
}
shop()
Also note that your conditional makes it so you will only locate one item with the wood type. To change this so that your comment is true and you are collecting all items simply change your conditional to:
if(shopState >= 1)
As well you are only checking one location because you have combined the words some and location in the second object of your items array.
I have an JS Array that is supposed to show only one element. It does, however its index is 1 rather than 0 and the count is 2. Also the array does not show a 0 index.
My code:
var _UnitOfMeasureRelatedUnitData = [];
var rows = $('#jqxUOMRelatedUnitsDropdownGrid').jqxGrid('getrows');
var RecordCount = 0;
if (rows.length !== 1 && rows[0]["UOMRelatedUnit_Name"] !== ""){
for(var i = 0; i < rows.length; i++){
var row = rows[i];
var _row = {};
if(row.UOMRelatedUnit_AddItem !== F) {
RecordCount += 1;
_row["Name"] = $("#txtUnitOfMeasureSetName").val();
_row["Active"] = T;
_row["UnitOfMeasureTypeID"] = $("input[type='radio'][id='rblUnitOfMeasureType']:checked").val();
_row["BaseUnitID"] = $("input[type='radio'][id='rblUnitOfMeasureBaseUnit']:checked").val();
_row["RelatedUnitDisplayOrder"] = RecordCount;
_row["RelatedUnitName"] = row.UOMRelatedUnit_Name;
_row["RelatedUnitAbbreviation"] = row.UOMRelatedUnit_Abbreviation;
_row["RelatedUnitConversionRatio"] = row.UOMRelatedUnit_ConversionOfBaseUnits;
_row["UnitOfMeasureSetID"] = UnitOfMeasureSetID;
_UnitOfMeasureRelatedUnitData[i] = _row;
}
}
....
}
In my JQx Grid, I have at least four choices. For this issue, Ive only selected the 2 choice in the Grid and its AddItem value is True, everything else is False.
What do I need to change in my logic as I can not see it at this point?
EDIT 1
I overlooked the placement of RecordCount += 1;, I will try moving it to the end of the assignments and see what happens.
EDIT 2
The placement made no difference.
Maintain another variable for indexing your data like this
var index=0; // place this outside of for loop
_UnitOfMeasureRelatedUnitData[index++] = _row;
you don't need RecordCount += 1; .
you can get the rowscount by using _UnitOfMeasureRelatedUnitData.length
So, I have this function it takes two arrays of objects, workArr and arr, and match there id property and then add up the hours property to store in the workArr array.
var workArr = [];
var arr = [];
foundID = [];
function blah()
{
var i = 0;
var j = 0;
//Add up the hours
for( i=0; i < workArr.length ; i++)
{
for( j=0; j < arr.length ; j++)
{
//Makesure the id's match and the week is within the given time frame
//ALSO make sure the id hasn't already be visited
if( cond1 && !(isInArray(workArr[i].id)))
{
workArr[j].total = workArr[j].total + arr[j].hrs;
foundId.push(workArr[j].id);
}//end if id === id
}//end for j loop
}//end for i loop
printArr(foundId);
}//End blah()
//Checks if the given id has already be found
//returns true or false
function isInArray(id) {
return foundID.indexOf(id) > -1;
}
The problem is when I print out my already visited id array, once this function ends, there are duplicates in it, and there shouldn't be because if a duplicate is found it breaks the if condition and doesn't get added to the already found id's. So somehow my if condition isn't weeding out the already visited id's. Please help me solve this seemingly easy problem.
Solved with the help from the comments should be workArr[i] not workArr[j]
if( cond1 && !(isInArray(workArr[i].id)))
{
workArr[i].total = workArr[i].total + arr[j].hrs; // workArr[i]
foundId.push(workArr[i].id); // workArr[i]
}//end if id === id
I'm building a jQuery table sorting script. Yes, yes, I know there are plug-ins for that, but where's the fun in ridding someone else's coat tails (not to mention an entire lack of learning and understanding)?
So I've got a good sort going on for alpha types, I'm now working on a numeric sort.
So quick down and dirty. I get the column values and push them into an array:
var counter = $(".sort tr td:nth-child("+(columnIndex+1)+")").length;
for (i = 1; i <= counter; i++) {
columnValues.push($(".sort tr:eq("+i+") td:eq("+columnIndex+")").text());
}
I then sort they array:
columnValues.sort(function(a,b){
return a-b
});
I then check for unique entries (this was mainly for same names):
$.each(columnValues, function(i, el){
if($.inArray(el, uniqueColumns) === -1) uniqueColumns.push(el);
});
I then use the array as a list of keys to get the data from the table and push into another array. This is where the problem comes in. For names it works just fine, but with number (i.e. 3, 30, 36) it doesn't. With the sorted list starting with 3 it sees the 3 in the 30 and/or 36 and grabs it.
Here is what I have tried:
for (i = 0; i < counter; i++) {
var key = uniqueColumns[i];
$(".sort tr:contains("+key+") td").each(function(){
rowValues.push($(this).text());
});
}
And:
for (i = 0; i < counter; i++) {
var key = uniqueColumns[i];
$(".sort tr td").filter(function(i){
if($(this).text() === key) {
rowValues.push($(this).text());
}
});
}
Here is the fiddle running the code with the first set of code (which works better then the second):
UPDATE:
Also just tried this (still not working, works for initial sort but not subsequent):
for (i = 0; i < counter; i++) {
var key = uniqueColumns[i];
var found = false;
$(".sort tr:contains("+key+")").filter(function(j){
$(this).children().each(function(){
if ($(this).text() === key) {
found = true;
}
});
$(this).children().each(function(){
if (found) {
rowValues.push($(this).text());
}
});
});
}
Figured it out on my own. Decided on a completely different approach. I created a multidimensional array out of the table data, then created a custom sort function that works for both numeric and alpha data. Here is the function that gets the data, sorts the data, and rewrites the table.
function sort(column) {
var columnIndex = $(column).index(),
rowValues = [];
/* Get Data */
$(".sort tr").not(":first-child").each(function () {
var innerArray = [];
$(this).find('td').each(function () {
innerArray.push($(this).text());
});
rowValues.push(innerArray);
});
/* Sort Data */
rowValues.sort((function(index){
return function(a, b){
if (!isNaN(a[index])) {
a[index] = parseInt(a[index]);
}
if (!isNaN(b[index])) {
b[index] = parseInt(b[index]);
}
return (a[index] === b[index] ? 0 :
(a[index] < b[index] ? -1 : 1));
};
})(columnIndex));
/* Replace Data */
$(".sort tr").not(":first-child").each(function(i){
$(this).find("td").each(function(j){
$(this).replaceWith("<td>"+rowValues[i][j]+"</td>");
});
});
}