Items in array returning last one only - javascript

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.

Related

Javascript Array ES6 Undefined Error

I'm having trouble solving this question (the result is always undefined) and I am not sure what I'm doing wrong... any ideas?
Write a function that takes a number and generates a list from 0 to that number.
Use the function to assign a value to the myNumberList variable so that it has the value of a list going from 0 to 5.
Assign a value to the variable secondLastItem that should be the second last item of the myNumberList array.
function listMaker(listLength) {}
var myNumberList = null; // replace with number list created by listmaker
var secondLastItem = null; // replace with second last item
You can try the following way using ES6's spread operator (...):
function listMaker(listLength) {
return [...Array(listLength).keys()];
}
var myNumberList = listMaker(10);
// If you want the specified number passed as argument to be included as the last item in the array then push it.
myNumberList.push(10);
console.log(myNumberList);
Here is one way to write it:
function listMaker(number) {
var secondToLast;
var list = [];
for (var i = 0; i <= number; i++){
list.push(i);
}
secondToLast = list[list.length - 2];
return [list, secondToLast]
}
var list = listMaker(5)[0];
var secondToLast = listMaker(5)[1]
console.log(list + "\n" + secondToLast);
That is the snippet ^
Here is the jsfiddle

appendChild() fails when trying to append a value stored in an array

