.splice() keeps deleting the last item of an array - javascript

I made a function on my form where I can add multiple file inputs for multiple images by clicking a button, this is working as expected. Now when I try to delete an input field with .splice it keeps deleting the last item of the array that my input fields are in, not the input field with the matching index. I have been trying to fix this issue for hours now, I just can't seem to find a solution. I hope someone can tell me what I'm doing wrong.
This is the method for adding a new input field:
addInputField() {
i++
this.values.links.push({
id: i,
url: ''
});
}
this is the code for deleting an input field:
deleteInputField(index) {
this.values.links.splice(index, 1);
const items = this.values.links.filter(item => {
return item.id > index
});
items.forEach(function (item) {
item.id = item.id -1;
});
}
This is the button that deletes the input field:
<v-icon
medium
v-if="link.id > 0"
color="#FF0000"
class="ma-4"
#click="deleteInputField(link.id)"
>

If you want to pass the id (link.id), just use this function.
function deleteInputField(itemId){
this.values.links = this.values.links.filter(item => {
return item.id !== itemId;
});
}
This will loop through the array and return all but the one that has the same id as the itemId passed.
otherwise, just pass in the index from the v-for loop in the #click handler
deleteInputField(index) {
this.values.links.splice(index, 1);
}

links is an array of objects. You are not passing an index in that array, but an id inside the nested object.
<v-icon
medium
v-if="link.id > 0"
color="#FF0000"
class="ma-4"
#click="deleteInputField(link.id)" // Change to index (mostly taken from v-for loop)
>

From the definition of the splice method, the first parameter is start:
The index at which to start changing the array. If greater than
the length of the array, start will be set to the length of the array.
If negative, it will begin that many elements from the end of the
array (with origin -1, meaning -n is the index of the nth last element
and is therefore equivalent to the index of array.length - n). If
array.length + start is less than 0, it will begin from index 0.
If you step through the code you will realise that the id you are passing is not an actual index of the link in the links array but the id of the link which is greater than the length of the array

The ID is not the index if you need to pass the index to the deleteInputField function you can delete the desired input field by this.values.links.splice(index, 1);

Related

How to remove one value from a key in localstorage that has many values?

