React formik and select array to string Convert onSubmit - javascript

React formik and react select package are I am using . I created on form that contains user can create new and Edit also working in same form. I have an one multi select field that field values are in array I want to change to string send to server on onSubmit. And also on update I want to get the string value convert array set to select field. I try it but cant found solution .please give me any ideas It helpful for me
codeSandbox:https://codesandbox.io/s/multipleselect-formik-3eqxp?file=/src/RegisterForm.js
Thanks for help

After getting the field value change the array to string on before submit. we want bind the change string value on field. It will be working fine for me.
Code Sandbox link :https://codesandbox.io/s/multipleselect-formik-3eqxp?file=/src/RegisterForm.js:657-844
function create(fields) {
console.log(fields);
const jobs = [];
fields.job.map((ele) => jobs.push(ele.value));
fields.job = jobs.toString();
console.log(fields);
}

i am not sure if this what you are looking for, but i did
function create(fields) {
fields.job = JSON.stringify(fields.job)
console.log(fields);
}
or
function create(fields) {
const jobs = [];
fields.job= fields.job.map((ele) => jobs.push(ele.value));
console.log(fields);
}
instead of
function create(fields) {
console.log(fields);
const jobs = [];
fields.job.map((ele) => jobs.push(ele.value));
const job = ("text => ", jobs.toString());
console.log(job);
console.log(fields);
}

I think you want to get the value from the array where the result should be
{name: "111", fatherName: "222", job: ["enginner", "painter"] }
function create(fields) {
const amendedFields = {
...fields,
job: fields.job.map((ele) => ele.value) // extract value from object, ["enginner", "painter"]
}; // not mutating the current fields object, copy it and mutate the new one.
console.log("old", fields);
console.log("new", amendedFields);
}

Related

Assign new name to object's key in an array of objects

In a Grid, records are fetched from API and displayed. It also has certain input fields, with text and date field. While inputting data for date its getting displayed two times, as seen in the console, the data from JSON is as est: 10/20/2022 but I want to display it as Establish: 10/20/2022. What modifications could be made in the code? Please refer to code below.
//Here 'allData' is an array of data from JSON
const tempData = allData;
tempData.map((x) => {
if (data.id === x.id) {
x.name = data.textVal;
}
// Here I'm trying to assign new key 'Establish' to old key 'est'
if (data.id === x.id) {
x["est"] = x["Establish"];
x.Establish = data.dateVal;
}
});
Please refer to codesandbox link --> https://codesandbox.io/s/jovial-aryabhata-95o2sy?file=/src/Table.js
Give this a whirl
if(data.id === x.id) {
delete Object.assign(x, {['Establish']: x['est'] })['est'];
}
I think your way works but if you want another way so you can create a new property by using:
Object.defineProperty(x, "Establish", Object.getOwnPropertyDescriptor(x, "est"));

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([])

How to search a value in an array inside another array

I have a problem of find a value in an array inside another array, and use the result to setState()
This is the initialState:
this.state =
{
initialStudents:[
{name:"str1",tags;["str","str",...],...},
{name:"str2",tags;["str","str",...],...},
...
],
students: [
{name:"str1",tags;["str","str",...],...},
{name:"str2",tags;["str","str",...],...},
...
]
}
The code i use to find the tags:
findTag = (tags, target) => {
tags.filter(tag => {
return tag.toLowerCase().search(target.toLowerCase()) !== >-1;
});
};
filterTag = e => {
let updatedList = this.state.initialStudents;
updatedList = updatedList.filter(student => {
return this.findTag(student.tags, e.target.value);
});
this.setState({ students: updatedList });
};
The filterTag does not update the students state
To solve your problem, I made a few edits and put them all in this working codesandbox example.
First, I changed your findTag function to something like this:
// pass in the tags from the student, and the target tag you're searching for.
// -> return true if 1 or more matching tag, false otherwise
findTag = (tags, targetTag) => {
// make sure you return something!
return tags.filter(tag => {
// check if current tag in arr matches target tag (case insensitive)
return tag.toLowerCase() === targetTag.toLowerCase();
}).length > 0; // check if there's 1 or more matching tag
};
Next, I updated the filterTag function in a few ways:
Immutably copy this.state.initialStudents into the local updatedList array. This is necessary so you don't mess up the current state before running this.setState!
Pass the value of the input via this.state.filterTag instead of e.target.value. This way, you'd update the filter when you click the button instead of on every time you press a key.
Here's how these changes look:
filterTag = e => {
// immutably copy initial student data
let updatedList = this.state.initialStudents
.map(student => ({
name: student.name,
tags: [...student.tags]
}))
// remove students w/out filter tag
.filter(student => {
return this.findTag(student.tags, this.state.filterTag);
});
// update state with new student list
this.setState({ students: updatedList });
};
A few other improvements I made:
Instead of manually setting data in initialStudents and students, I made them immutably copy the same data set from the const initialStudents data set. This could be done in the componentDidMount lifecycle method if you're fetching students from a database.
I fixed your student object declarations - you put tags;["str"...] which is invalid - the semicolon ; should be a normal colon :
I changed some "str" values to "str2" to make them unique between students
Let me know if you have questions about the codesandbox or anything else :D Hope it helps!

