React hooks -to reinitialise array to empty - reactjs

i do have one state written as
const[checkboxIds,setCheckboxIds]=useState([])
and i have one useEffect as
useEffect(()=>{
if (!isEmpty(currentData)) {
currentData.forEach(id => {
checkboxIds.push(id);
});
setCheckboxIds(checkboxIds);
}
},[currentData])
and i am showing the count as {checkboxIds} and is displaying correct
Again i do have 4 tabs like alphabets,colors,animals and cars,when i click on each tab current Data changes ,so checkboxIds count also should change. its changing, but its incrementing previous count as well
For example if i do have 10 objects in alphabets, its showing count as 10 in the initial page load and when i click on colors(it have 5 objects),its showing count as 15 (it should show only 5) and when i click on animals(it have 10 object) ,its showing count as 25(it should show its count as 10)
so i understood somwhere setCheckboxIds should be reinitiated ,but for me its not working

I think you need to update your useEffect to
useEffect(()=>{
if (!isEmpty(currentData)) {
const updatedCheckboxIds = [];
currentData.forEach(id => {
updatedCheckboxIds.push(id);
});
setCheckboxIds(updatedCheckboxIds);
}
},[currentData])
This way on each effect it will create a new checkboxIds array and will push the ids into it.

Related

Showing the new row in react-table on the current page

I have been playing with ReactTable v7 for a while and have encountered the following problem: when the table is sorted and uses paginator sometimes adding (or editing) a row causes it to be outside the current page.
You can see the problem here:
https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/material-UI-kitchen-sink
Sort the table by First Name
Press add
Enter a record with First Name "zzzzz"
The record is added but is currently hidden which confuses users.
Is there a "standard" way to fix the issue? Am I missing something?
In v6 I have done a workaround for it:
React.useEffect(() => {
if (editedElementId && reactTable) {
const { data } = reactTable.props;
if (data && data.length > 0) {
const internal = reactTable.getResolvedState();
let position = -1;
internal.sortedData.forEach((row, i) => {
if (row._original.id === editedElementId) position = i;
});
if (position >= 0) {
const pageNumber = Math.floor(position / pageSize);
setPage(pageNumber);
} else {
alert.info("Element not visible");
}
}
}
}, [editedElementId]);
...
<ReactTable
ref={(r) => {setReactTable(r);}}
...
But maybe there is a bulit-in way to achieve it?
There is not currently a way to only sort the elements which are currently being displayed, no.
React Table v7's useSortBy hook sorts the entirety of the input data array, so sorting by First Name descending (A->Z) naturally places 'ZZZZZZ' at the end of the list, which will be hidden due to pagination. The v7 way of doing it would probably be similar to what you are doing already, using the exposed properties from the useTable hook instead of reactTable.resolvedState() and etc. Another way to do it would be to write your own custom sortBy method and only sort the items [0...n] where n is the number of currently displayed items.
As a side note, since the autoResetSortBy property is true by default in the example you linked, the step of sorting on First Name is irrelevant -- since the function which adds a new user to the list mutates the data array, the sorting method is reset. That function appends the new user to the end of the list, so it will always be on a new page, even if the "Rows per page" option is set to "All". Both issues can be fixed by setting autoResetSortBy to false, and changing the pageSize in addUserHandler.

In angular Pushing objects in array getting duplicated

