Remove specific value in array and add new updated value - reactjs

I'm trying to remove existing specific value in an array before adding or push another updated value. My purpose is to avoid duplicate same id and value to array. What i'm trying to achieve is when onchange triggered check if that value is existing on array and if exist remove the old one and push the update value.
const [array, setnewarray] = useState([]);
function handlechangeselected(val,id){
var newarray = array;
const valueToRemove = id;
newarray.filter(item => item.id === valueToRemove);
newarray.push({ value: val, id:id });
setnewarray(newarray);
}
<select
onChange={(e) => handlechangeselected(e.target.value,row.ID)}
>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>

The first issue is that filter doesn't modify the array, but rather returns a new array. You're not using the returned array, so newArray is unchanged.
The other issue is that filter filters out out any values that return false from your callback, so you want your filter to return true for any items that don't match valueToRemove (in other words, !== instead of ===). You can also use .concat to chain after array.filter.
Here it is, simplified a bit:
const [array, setNewArray] = useState([]);
function handlechangeselected(value, id){
const newArray = array
.filter(item => item.id !== id)
.concat({ value, id });
setNewArray(newArray);
}

Related

Cannot remove duplicates

I follow this question to achieve the result Remove duplicate values from JS array. Also, I read a lot of stuff like https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set, but unfortunately, values are still duplicated
.map((devicedetails, index) => {
return (
<option key={index} value={[...new Set(devicedetails.groupName)]}>
{[...new Set(devicedetails.groupName)]}
</option>
);
});
Note: I thought it's clear but **devicedetails ** consists of JSON with multiple values, not just one
Result:
Updated:
before return: var list = [];
filteredList.map((devicedetails, index) => {
list.push(devicedetails.groupName);
if (list.length === index + 1) {
var data = [...new Set(list)];
data.forEach((element) => {
return <option value={element}>{element}/option>;
});
}
})
But in this case, is returning nothing in option but it's working I check via console.log(element)
You need to remove duplicates of the whole array and then map over the version with duplicates removed.
[...new Set(myArray)].map((devicedetails, index) => (
<option key={index} value={devicedetails.groupName}>
{devicedetails.groupName}
</option>
));
Instead of looping over devicedetails, outside of the return, create a modified array using the spread syntax and set it as a new variable. Then loop over that instead.
e.g.
const array = ['test', 'testing', 'test', 'test1234', 'testing']
const updatedArray = [...new Set(array)]
console.log(updatedArray)

How to make function run with newly selected option React

I have created a function to calculate the winner between the two selected pokemon. However, instead of using the newly selected option, it is using the previously selected option.
Here is my function:
function selectedWinner(){
console.log(pokemonName+' '+pokeOneTotal);
console.log(pokemonName2+' '+pokeTwoTotal);
if(pokeOneTotal>pokeTwoTotal){
setPokemonWinner(pokemonName);
}else if(pokeOneTotal<pokeTwoTotal){
setPokemonWinner(pokemonName2);
}else{
setPokemonWinner("Draw");
}
}
I have set it so that it is called in the different select functions, which are on click functions, here is one as an example:
function optionOneSelected(){
console.log('selected');
axios.get('https://pokeapi.co/api/v2/pokemon/'+ pokemonOne.current.value)
.then((res)=>{
let data=res.data;
console.log(data);
let type = data.types[0].type.name;
let id = data.id;
let height= data.height;
let weight = data.weight;
let name = data.forms[0].name;
let hp = data.stats[0].base_stat;
//console.log(type)
setPokemonType(type);
setPokemonId(id);
setPokemonHeight(height);
setPokemonWeight(weight);
setPokemonName(name);
setPokemonHp(hp);
let sum=0;
sum= data.stats[0].base_stat+ data.stats[1].base_stat+ data.stats[2].base_stat+ data.stats[3].base_stat+data.stats[4].base_stat+data.stats[5].base_stat;
setPokeOneTotal(sum);
let pokemonOneDataList = [
data.stats[0].base_stat, data.stats[1].base_stat, data.stats[2].base_stat, data.stats[3].base_stat,data.stats[4].base_stat,data.stats[5].base_stat
];
let labels = [
'hp', 'Attack', 'Defense', 'Special Attack', 'Special Defense', 'Speed'
];
setPokemonOneData(pokemonOneDataList);
setDataLabels(labels);
selectedWinner();
})
}
Here is the function where is it called:
<select onChange={optionOneSelected} ref={pokemonOne} onLoad= {() => this.optionOneSelected()}>
<option selected="selected" value="charmander">
charmander
</option>
{pokemonOptions}
</select>

Filter table with select options (check if column is number or null) in React

