handling state during onChange event - javascript

handling state during onChange event, aray of mutiple objects , and objects with multiple key Value pair, dunring onChange how to handling and update the state with out overwrite any object or value of objects
// state exits with array of multiple objects and objects with multiple key value pairs.
const [employement, setEmployement] = useState([{title:"react_js", exp:"good", id:1}, {title:"laravel", exp:"master", id:2}, {title:"node_js", exp:"well", id:3},{title:"flutter", exp:"mid", id:4}])
// method to change the input value
const handleChange =(id, inputValue)=>{
// need help how to change the single value , without any over in object value and without overRIght whole object in an array .
employement.filter((emp) => {
if (emp.id === id) {
setEmployement([{ ...emp, job_title: inputValue }]);
}
});
// but upper logic not working correctly, this code need improvement
}
// map method to iterate the array
employement.map(singleEmp=>{
<input type="text" value={singleEmp.title} onChange={(e)=>handleChange(singleEmp.id, e.target.value)}/>
})
// last this is dummy structure of my real code, real code is long enough but same as it, thank you for your any suggestions

Try this as your handleChange method
// method to change the input value
const handleChange = (id, inputValue) => {
setEmployement((prevstate) => {
return employement.map((emp) => {
if (emp.id === id) {
return { ...emp, title: inputValue };
}
return emp;
});
});
};
Code sandbox => https://codesandbox.io/s/nice-greider-0efof?file=/src/App.js

Related

Add or replace object to array with dynamic key name in javascript (reactJS)

I have a number of select, when i onChange them i want to keep in componente state the selected value
the onChange function i call do something like this:
function validateVariations(event) {
console.log(event.target.value);
console.log(event.target.name);
setSelected((selected) => [
...selected,
{ [event.target.name]: event.target.value },
]);
.... //OTHER PROCESS
}
basically i add to state select an object like:
[{Weight: "250"},{Pack: "Tin"}]
but using it a couple of time it fill up with the history changes like this:
[{Weight: "250"},{Weight: "500"},{Weight: "250"},{Pack: "Tin"}, {Pack: "Card"}]
so i need to add the { [event.target.name]: event.target.value } only if its not present an object with key [event.target.name], otherwise i need to replace it.
i tried using findIndex but im not able to reference to a dynamically named key
this is not working:
var i = data.findIndex(function(e) {
return e.[event.target.name] == event.target.name;
});
any elegant solution?
Based on the format of your data, you could use this:
var i = data.findIndex(function(e) {
return Object.keys(e)[0] === event.target.name;
});

Array type variable changes to string on setState

How can I get the state and array to work consistently?
The results are so confusing and inconsistent.
This is state:
this.state = {
tutorSubjects: [],
};
This is setting state; the first console.log logs the subject in an array, the second logs and empty array:
const name = target.name;
if (name === "tutorSubjects") {
let subjects = this.state.tutorSubjects.concat(value);
console.log(subjects)
this.setState({
tutorSubjects: subjects
}, console.log(this.state.tutorSubjects))
}
this handles submit and logs th subject as a string without the array:
handleSubmit = e => {
console.log(this.state.tutorSubjects)
}
My main goal is to send an array to the server, and now it's sending a string.
I have not idea why, but now that I have changed the state to subjects and updated state like below, It works perfectly.
if (name === "tutorSubjects") {
let subjects = this.state.subjects.concat(value);
console.log(subjects)
this.setState({
subjects
}, console.log(this.state.subjects))
}
The callback argument to setState should be a callback function but you're not supplying it that way, instead you're evaluating console.log(...) immediately and displaying that before setState gets called.
Fix it by ensuring it runs after:
this.setState({ subjects }, () => console.log(this.state.subjects));
Your original code is roughly equivalent to:
let v = console.log(this.state.subjects);
this.setState({ subjects }, v);
Where clearly that's out of order when expressed that way.

knockoutobservable value update only inside the clicked function but not in the UI in Type Script code