The value of one input is affecting another

I have a simple app which allows someone to add a numbers into an input, and have those numbers render onto the page (as inputs) which can be edited.
addSiblingValue(evt) {
this.setState({
currentObject: {
...this.state.currentObject,
numberOfSiblings: evt.target.value
}
});
add() {
const array = [...this.state.array, this.state.currentObject];
this.setState({
array
});
}
siblingCountChange(rowIndex, event) {
const array = [...this.state.array];
array[rowIndex].numberOfSiblings = event.target.value;
this.setState({ array });
}
So when I add a number it renders a new input with the value set to the number I've just added, but when I go to change that value, it now is affecting the first input.
The first row of inputs are using their own object currentObject which pushes to to the this.state.array, so I'm not sure why editing anything in that array would affect the currentObject?
Expected behaviour:
User enters a number into the input and clicks add
That input is rendered and can be edited independently
How do I achieve this or what is it I'm doing wrong here?
CodeSandbox
Thank you
When you add this.state.currentObject to the array, it works as an reference, so that the added object in the array and this.state.currentObject are the same object. You can prevent that by adding not the object itself, but a copy of the object into the array:
add() {
const array = [...this.state.array, {"numberOfSiblings": this.state.currentObject.numberOfSiblings}];
this.setState({
array
});
}
siblingCountChange(rowIndex, event) {
const array = [...this.state.array];
array[rowIndex].numberOfSiblings += parseInt(event.target.value);
this.setState({ array });
}
You were not adding the actual number to the current state. I also removed the value from the add like so:
<input
type="text"
onChange={this.siblingCountChange.bind(this, rowIndex)}
/>
You will need to put error handling on the state as a string plus a number leads to NaN error. As you can see the number is parsed before addition.
Thanks to dieckie for pointing me in the right direction. Unfortunately that particular solution did not work, but using Object.assign to create a reference and pushing that to the array did?
Posting here so it helps others/myself in future:
add() {
let copyOfCurrentObject = Object.assign({}, this.state.currentObject);
const array = [...this.state.array, copyOfCurrentObject];
this.setState({
array
})
}
This question was also helpful.

Trouble with React/JS filter

I am trying to implement a filter function that is able to search in two separate JSON fields when a user types in a search bar. Searching the whole JSON returns errors and if I repeat this function, the two similar functions cancel each other out.
My current filter function:
let filteredOArt = origArt.filter((origAItem) => {
return origAItem.authors.toLowerCase().includes(this.state.search.toLowerCase())
});
I want to be able to have the search look within the "authors" field as well as a "description" field.
Before the React render, I have this function listening to the state:
updateSearch(event) {
this.setState({ search: event.target.value })
}
Then my search function is in an input field in the React return:
<h6>Search by author name: <input type="text" value={this.state.search} onChange={this.updateSearch.bind(this)} /></h6>
You can tweak the function a bit like this
let filteredOArt = origArt.filter((origAItem) => {
return (
(origAItem.authors.toLowerCase().includes(this.state.search.toLowerCase())||
(origAItem.description.toLowerCase().includes(this.state.search.toLowerCase())
)
)
});
You actually can do a filter for both fields.
Given you have your searchValue and your array with the objects you could filter this way:
const filterByAuthorOrDescription = (searchValue, array) =>
array.filter(
item =>
item.authors.toLowerCase().includes(searchValue.toLowerCase()) ||
item.description.toLowerCase().includes(searchValue.toLowerCase())
);
const filtered = filterByAuthorOrDescription(this.state.search, articles);
filtered will now contain an array of objects that contain your searchValue in either description or authors that you can map through.
You could use some to check if the filter is positive for at least one field :
let filteredOArt = origArt.filter(origAItem => ['authors', 'description'].some(field => origAItem.[field].toLowerCase().includes(this.state.search.toLowerCase())))
Just iterate over the different field names you want to use.
Some will return true if any of the fields mentioned contains your string and avoid repetitions in your code.
Long syntax :
origArt.filter(origAItem => {
return ['authors', 'description'].some(field => origAItem.[field].toLowerCase().includes(this.state.search.toLowerCase()))
})

Categories

Resources