i have a issue, i have two inputs then and i can't permit the user save this edit if the two values is equals.
my state who contains a data from db
const [doctorRegisters, setDoctorResgisters] = useState<any>([]);
inside this array i contain this
[{"__typename": "DoctorMedicalRegister", "counsil": "CRM", "id": "141", "isMainRegister": true, "register": "1234567/RS"}, {"__typename": "DoctorMedicalRegister", "counsil": "CRM", "id": "153", "isMainRegister": false, "register": "1234567/RS"}]
and i need compare two register who if is equal, i cant permit user save he save just is different
here is a code who i try fix this
const isEquals = () => {
doctorRegisters.map((item: any) => {
if (item.register) {
doctorRegisters.map((item2: any) => {
if (item2.register) {
if (item.register === item2.register) {
console.log('iguais')
}
}
});
}
});
};
but this work only for dont edited values i need verify when this value is changed in input in this case i only verify in db this values is equals
here is my handle change
const handleEditRegisterCrm = (crm: string, id: number) => {
setDoctorResgisters(
doctorRegisters.map((item: any) => {
if (item && Number(item.id) == id) {
item.register = `${crm}/${item.register?.split('/')[1] || ''}`;
}
return item;
}),
);
};
You could do something like:
const handleEditRegisterCrm = (crm: string, id: number) => {
if (!doctorRegisters.some((doctorRegister) => doctorRegister.register.includes(registerToCompare)) {
setDoctorRegisters(
doctorRegisters.map((item: any) => {
if (item && Number(item.id) == id) {
item.register = `${crm}/${item.register?.split('/')[1] || ''}`;
}
return item;
}),
);
}
};
Remember you should keep track of the registerToCompare in order to find if it's already inserted in the doctorRegisters list. I'm assuming you can obtain that value from the your handleChange function.
Related
I have a svelte store that uses this data:
{ "books": [
{
"id": "F0tE_25",
"title": "Abc",
...
},
"id": "zNPAQit",
"title": "Ny, Ny",
...
}
]
}
I edit a book in a form and call the function below to update the store (id is the book id to update and bookData is the updated data (from the form):
updateBook: (id, bookData) => {
bookstore.update(items => {
const index = items.findIndex(i => i.id ===id)
const updatedBook = {...items[index], ...bookData}
const updatedBooks = [...items]
updatedBooks[index] = updatedBook
return updatedBooks
})
}
It works. It just seems like a lot of juggling to perform an update. Wondered if there was a better way?
There are a few problems associated with the approach in the question viz use of findIndex. If the item with the given id doesn't exist the value of index will be -1 which will result items[index] to be undefined and will be the cause of other undesired behavior.
You can use .map() to eliminate and simplify the update. Here is an example.
updateBook: (id, bookData) => {
bookstore.update(items =>
items.map(item => {
if (item.id === id) {
return { ...item, ...bookData };
}
return item;
})
);
}
Edited: #pilchard's answer might be even clearer implementation with the use of ternary operator.
updateBook: (id, bookData) => {
bookstore.update(items =>
items.map(item => {
return item.id === id ? { ...item, ...bookData } : item;
})
);
}
Hope that helps.
I have a list of objects like this.
results = [
{ id: 1,
status : "Active"
// Some other fields
tags : [{val: 'IGM', color: 'light-success' },
{val: 'Gated Out', color: 'light-primary' },
]
},
// ...
]
now I want to filter objects in relation to tags,
the input to filter the list is also in the form of an array using multi-select input.
like
[{value: 'Gated Out', label: 'GATED OUT'}, .. ]
I'm able to filter data of other fields but not the tags because other fields are in strings and tags are an Array.
But now How can I modify this to work with the array as well.
I'm using that approach;
const handleTagsFilter = (value) => {
let updatedData = []
const dataToFilter = () => {
if (
status.length ||
custom_tags.length
) {
return filteredData
} else {
return results
}
}
setCustomTags(value)
if (value.length) {
updatedData = dataToFilter().filter((item) => {
const startsWith = item.status.toLowerCase().startsWith(value.toLowerCase())
const includes = item.status.toLowerCase().includes(value.toLowerCase())
if (startsWith) {
return startsWith
} else if (!startsWith && includes) {
return includes
} else return null
})
setFilteredData([...updatedData])
setCustomTags(value)
}
}
That function works with filtering strings like we have the status field to Active than this work, But I'm not sure how I can modify it to work with the array as well.
Maybe something like:
let search_str = 'abc'.toLowerCase();
let filtered_results = results
.map(v => v.tags.filter(_v => _v.val.toLowerCase().includes(search_str)))
.filter(v => v.length)
.reduce((a, b) => a.concat(...b), [])
I am trying to implement a functionality where I want to push object into an array when the user checked it and remove it if the user unselects it. I have a menu where I am collecting user choices. I have implemented code but it has not resolved my issue, Could someone please help me how to resolve this issue. Thanks
const selectSingle = (id, item, index) => {
const user = Cookies.get("user") && JSON.parse(Cookies.get("user"));
let callScheduleIds = Object.assign([], allCallNotifications);
if (callScheduleIds.findIndex((item) => item.order_id === id)) {
callScheduleIds.push({
order_id: id,
phone_number: item.phone1,
sender_id: user.user.id,
});
} else {
callScheduleIds.splice(callScheduleIds.indexOf(id), 1);
}
setAllCallNotifications(callScheduleIds);
};
You can do it by using Lodash.
const selectSingle = (rowIndex, item) => {
let callIds = Object.assign([], allCallNotifications)
if (_.findIndex(callIds, { id: item.id }) === -1) {
callIds.push(item)
} else {
callIds.splice(_.findIndex(callIds, { id: item.id }), 1)
}
setAllCallNotifications(callIds)
}
I need to push to the array cities if there is no such a city
getCityList() {
const { StoreInfo } = this.props;
this.emptyCityList();
return StoreInfo.map((StoreInfo, index) => {
console.log(this.cityPushCheck(StoreInfo.city));
if (this.cityPushCheck(StoreInfo.city)) {
CITY_LIST.push({
id: index, label: StoreInfo.city, value: StoreInfo.city, disabled: false
});
}
});
}
cityPushCheck(city) {
const MAP = CITY_LIST.map((CITY_LIST) => {
if (CITY_LIST.label === city) {
console.log('are equal');
return false;
}
});
return true;
}
I was trying return CITY_LIST.map((CITY_LIST) =>
without const or return CITY_LITS.map is not working
can't get it.
what I am doing wrong?
[UPDATE]
So this solution worked for me
getCityList() {
const { StoreInfo } = this.props;
this.emptyCityList();
return StoreInfo.map((StoreInfo, index) => {
if (this.cityPushCheck(StoreInfo.city)) {
CITY_LIST.push({
id: index, label: StoreInfo.city, value: StoreInfo.city, disabled: false
});
}
});
}
cityPushCheck(cityLabel) {
const cityFromList = CITY_LIST.find(city => city.label === cityLabel);
return cityFromList === undefined;
}
thanks to #quittle
It's a bit unclear what you are asking for exactly but I believe your question is how to implement cityPushCheck so that it returns false if the city is in CITY_LIST and true otherwise. Assuming CITY_LIST is an Array, there's a helpful function called find on arrays that greedily check for the presence of an entry based on a condition.
cityPushCheck(cityLabel) {
// Grabs the instance of the city from the list if it was present
const cityFromList = CITY_LIST.find(city => city.label === cityLabel);
// cityFromList will be undefined if "find" didn't have a match
return cityFromList === undefined;
}
While use map, you go city by city in your array, and for each return boolean. You might consider use filter, and then check if the filtered array have any length just once
cityPushCheck(city) {
CITY_LIST.filter(CITY => CITY.label == city).length
}
Now, if there isn't such city at array, length is 0 what is equal to false at JS
I have an object to collect data to send to an API:
apiData: {
colors: [],
years: [],
// ..
}
Many of the children of this apiData are arrays like colors and years, I call these 'subgroups'. A user can select a multitude of subgroups with checkboxes that trigger:
handleCheckboxColorChange(value, isChecked) {
let newApiData = '';
this.setState( (prevState) => {
if (isChecked === true) {
newApiData = {...prevState.apiData, colors: [...prevState.apiData.colors, value]}
} else {
newApiData = {...prevState.apiData, colors: [...prevState.apiData.colors.filter(item => item !== value)]
}
}
return {apiData: newApiData}
}, () => this.props.handleApiCall(this.state.apiData))
}
I use a similar function for the other 'subgroups'. For years, all that changes in the function is colors to years. So I wish to create a more general function that can take a 'subgroup' as argument to target the right array in my object. I tried to pass a third variable (a string) subGroup like so:
handleCheckboxChange(value, isChecked, subGroup) {
// ..
newApiData = {...prevState.apiData, subGroup: [...prevState.apiData.subGroup, value]}
This does not work (I guess because it is now looking for the child 'subgroup' in my object). How can I make this work?
Use bracket notation :
handleCheckboxChange(value, isChecked, subGroup) {
// ..
newApiData = {...prevState.apiData, [subGroup]: [...prevState.apiData[subGroup], value]}
To make it a bit prettier, you can use this:
handleCheckboxColorChange(value, isChecked, subGroup) {
this.setState((prevState) => {
const newState = { ...prevState }
newState[subGroup] = isChecked ? [ ...newState[subGroup], value ] : newState[subGroup].filter(item => item !== value)
return newState
}, () => this.props.handleApiCall(this.state.apiData))
}