I am new at React and I am stuck.
I have a table with data from database. I want to filter that table with a select dropdown. I have mulitple "select-fields" that works fine, because the value in the dropdown matches the exact value in database. But now I just want to check if the column value is null or a number.
In my select options I just want three options (see left picture):
All (Show all result. It is working)
Missing number(is null in Database. Not working)
Has number(Not working)
So the value in the table column (see right picture) I want to filter is either a number or null.
Here is my code so far:
const [filteredData, setFilteredData] = useState([]);
//Column in table:
{
Header: () => (<div>TableHead</div>),
accessor: "accessorToDatabase",
Cell: (props) => { return <div>{props?.cell?.value}</div> }
}
// The select dropdown and the table
<Col>
<Label>Select Dropbox</Label>
<Input type="select" onChange={handleChange('id', 'description')}>
<option>All</option>
<option value="false">Missing number</option>
<option value="true">Has number</option>
</Input>
</Col>
<Table columns={columns} data={filteredData} HandleRowData={HandleRowData} />
//The filter functions
const handleChange = name => ({ target: { value } }) => {
filter[name] = (value === 'All') ? null : value
if (checkProperties(filter)) {
var filtered = state
}
else {
var filtered = handleFilter(state, filter)
}
setFilteredData(filtered)
}
const handleFilter = (arr: Object[], filters: Object) => {
const filterKeys = Object.keys(filters)
return arr.filter(eachObj => {
return filterKeys.every(eachKey => {
if (!filters[eachKey] || !filters[eachKey].length) {
return true
}
})
})
}
I have tried with something like this, for looping through all values in the column, but without no success:
state.map(x=>((
x.id> 0 ? x.id : null)))
.map is used to transform one array of values/objects to another array with the same length but with transformed values/objects. What you want to use is .filter, which removes elements from an array but maintain the element structure.
To keep the ones that does not have an id:
array.filter(x => !x.id)
To keep the ones that has an id that is a number:
array.filter(x => !isNaN(x.id))
A simple Array.prototype.filter should do the trick:
//removes all entries with an id of `0 || null || undefined`
state.filter(entry=>!!entry.id)
//removes all entries with an id of `null || undefined` but keeps the 0
state.filter(entry=>!!entry.id || entry.id === 0)
I would not recommend using isNan: as it internally tries to parse strings to check if they are numbers you might end up with some unexpected behaviors. It also goes wild with booleans, null and undefined.
See this link for more info:
https://www.w3schools.com/jsref/jsref_isnan.asp
EDIT
Rereading your question it looks like you want
all items
items with an ID of type number
items that are not numbers
Here is how you could implement that
const [items,setItems]= useState(someItems)
const [filter, setFilter]=useState('all')
function handleChange(e){
setFilter(e.target.value)
}
const filteredItems = items.filter(item=>{
if(filter === 'number')
return typeof items === 'number'
if(filter === 'no-number')
return typeof item !== 'number'
return true
})
return (
<React.Fragment>
<select onChange={handleChange}>
<option value='all'>All</option>
<option value='no-number'>Missing number</option>
<option value="number">Has number</option>
</select>
<Table columns={columns} data={filteredData} HandleRowData={HandleRowData} />
</React.Fragment>
)
Change the elements with the specific library you are using and you are good to go
I would recommend not using NaN, as it tries to parse strings. Instead, you can create an array and use the map function, in combination with the filter function.

display array values into select option tag in react js

I am trying to display array values into select tag, but all the array values displayed as single value. Please see below logic I added. Data is dynamic, I am getting data from backend like this ["Sankranti", "Sankranti 1"].
const [eventNameList, setEventNameList] = useState([])
var eventList = eventNameList.length > 0 ?
eventNameList.map((item,i) => {
console.log('list: ', item)
return (
<option>{item}</option>
)
})
:
'No Events'
<select>
{eventList}
</select>
please find below console screen shot
It looks that your list is nested inside another array so to fix this you could use flatMap instead of map
or you could just iterate throw the first element inside your nested array
const [eventNameList, setEventNameList] = useState([])
var eventList = eventNameList.length > 0 ?
eventNameList[0].map((item,i) => {
console.log('list: ', item)
return (
<option>{item}</option>
)
})
:
'No Events'
<select>
{eventList}
</select>

Can I pass object of data in select option

Can I pass object of data in select option ?
I'm displaying name in select option & I'm using ID in value.
After some option is selected, I want to display the selected option. Since the value is ID, I can't display name.
How can I solve this?
This is my code:
{
Makes.hasData ?
(_.map(Makes.data.data, (make, index) => {
return (
<option key={index} value={make.id}> {make.make}</option>
);
}))
: ''
}
Thank You
On your select option you will have onChange in that you can search in the array for the obejct with a given id using lodash's find method
handleChange(e) {
var id=e.target.value
var value = _.result(_.find(Makes.data.data, function(obj) {
return obj.id=== id;
}), 'make');
console.log(value)
}

Resources