The following code deletes all children of a certain element, besides these listed inside the saved variable.
let rightCol = document.querySelector("#rightCol");
let saved = rightCol.querySelectorAll('._4-u2._3-96._4-u8');
let savedArr = [];
saved.forEach(()=>{
savedArr.push(saved);
});
rightCol.innerHTML = ''; // Delete all children before retrieving "saved" ones.
for (var i = 0; i < savedArr.length; i++) {
rightCol.appendChild(savedArr[i]);
};
The code fails with this error:
TypeError: Argument 1 of Node.appendChild does not implement interface Node.
Why the code fails?
The code you presented have 2 errors:
querySelectorAll should be executed on document.
you are pushing entire array in for each loop.
here is the working copy
let rightCol = document.querySelector("#rightCol");
let saved = document.querySelectorAll('._4-u2._3-96._4-u8');
let savedArr = [];
saved.forEach((s)=> {
savedArr.push(s);
});
rightCol.innerHTML = ''; // Delete all children before retrieving "saved" ones.
for (var i = 0; i < savedArr.length; i++) {
rightCol.appendChild(savedArr[i]);
};
You are pushing your collection array for each element in your selection return instead of the elements
Where your code state .each(()=> on the next line, the argument to push should be this
On each iteration of forEach you are adding the entire saved array to savedArr. You should instead add each item using the parameter passed into the forEach callback.
e.g.
saved.forEach((s)=> {
savedArr.push(s);
});
Not sure why you're copying the array over to another array here though..

Why does array contain only last value n times?

This function returns the same value in the array list.
For example if i=10, then my array should contain 10 different values, but it stores only the last value 10 times.
What is the problem in my code?
$scope.webTempIds=[];
$scope.wId={};
$scope.getIds=function(){
for(var i=0;i<$rootScope.retData.length;i++){
$scope.wId.ID=$rootScope.retData[i].WEBUI_TEMP_ID;
$scope.webTempIds.push($scope.wId);
}
return $scope.webTempIds;
}
$scope.wId={};
is changed every time. The array contains the reference to this object and hence when you change the value it changes the value in the array.
let obj = {};
let result = [];
for(let i = 0; i<10; i++){
obj.a = i;
result.push(obj);
}
console.log(result);
This happens because you use $scope for wId.ID outside of loop. Therefore your list items point to the same object.
Once you change $scope.wId.ID , the list $scope.webTempIds will be updated too.
To fix it make id local:
for(var i=0;i<$rootScope.retData.length;i++){
var wId = {
ID: $rootScope.retData[i].WEBUI_TEMP_ID;
}
$scope.webTempIds.push(wId);
}
As a side note: use Scope to bind application controller and the view. (inside the for loop you don't need scope)
As others have correctly pointed out, you end up with the last item in the array because the value that you push to the array is on the $scope and gets replaced with the new value each time.
To offer an alternative approach, you could use the Array.prototype.map function to return a new array prepopulated with just the id property values of each data item:
$scope.getIds=function(){
$scope.webTempIds = $rootScope.retData.map(
function(obj){
return obj.id;
}
);
}
This eliminates the need for any loops with temporary variables and any pushing to manually build up a new array from scratch.
$scope.getIds=function(){
$scope.webTempIds=[];
for(var i=0;i<$rootScope.retData.length;i++){
$scope.wId={};
$scope.wId.ID =$rootScope.retData[i].WEBUI_TEMP_ID;
$scope.webTempIds.push($scope.wId);
}
return $scope.webTempIds;
}

Remove item from array in JavaScript

Seen this question a lot, but cannot find something that's what i'm looking for.
onClick I push an item to an array I have, however, if there's 3 items in my array I don't want to be able to push items anymore.
var selectedData = [];
I set my empty variable.
var index = selectedData.indexOf(3);
I then get the index of my array which is 3
if (index > 3) {
selectedData.splice(index, 1);
}
Then within my if statement I say, if my index which is 3, is bigger then 3, then splice at index and remove one.
selectedData.push(TheThing);
I then push TheThing to my array if the if statement above isn't true.
However, I have a variable var arrayLength = selectedData.length; that grabs the length, and when I console log it, it starts at 0 and splices items anything after 4. Not 3.
Any idea what i've done wrong or misunderstood?
Thanks
More full example of my code
var selectedData = [];
myElement.on('click', function() {
var index = selectedData.indexOf(3);
if (index > 3) {
selectedData.splice(index, 1);
}
var arrayLength = selectedData.length;
console.log(arrayLength, 'the length');
});
So in short, onClick check my array and remove anything after the third that gets added into my array.
Do you want this to behave as a stack or a queue?
So your code here:
var index = selectedData.indexOf(3);
Is not grabbing the 3rd index - its grabbing the first index where it sees 3, or -1 if it doesn't. Replace your if statement with,
if (selectedData.length > 3) {
selectedData.pop() // removes last element (stack)
// or
selectedData = selectedData.slice(1) //remove first element (queue)
}
I think you need to try var arrayLength = selectedData.length -1;
You start at 0 like a normal array, but don't you start with an empty array?
Plus when you use .length, it returns the true count of the array or collection not a 0 index.
`
you can override push() method of your array like this:
var a = [];
a.push = function(){}
or like this
a.push = function (newEl){
if(this.length <3){
Array.prototype.push.call(this, newEl)
}
}
This is not complete example because push() can take many arguments and you should to handle this case too
var index = selectedData.indexOf(3); simply give you the index of the element of the array that has value 3
Example
selectedData = [ 0, 3 , 2];
alert( selectedData.indexOf( 3 ) ); // this will alert "1" that is the index of the element with value "3"
you can use this scenario
var selectedData = [];
myElement.on('click', function() {
//if selectedData length is less than 3, push items
});
This could work.
myElement.on('click', function() {
if(selectedData.length > 3){
selectedData = selectedData.splice(0, 3);
}
console.log(selectedData.length, 'the length');
});

For loop looping one too many times

I have some code:
var cart = [];
var items = [];
var cart_node = document.querySelectorAll('#tblItineraryModuleStayDetail > tbody > tr');
var cart_as_array = Array.prototype.slice.call(cart_node, 2); // start at item 3 (2)
for(var i=0;i<cart_as_array.length;i+=2) {
items.push(cart_as_array[i]);
}
Now, in the console if I type items I get:
So I expect the loop to go around once in this instance.
Here's my loop:
for(i=0; i < items.length; i++) {
// set vars
cart[i] = {};
var name = items[i].querySelector('.txtStayRoomDescription').textContent;
var price = items[i].querySelector('.tblItinPriceSummary tr td:last-child').textContent;
var brand = items[i].querySelector('.txtStayRoomLocation').textContent;
// add to object
cart[i].name = name;
cart[i].price = price;
cart[i].brand = brand;
// add to cart array
cart.push(cart[i]);
}
Which gives:
I expected a result with array cart containing one item object not two. But it has two identical objects.
What's going on here?
You're first setting the ith element of the cart array as your object, then also pushing it onto the end; this will put two copies in, as you see.
Edit for question in comments:
Let's go through your code line by line:
for(i=0; i < items.length; i++) {
// set vars
cart[i] = {};
After cart[i] = {} puts an empty object in the cart array at index i; if there was something there before, it will be overwritten, otherwise the array will simply be added.
// stuff setting properties removed
// add to object
cart[i].name = name;
cart[i].price = price;
cart[i].brand = brand;
Now, the object at cart[i] has received the attributes you constructed. The cart array now contains an object with these name, price, and brand attributes at position i.
// add to cart array
cart.push(cart[i]);
Now, in addition to the reference at i, you've pushed a second reference to the object stored at i on to the end of the array. This will produce the behavior you are observing: the object will be in the array twice.
I would recommend changing cart[i] = {} (and the associated code that adds properties of this object) to construct the object while it is stored in a local variable, then push it on to the array at the end of the loop.
At line 3 of your code you create an empty object in your array:
cart[i] = {};
then at line 14 you push that object into your array again:
cart.push(cart[i]);
You should instead just create an object, and push it at the end:
var item = {};
// ... add properties to item ...
cart.push(item)

Categories