please I am stuck in this problem from yesterday without fixing :
when I click the knockout checkbox, the button will send the true-false value and by the click, event reach the driverSelected function, there will print the item and it works perfect, but I need to filter the selected data with other information, but it not changes is empty
Html
<input type="checkbox" data-bind=" checked:isSelectedDriver , click:$root.driverSelected()" />
this.assignedDriver = ko.observable(new Model.Driver());
view model function
driverSelected = () => {
return (item, ui: any) => { // lambda expression
if (item.isSelectedDriver()) {
this.assignedDriver = ko.observable(item.driver);
this.assignedDriver.valueHasMutated;
console.log(this.assignedDriver());
return true
}
}
}
the result in HTML it shows me the default which empties without errors even when I delete the attribute value ( wbc_name) is show me [ object object }
You are reassigning what this.assignedDriver is, instead of setting the value in your JS.
To assign a value to an observable, you call the observable with the value that you want to set it to, for example:
this.thing = ko.observable(5); // Observable created, initial value 5.
this.thing(42); // Sets the value of the observable, value is now 42;
See the documentation that explains this.
In this case, the fix would be to modify the first two lines in the if-statement in driverSelected.
driverSelected = () => {
return (item, ui: any) => {
if (item.isSelectedDriver()) {
this.assignedDriver(item.driver);
console.log(this.assignedDriver());
return true;
}
};
};

React Beginner Question: Confusing Arrow Function Example

I'm a React/ES6 beginner and I'm using this code I found to handle a checkbox inside a custom component being clicked (the custom component includes a material-ui CheckBox, hence the "checked" value). I'm planning on adding more fields to the custom component, such as a textbox that corresponds to the checkbox where the user can add more information about the box they checked.
Anyway, I'm a bit confused about what's going on in that first line. I was hoping one of you senior level devs could break it down for me so i can understand what's happening here.
Two things to note:
index console logs as an integer value (position in my mapped array)
checked is false by default but console logs as true (is it being
toggled true somehow?)
const onMediaDeliverableChange = index => ({ target: {checked} }) => {
console.log('>> [form.js] (onMediaDeliverablesChange) index = ',index);
console.log('>> [form.js] (onMediaDeliverablesChange) target = ',checked); }
Here's an example of code that I took this from, that is working.
const onCheckBoxChange = index => ({ target: { checked } }) => {
const newValues = [...values];
const value = values[index];
newValues[index] = { ...value, checked };
console.log('>> [form.js] (onCheckBoxChange) value = ',value, index);
console.log('>> [form.js] (onCheckBoxChange) newValues[index] = ',newValues[index]);
props.setDesignOrDigital(newValues);
};
The following:
const onCheckBoxChange = index => ({ target: { checked } }) => {
// stuff
};
could also be written as:
const onCheckBoxChange = index => (event) => {
const checked = event.target.checked;
// stuff
};
{ target: { checked } } is an example of using object destructuring on a function argument. In this case, the argument would be an event.
The first part:
index => another-function
is, as svey mentioned in the comments, an example of a curried function. I assume onCheckBoxChange was used in a loop where the index of the checkbox being rendered was passed in which then returns a function that is an event handler for the change event. The index is then used to get/set the checked state for the respective checkboxes.

Reactjs filter state by key and value

React Newbie here.
I'm trying to match the value of a specific id located in my state, so I can change some value before updating the database via my api.
The state is
state = {
library: []
}
and then with when the axios changes the state the array looks something like:
0:{_id:"", time:"", value:""},
2:{_id:"", time:"", value:""}
When I run console.log, it reads it like this.
(2) [{…}, {…}]0: {_id: "5c82803ad634ea0bebfb3eff", time: "2019-03-08T14:46:18.663Z", value:""}1: {_id: "5c827fb9d634ea0bebfb3efe", time: "2019-03-08T14:44:09.818Z", value:""}
So basically when I type in a specific input field, identified by it's _id, I need to update the value state of that specific state.
Here's the code I have written so far. _id is the unique key of the input field and event value what I'm typing.
updateRead = (_id, event) => {
console.log(_id);
console.log(event.target.value)
this.setState(?????)
};
Help would be much appreciated!
Cheers
You can use the array map method on the library array in your state, and just return the elements as is if the _id doesn't match, and update the value if the _id does match.
updateRead = (_id, event) => {
const { value } = event.target;
this.setState(prevState => ({
library: prevState.library.map(read => {
if (read._id !== _id) {
return read;
}
return {
...read,
value
};
})
}));
};
Two of the fundamental rules of state in React are:
Never modify state directly
Use the callback version of setState when you're setting state based on existing state (more)
Separately, you can't access properties on the synthetic event after the event handler has returned, so you'll want to grab the value before calling setState (since the call to your callback will be asynchronous).
Within the callback, you copy the array, find the relevant object, copy it, and set the value.
So:
updateRead = (_id, event) => {
const {value} = event.target;
this.setState(({library}) => ({
library: library.map(entry => entry._id === _id ? {...entry, value} : entry)
}));
};
map creates a new array from the previous array's entries. The callback returns a new object if the IDs match (using property spread notation) with an updated value, or the original object (since we don't have to copy objects we aren't modifying).

Categories