I've seen this question asked before but the solutions didn't help me hence why i've asked it again.
Currently, I am storing values into an array and that array is getting stored into localstorage.
This is the object
data.items -
0: {id: 190217270, node_id: 'MDEwOlJlcG9zaXRvcnkxOTAyMTcyNzA=', name: '3-Bit-CNC-Starter-Pack'}
1: {id: 187179414, node_id: 'MDEwOlJlcG9zaXRvcnkxODcxNzk0MTQ=', name: 'inb-go}
I have mapped through this and used 'name' as the value. I am calling this value through a button using this function
const favs = [];
function checkId(e) {
if (e.target.value !== ""){
if (!favs.includes(e.target.value)){
favs.push(e.target.value);
localStorage.setItem("name", JSON.stringify(favs));
console.log(favs);
document.getElementById("favsarray").innerHTML = favs;
}
}
}
and to remove the value from localstorage I am using this function.
function removeId(e, value) {
if (e.target.value !== "") {
favs.pop(e.target.value);
console.log(favs);
document.getElementById("favsarray").innerHTML = favs;
const stored = JSON.parse(localStorage.getItem("name"));
delete stored[value, e.target.value];
localStorage.setItem("name", JSON.stringify(stored));
console.log(stored);
}
}
Although the value is being removed from the array, it is not being removed from localstorage.
side note - I am calling this function with a separate button.
console log
array (item is gone)
[]
localstorage (the value is still there)
[
"Spiral-Up-Cut-Router-Bit"
]
But if I select another item to be added to localstorage, then the previous item gets removed.
UNFAVORITE - FUNCTION REMOVEid
[
"Spiral-Up-Cut-Router-Bit"
]
NEW FAVORITE - FUNCTION NEWId
[
"graphqless"
]
I hope this makes sense, I tried to add detail to it as best as possible.
Try to use localStorage.removeItem method to remove item from storage:
function removeId(e, value) {
if (e.target.value !== "") {
favs.pop();
// other code here
localStorage.removeItem('name'); // method to remove item from storage
}
}
UPDATE:
If an item is removed from array and we want to set this updated value to localstorage, then we can just update this value:
function removeId(e, value) {
if (e.target.value !== "") {
favs.pop();
console.log(favs);
document.getElementById("favsarray").innerHTML = favs;
const stored = JSON.parse(localStorage.getItem("name"));
delete stored[value, e.target.value]; // this code looks very fishy - charlietfl
localStorage.setItem("name", JSON.stringify(favs));
console.log(stored);
}
}
The easiest way is to just overwrite the item in localStorage. Once you remove the item from the favs array, call localStorage.setItem("name", JSON.stringify(favs)); again and you're done.
I am not sure whether this will help you but anyway I am sharing.
I don't understand this part of the abovementioned code:
delete stored[value, e.target.value];
What are you passing in the value and e.target.value? If it is the name ("Spiral-Up-Cut-Router-Bit") itself then the delete won't remove the value from the array. Usually, when you use the delete operator on the JS array you need to pass the index of the value, not the value itself.
Also, When you delete an array element, the array length is not affected. This holds even if you delete the last element of the array.
When the delete operator removes an array element, that element is no longer in the array.
You can refer to the above output image, when I deleted the array values using the value even though its output is true it does not delete the value from the array. But when I used the index value for the delete, it deleted the value from the array.
Note: The array just removed the value but did not clear the index.
Maybe, you should use splice to remove specific values from the array and store the new array into the storage.
Also, the delete operator works well with JS objects. If you want to read more about this you can go to this link.✌🏼
Delete using splice:
var trees = ['redwood', 'bay', 'cedar', 'oak', 'maple']; trees.splice(3,1); console.log(trees);
As suggested, use splice (which will also update the Array's length) to delete the entry from the Array.
const stored = JSON.parse(localStorage.getItem("name"));
const index = stored.indexOf(nameValue);
if (index !== -1) {
stored.splice(index, 1);
localStorage.setItem("name", JSON.stringify(stored));
}
See:

How to delete an item in a reverse sorted array in *ngFor in Angular

I'm trying to delete a specific item in the array based on the index. Currently, I have an issue deleting the first and last element of the array. When I try delete the last element, the first element gets deleted and vice versa.
Here's an excerpt from my code
HTML
<div *ngFor="let item of itemsList.slice().reverse(); index as i">
<ion-item>{{item.name}} <button (click)="deleteItem(i)">Delete</button></ion-item>
</div>
TS
itemsList = [{
name: 'Item 0'
}];
count = 0;
constructor() {}
addItem() {
this.count += 1
this.itemsList.unshift({
name: `Item ${this.count}`
})
}
deleteItem(index) {
console.log('Delete ', this.itemsList[index].name)
this.itemsList.splice(index, 1)
}
I created a working example using StackBlitz. Could anyone please help?
Use length - index - 1 in your splice to get the correct index of the normal array.
this.itemsList.splice(this.itemsList.length - index -1, 1)
I can't think of any reason why you wouldn't code it like this:
(click)="deleteItem(item)"
It's really a much better way to write code.

typescript remove object array through parent key

Lets say I have this variable
this.mylist.push([{key:{"test1":name,"test":desc,"hi i am a test":other,"none":type,"amount":0} }]);
This will be added to the array mylist
I want however on some condition to remove the current created list by deleting it through the unique key so
I want to splice the object array so the value will be removed to prevent duplicates
I tried
this.mylist.splice(this.mylist.indexOf(key), 1);
But did not work
i try to remove the array by getting the unique key which holds these child values
I also tried
this.mylist.splice(this.mylist.indexOf([{key}]), 1);
Someone who can help me out :(
CheckBox(values,values,values) {
this.bool = (this.mylist.indexOf(key) === -1);
if (this.bool) {
this.mylist.push([{key:{"key":key,"naam":naam,"beschrijving":beschrijving,"type":type,"aantal":aantal} }]);
}
else {
this.mylist.splice(this.mylist.indexOf(key), 1);
}
}
The function above is an event when a user clicks on a checkbox. When true the array must be filled with values. Else the array with the unique key must be removed to prevent duplicates
After the push statement, this.mylist will contain the array of arrays since you have pushed
[{key:{"test1":name,"test":desc,"hi i am a test":other,"none":type,"amount":0} }]
which is an array and you cannot access the array with the key (in this case you cannot access this.mylist[0], if the above array is added as first element, with this.mylist.indexOf(key))
One possible solution is you can make the type of mylist as object instead of array, then you can add elements to the Object like this
[{key:{"test1":name,"test":desc,"hi i am a test":other,"none":type,"amount":0} }];
this.mylist.key = {"test1":name,"test":desc,"hi i am a
test":other,"none":type,"amount":0} }
later you can use checkbox function like this
CheckBox(values) {
this.bool = (this.mylist.key === -1);
if (this.bool) {
this.mylist.key={"key":key,"naam":naam,"beschrijving":beschrijving,"type":type,"aantal":aantal};
} else {
delete this.mylist.key;
}
}
The logic behind Checkbox function seems incorrect, as the function will be checking if mylist contains a key, if it's not present then add the key to mylist and removes if its present. This logic does not properly handle the removing of duplicates if that's your final goal.

Angular 2 Filter array and append data

Quick one, I've 2 arrays/ objects. One contains all items the other contains selected ID's from the first array.
My question is, what is the best way to loop through both arrays find selected items from the second array and if they are true append data to first array. What I'm trying to do is append true to the first array if the ID's match.
For example something like this:
this.categories.filter(
category => {
this.user.category_ids.filter(
selected => {
if(selected == category._id) {
var data = {'selected': true};
category.push(data);
}
}
);
console.log(category);
}
);
At the moment I'm looping through categories object then through user.category_ids and if the ID's match I want to append selected: true to first array object, if this makes sense. I get error:
core.es5.js:1084 ERROR TypeError: category.push is not a function
Which I don't understand why. I've also tried splice.
Also to me this doesn't seem like best approach, because I've 12 items in first array. And if all 12 are selected, second array will have 12 items. So looping through 12 * 12 to me is little expensive, memory wise.
You can try something like this:
this.categories.map(category => {
category.selected = this.user.category_ids.indexOf(category._id) !== -1;
return category;
});
if (selected == category._id) {
category['selected'] = true;
/* you can build a interface for category
* or declare category as any
* then you can write it as the below
*/
// category.selected = true;
}
push is to add a new item to an array.
Kindly clarify if categories is an array of objects? If yes then you cant use push to add a new object since each element in the categories is an object and object don't have push method. Add new property to object instead using
category.selected=true or
category['selected']=true;
Assumptions:
this.user.category_ids is a 'array of objects' as you are using 'category._id'.
if ids match you want to add a key 'selected' whose value is true , to that object whose id is matched .
Solution:
- You are getting this error category.push is not a function because category is an object not an array ,push only works with array.
if(selected == category._id) {
category['selected']=true;
}

Javascript: How do I splice a value from an array with an index of 0?

I am attempting to remove a value from an array using splice. starting at 0 and ending at 0 splice, but it is not removing the value at index 0. I added a function getItemRow to check the species index which returns 0. I dumped the values of the array into an alert and it still outputs species which should of been deleted. invalidElement.splice(indexValue, indexValue); works as expected for indexes that are NOT 0. Why is this happening and how do I delete the value that has 0 index?
javascript code:
var invalidElement = new Array("species", "alias", "gender", "breeding", "birth_date");
//This function will be removed once fixed!!
function getItemRow()
{
var myPosition=-1
for (i=0;i<invalidElement.length;i++)
{
if(invalidElement[i]=="species") {
myPosition = i;
break;
}
}
alert(myPosition)
}
function validateElement(formId, element, selector, errorContainer)
{
getItemRow()//for testing purposes
//var indexValue = $.inArray(element, invalidElement);
var indexValue = invalidElement.indexOf(element);
alert(element);
$.ajax({
type: 'POST',
cache: false,
url: "validate_livestock/validate_form/field/" + element,
data: element+"="+$(selector).val(),
context: document.body,
dataType: 'html',
success: function(data){
if (data == "false")
{
$(errorContainer).removeClass('element_valid').addClass('element_error');
invalidElement = element;
alert(invalidElement.join('\n'))//for testing purposes
//alert(indexValue);
}
else
{
$(errorContainer).removeClass('element_error').addClass('element_valid');
invalidElement.splice(indexValue, indexValue);
alert(invalidElement.length);//for testing purposes
alert(invalidElement.join('\n'))//for testing purposes
}
}
});
}
$("#species").change(function(){
validateElement('#add_livestock', 'species', '#species', '.species_error_1')
});
I think you want splice(0, 1).
The second argument is how many you want removed...
An integer indicating the number of old array elements to remove. If howMany is 0, no elements are removed.
Source.
Splice can work in two modes; to remove or insert items.
When removing items you'll specify two parameters: splice(index, length) where index is the starting index, and length is a positive number of elements to remove (fyi: passing a "0", as in your example, does nothing--it's saying "remove zero items starting at index"). In your case you'll want:
invalidElement.splice(indexValue, 1); // Remove 1 element starting at indexValue
When inserting items you'll specify (at least) three parameters: splice(index, length, newElement, *additionalNewElements*). In this overload you normally pass 0 as a 2nd parameter, meaning to insert the new elements between existing elements.
var invalidElements = ["Invalid2", "Invalid3"];
invalidElements = invalidElements.splice(0, 0, "Invalid1");
There's also a convenience function for removing the first element in an array:
array.shift();
See: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/shift.
Mozilla Dev Center - Array.splice states that the second parameter is 'howMany' elements to remove.
I'm not sure how your code worked when it passed in the indexValue as the number of elements to remove, unless you were removing from the end of the array.

Categories