Trying to build remove function, going wrong - javascript

I am trying to build a remove function to my weather app, the function working only on the last place in the array I tried via MAP loop but I get too many renders errors.
This is the sandbox URL of my project -
https://codesandbox.io/s/kind-platform-cymzx?fontsize=14&hidenavigation=1&theme=dark
I don't get it if ts working on the last one why won't you on the first one?
(with for loop it's letting me edit only the last one, in map loop, it's saying too many renders)
Guys I stuck on this for 3 days now please help.

Here is your function:
let deleteFunc = (name) => {
allFavorite.map((item, index) => {
console.log(item.name);
let updatedFavorite = allFavorite.filter((item, i) => (item.name = name));
setAllFavorite(updatedFavorite);
});
};
First problem is that you mutate item.name in filter function.
Second problem is that you are seting state inside the map, so you call setAllFavorite for each item in your allFavorite.
Your goal here is to construct new state first, and then apply it in one go, like this:
let deleteFunc = (name) => {
// this will return new array where item with name `name` removed, and will pass it into state setter
setAllFavorite(allFavorite.filter((item) => item.name !== name));
};

Related

'splice' instead of 'filter'

I have a field for entering tags. It is also possible to remove tags.
And here I have a question.
My deletion code is below. Tags can be deleted one at a time, in any order (first, last, somewhere in the middle, it doesn't matter).
const deleteTag = (index) => {
setTags((prevState) => prevState.filter((tag, i) => i !== index));
};
But I would like to use 'splice' instead of 'filter'. With the same functionality.
Tell me how to do it
Splice's first argument is the item index, and the second argument is how many items you want to delete from that index.
const deleteTag = (index) => {
setTags((prevState) => {
prevState.splice(index, 1)
return [...prevState]
});
};
UPDATE
If you are using <StrictMode> the setState will execute twice and will delete two items instead of one.

UseState how to set an Array back to empty?

I'm trying set clickFavIconArray back to an empty array with the hook.
Basically, the setClickFavIconArray has a list of IDs the showFavIcon() checks that ID and if it contains the same ID I want to remove it from the array and update the setClickFavIconArray to the new Array.
However, it just seems to be adding on to the original clickFavIconArray no matter what. Is there a way to clear the clickFavIconArray state back to an [] empty array?
Some help here would be awesome.
const [clickFavIconArray, setClickFavIconArray] = useState([]);
function showFavIcon(id){
if (clickFavIconArray.includes(id)) {
const newArray = clickFavIconArray.filter(item => !id.includes(item))
setClickFavIconArray(newArray)
}
setClickFavIconArray([...clickFavIconArray, id])
}
Simply pass the new value of empty array to setClickFavIconArray():
setClickFavIconArray([])
To make sure that the id is not immediately added to the array again, add a return statement inside the if-statement.
const [clickFavIconArray, setClickFavIconArray] = useState([]);
function showFavIcon(id){
if (clickFavIconArray.includes(id)) {
const newArray = clickFavIconArray.filter(item => !id.includes(item));
setClickFavIconArray(newArray);
return; // make sure that the next line is not executed
}
setClickFavIconArray([...clickFavIconArray, id])
}
There are two issues with the code
filter function seems to be invalid it should be replaced with
clickFavIconArray.filter(item => id != item)
You are adding id again to the array with this
setClickFavIconArray([...clickFavIconArray, id])
If you want to remove id, there is no need for this line in your code.
However you can always set clickFavIconArray to an empty array state using this code:
setClickFavIconArray([])

ngx dropdown list get selected values

I am trying to use ngx dropdown list like this:
<ngx-dropdown-list [items]="categoryItems" id="categoriesofdata" [multiSelection]="true"
[placeHolder]="'Select categories'"></ngx-dropdown-list>
And I am getting all selected values like:
get selectedCategories() {
const items = this.categoryItems.filter((item: any) => item.selected);
return items.length ? JSON.stringify(items.map(item => ({
value: item.value
}))) : '';
}
and output looks like:
[{"value":"Surname"},{"value":"Address"}]
I want to get only for example Surname instead of value and Surname.
[0].value
How Can I do this?
Should I use for loop or is better option?
I think you're almost there, in fact you're doing a little too much. Your map function should just return the value you are interested in rather than creating a new structure.
get selectedCategories() {
const items = this.categoryItems.filter((item: any) => item.selected);
return items.length ? JSON.stringify(items.map(item => item.value)) : '';
}
Edit:
And as a personal preference, I would refactor to something like this:
get selectedCategories() {
if (!this.categoryItems.length) {
return '';
}
const surnames = this.categoryItems
.filter(item => item.selected)
.map(item => item.value);
return JSON.stringify(surnames);
}
I prefer to get out of a function early in the case where no further processing is required. And I would return the result of chained filter and map functions into a new surnames variable. The named variable signals the intention of the code, and keeps the array logic together.
This is just my preference though. Your code was almost there functionally.

slice happens in the code but it doesnt update in the UI

there are three drop down menus in the initial state.
after I select the first drop down the second drop down values gets loaded
after I select the second drop down values.
a new set of drop down loads.
when I select remove button of the second set.
it doesnt remove that set but it removes the first set.
when I debugged removeSelectedValue method there slices are happening correctly but its not updating in the updating
can you tell me how to pass the queryComponents values so that it will update in the UI.
can you tell me how to fix it.
so that in future I will fix it myself.
providing my relevant code snippet and sandbox below.
all my code is in demo.js
https://codesandbox.io/s/4x9lw9qrmx
removeSelectedValue = index => {
console.log("removeSelectedValue--->", index);
let seletedValues = this.state.queryComponents;
seletedValues.splice(index, 1);
console.log("spliced Values--->", seletedValues);
this.setState({ queryComponents: seletedValues });
};
render() {
let queryComp = this.state.queryComponents.map((value, index) => {
return (
<AutoCompleteComponent
key={index}
value={value}
index={index}
valueSelected={this.getSelectedValue}
removeSeleted={this.removeSelectedValue}
/>
);
});
return <div>{queryComp}</div>;
}
When you do let seletedValues = this.state.queryComponents;
you're creating a reference to that variable, instead of making a copy.
You need to make sure you replace your state with a new object/array for the re-render to happen.
Please try this:
removeSelectedValue = index => {
this.setState(prevState => ({
queryComponents: prevState.seletedValues.filter((a, i) => (i !== index));
});
};
That filter function is equivalent to the splice you were using, but returns a new array instead of modifying the original one.
On the other hand, I 'm passing setState a function that uses prevState making the code shorter.

Splice removes only last element in array

I'm having a small issue with React (still new to it). I have an array of Results. These Results have nested Bookings, also in an array, and the latter is what I'm manipulating.
When User creates Booking, everything goes as expected - findIndex gets the correct Result element and modifies its Bookings array accordingly.
However, when I want to "Unbook", it only finds the last Result in the array, and findIndex is always -1 (so I haven't even gotten to the Bookings part, because the Result index I get is wrong).
The code is similar, my items all have unique keys, and I don't understand what could be the problem (using Alt as Flux implementation)?
Here is what happens on Create:
onCreateBookingSuccess(data) {
let resultIndex = this.results.findIndex((result) => result.id === data.id);
this.results.update(resultIndex, (result) => result.bookings.push(data));
toastr.info('Booked! User will receive notification.');
}
And on delete:
onDestroyBookingSuccess(data) {
let resultIndex = this.results.findIndex((result) => result.id === data.id);
var myBooking;
this.results.map((result) => {
myBooking = result.bookings.findIndex((booking) => booking.id === data.booking);
});
this.results.update(resultIndex, (result) => result.bookings.splice(myBooking,1));
toastr.warning('Unbooked! User will receive notification.');
}
My object:
<Result key={result.id} id={result.id} bookings={result.bookings} />
As I mentioned, the first operation goes as planned, everything is modified as it should. The issue with the second op starts from the very beginning, when resultIndex returns -1.
The problem seems to be here:
var myBooking;
this.results.map((result) => {
myBooking = result.bookings.findIndex((booking) => booking.id === data.booking);
});
You’re always assigning to myBooking, even when the index is not found (-1) after having already found it, so it’s equivalent to this.results.last().bookings.findIndex(...). Really you only want to get the (first?) value that’s not -1:
var myBooking = this.results.map((result) => {
myBooking = result.bookings.findIndex((booking) => booking.id === data.booking);
}).find((index) => index != -1);
Also, consider renaming myBooking to better indicate it’s an index and not the actual record.

Categories

Resources