EventEmitter in service
toshoppinglist = new EventEmitter<Ingredients[]>()
Emitting method
toshoppinglist() {
this.slservice.toshoppinglist.emit(this.item.ingredients);
}
ingredients : Ingredient []
Subscribing to emit and pushing emitted values
this.slservice.toshoppinglist.subscribe(
(ingredients: Ingredients[]) => {
for (let item of ingredients) {
this.ingredients.push(item);
}
}
)
Now, when pushing new values into the array,it's getting duplicated.It's work fine for first pushing,but getting duplicated after that.
Ok, first in my opinion you use wrongly EventEmitter. Eventemitters used only inside DUMB components to raise an event to Smart component. And not inside services. Second, yes it will be duplicated. Imagine you have button which will raise this eventemitter and we emit the same ingredient every time. Inside the subscribe you didnt check that new ingredient are different. And because you use list, it doesnt care if you have duplicates. So a solution is to add to the subscribe a check that it will push only - new- ingredients.
You need to add a check in your subscription function.
currentIngredients: Ingredients[];
this.slservice.toshoppinglist.subscribe(
(ingredients: Ingredients[]) => {
> //here you need the if condition comparing it to a current
> ingredients array to see if it exists or not
for(let item of ingredients) {
if(this.currentIngredients.includes(item) {
// in this case you should increment the count of ingredient
currentIngredients[item].count++;
}
else {
// this should only add non-existing items ingredients list
this.currentIngredients.push(item)
}
}
}

React.js - TODO List striking through task text and sorting not working

I am having a hard time with a React.js project. I have a TODO list and there is a function to mark a task as done. I have a button next to each and every task and if I click on it the following function will be called.
crossLine(key){
const currentTaskArray = [...this.state.task]
const deletedItems = currentTaskArray.filter(deletedItem => deletedItem.key == key);
const taskAfterDeleted = currentTaskArray.filter(deletedTask => deletedTask.key !== key);
this.setState({
task: [taskAfterDeleted,deletedItems]
})
};
I first need to strike this item ( just html strikethrough) so that I know it is done. After that, it should be removed from the array and should be moved to the bottom of the list and the rest of the items should be moved accordingly. The following function does not seem to contain anything inside deletedItems.
you can find the full project at https://codesandbox.io/s/jovial-gauss-s12bf.
.filter() returns an array of the remaining elements. Therefore, taskAfterDeleted and deletedItems are both arrays. You'll need to spread them in your new state:
[...taskAfterDeleted, ...deletedItems]

Sort an array of objects based on another array of objects in angular 7

I know it's been asked million+1 times. But i've found no help in those questions/answers.
I have 2 arrays of 2 different objects one string property is used to uniquely identify them. This would be the key to sort about, but said object prop names are not equal (accessValue, modifiedOption). But their values are!
Object1: { ... accessValue, ... };
Object2: { ..., modifiedOption, ... };
array1:Object1[];
array2:Object2[];
I'd like to sort array1 based on the object indencies of array2.
So all of array1 items'd be in the same order as array2.
These two arrays are used to model a connected dropdown selection system, which can be added to are removed from. The Addition is screwing me over (lastly added item is appended to the first place and not the last) probably because of filter below?
What I use to add new dropdowns:
addFieldRow() {
this.fieldRows.push(0); // since desired selection is not known yet but need to populate the array that represents the 1st selection so a 2nd main selection dropdown will appear on screen
...
}
public onSelect() {
// if a selection is happened check the values of editOptions (contains data about all main selectable options)
this.fieldRows = this.editOptions.filter(
option => this.selectedOptions.some(el => el.modifiedOption === option.accessValue)
);
this.disableSelected(); // disable already selected items (not related to my issue)
this.optionSelected = true; // this is just for button disabled toggle
}
So either i need to figure out my addRow logic (if it has any flaws) or implement a sorting utility to make sure that the objects of fieldRows are in the same order as selectedOptions' -> since this models the selection directly.
I cannot really add a stackblitz since it's hard to model my current state.
Okay I am a complete idiot!
Since I know the current index (since i am looping through fieldRows).
All I had to do is replace this:
public onSelect() {
this.fieldRows = this.editOptions.filter(
option => this.selectedOptions.some(el => el.modifiedOption === option.accessValue)
);
With this:
public onSelect(index) {
this.fieldRows[index] = this.editOptions.find(option => this.selectedOptions[index].modifiedOption === option.accessValue);
this.disableSelected();
this.optionSelected = true;
}
Now it works correctly.

How to limit array to 5 items and put new item at top of list

I want to print a list of scores with a limit of 5. The newest score at the top. The app is a simple timer which the user can hold down the button, release, then tap a Done! button to set the score in the state. Currently the scores printed on the app from scoreArray are duplicated multiple times exponentially when click the Done! button.
The code currently is what I've been advised to try but it doesn't work.
Setting the state with the score:
onSubmit() {
this.setState(prevState => ({
scoreArray:[this.state.scoreArray.concat(ms(this.state.time,{verbose: true})), ...prevState.scoreArray],
time:0,
submit:true
}));
And in the render I have this:
{this.state.scoreArray.map(function(item,i){
return (i < 5) ? <Text key={i}>{item}</Text> : null}).filter(x=>x)
}
I expect the scores list to populate the newest score at the top, pushing the older scores down the list and these older scores disappear when the limit of the scores is > 5.
You are again providing an array inside the "scoreArray", hence the nested structure. Try changing the setState call to this:
`
this.setState(prevState => ({
scoreArray:[ms(this.state.time,{verbose: true}), ...prevState.scoreArray],
time:0,
submit:true
}));
`
This way you are adding a new element on top of your array and then spreading the previous elements in the new array.

Resources