The problem is that I need to pass array of object , I can not get my accepted data .My accepted data will be this format. However, user can remove by using unchecked.
{
notification : {group:["can_view","can_create", "can_delete","can_update","can_upload","can_download"],
topGroup:["can_view","can_create", "can_delete","can_update","can_upload","can_download"}
}
handleAllChecked = (id, role, data) => event => {
let fruites = this.state.fruites;
fruites
.filter(f => f.groupId === id)
.forEach(fruite => {
if (event.target.checked === true) {
fruite.isChecked = event.target.checked;
console.log(data);
} else {
fruite.isChecked = false;
}
});
this.setState({ fruites: fruites });
};
here is my codesanbox , You can easily understand
https://codesandbox.io/s/fragrant-http-v35lf
Related
I am creating an App in which I have two screens -- One is Feed and Bookmark. Each Feed has bookmark icon from which we can add and delete bookmark. If I add bookmark from feed then It will be added to list and if I delete that then list will be updated with existing once but the issue is that sometime data added double at the time of addition and sometimes at time of deletion array did not get the index of selected item and stays there and sometimes my list got disturbed with showing half items.
Code to click bookmark button on feed
const selectBookmark = () => {
item.bookmarked = !item.bookmarked;
setBookMarkSelected(!item.bookmarked);
setBookmarkClicked(true);
setBookmarkLoader(true);
};
Call API each time at updating bookmark
const bookmarkResponse = await addDeleteBookmark(
email,
userId,
item.cardId,
userSelectedChannel,
token,
item.bookmarked,
item.createdAt,
item.cardType,
)
.then(res => {
setBookmarkLoader(false);
if (res !== 'error') {
console.log('not in else');
updatebookMark();
} else {
console.log(' in else');
item.bookmarked = !item.bookmarked;
}
})
.catch(function (error) {
setBookmarkLoader(false);
});
};
**when I get response from API I call updateBookmark function too update local database **
const updatebookMark = () => {
// code to update feed Array locally
let newArray = [...feedArray];
let id = item.cardId;
const index = newArray.findIndex(object => {
return object.cardId === id;
});
if (index !== -1) {
newArray[index].bookmarked = item.bookmarked;
addFeedsToLocalDB(newArray);
}
// code to update bookmark Array locally
let bookmarks = [...bookmarkArray];
// bookmark added then add new bookmark
if (item.bookmarked) {
const index = bookmarkArray.findIndex(object => {
return object.cardId === id;
});
if (index === -1) {
bookmarks.push(item);
addBookMarksTOLocalDB(bookmarks);
}
} else {
// if deletion then delete from bookmark
const indexBookmark = bookmarks.findIndex(object => {
return object.cardId === id;
});
console.log('bookmark card indexBookmark image', indexBookmark);
bookmarks.splice(indexBookmark, 1);
// console.log('bookmarked after splicing image', bookmarks);
addBookMarksTOLocalDB(bookmarks);
// setBookmarksArray(bookmarks);
}
let homeArray = [...homeCards];
const indexHome = newArray.findIndex(object => {
return object.cardId === id;
});
if (indexHome !== -1) {
homeArray[indexHome].bookmarked = item.bookmarked;
addHomeToLocalDB(homeArray);
}
};
but the issue is that this addition and deletion bookmark is causing issue and I am not able to get that.
i have been suffering to get the items' data listed according to their categories
i don't know what am I doing wrong.
so basically, I have data coming from a bearer token API and it is listed successfully on the screen but I want as a second step to list according to their categories. there are five categories and more than 60 items.
here is my code:
const [filterList, setFilterList] = useState("all");
const [newProduct, setNewProduct] = useState(products);
// filtering data by category
useEffect(() => {
let isValidScope = true;
const fetchData = async () => {
// pass filterList in fetch to get products for the selected category ??
// pass parameters to fetch accordingly
const res = await fetch(
"https://myapi-api.herokuapp.com/api/categories/",
{
method: "GET",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
}
);
if (!isValidScope) {
return;
}
setNewProduct(res);
};
fetchData();
return () => {
isValidScope = false;
};
}, [filterList]);
function onFilterValueSelected(filterValue) {
setFilterList(filterValue);
}
let filteredProductList = newProduct?.filter((product) => {
// should return true or false
// option 2 if product has a category property
return product.category === filterList;
// existing code
if (filterList === "electronics") {
return product.electronics == true;
} else if (filterList === "clothing") {
return product.clothing === true;
} else if (filterList === "accsessories") {
return product.accsessories === true;
} else if (filterList === "furniture") {
return product.furniture === true;
} else if (filterList === "hobby") {
return product.hobby === true;
} else {
// here dont return truthy
return false;
}
});
You could fetch all of them once when the component mounts and them filter them on every render based on the selected filter instead of fetching products everytime in useEffect when filter changes.
const [filterCategory, setFilterCategory] = useState("");
function onFilterValueSelected(filterValue) {
setFilterCategory(filterValue);
}
let filteredProductList = newProduct?.filter((product) => {
return product.category === filterCategory;
});
Try something like that:
const categories = ['Cat1', 'Cat2', 'Cat3'] // Since you hardcode it anyway, its fine to have a hardcoded array here. But you can retrieve unique categories by getting Object.values on category and new Set() them
return (<> {categories.forEach(category => {
fetchedData.filter(el => el.category === category).map(filteredElement => {return <h1> {filteredElement.property} <h1>})}) </>}
The senerio is that when choose categories using checkbox those checked box who are slected save their values in db in different column.
const checkListNames = check.map((item) => item.name)
values in want to save in different columns.
Getting output such as :
['A stage is required', 'Themed decoratiions are essential to my event'].
Want to save these values in different columns
const handleSubmit = (e) => {
e.preventDefault();
if (check.length > 0) {
const checkListNames = check.map((item) => item.name);
let formData = new FormData();
formData.append('list_category', categoryId);
formData.append('name', checkListNames);
formData.append('event_id', get_all_data.data7);
formData.append('created_by', '629829078779cc4a00139c9a');
for (var pair of formData.entries()) {
console.log(pair[0] + ' - ' + pair[1]);
}
api
.post('checklist', formData)
.then((response) => {
const { data } = response;
if (data.status == '1') {
toast.success('Checklist added successfully');
history.push('/CheckList');
} else {
toast.error('Something went wrong !');
}
})
.catch((error) => {
throw error;
});
} else {
toast.error('Select atleast one category');
return false;
}
};
This is a follow up question to this question:
Why calling react setState method doesn't mutate the state immediately?
I got a React component with a form which can be used to add items or edit a current item. The form is being saved as a state of the component along with all its values.
When submitting the form I'm doing this:
const onSubmitForm = () =>
{
if(editedItem) //the item to edit
{
EditSelectedItem();
setEditedItem(undefined);
}
else
{
//handle new item addition
}
clearFormValues();
setEditedItem(undefined);
}
And the edit method:
const EditSelectedItem = () =>
{
setItemsList(prevItemsList =>
{
return prevItemsList.map(item=>
{
if(item.id !== editedItem.id)
{
return item;
}
item.name = formSettings["name"].value ?? "";
item.description = formSettings["description"].value ?? "";
item.modified = getNowDate();
return item;
});
})
}
The problem is that because the setItemsList is not being called synchronously, the clearFormValues(); in the submit form method is being called before, and I lose the form's old values (in formSettings)..
How can I keep the old values of formSettings when the setItemsList is called?
The solution is easy here, you can store the formValues in an object before using it an setItemsList
const EditSelectedItem = () =>
{
const values = {
name: formSettings["name"].value ?? "";
description: formSettings["description"].value ?? "";
modified: getNowDate();
}
setItemsList(prevItemsList =>
{
return prevItemsList.map(item=>
{
if(item.id !== editedItem.id)
{
return item;
}
return {...item, ...values};
});
})
}
I have a group of checkboxes, whenever I select a checkbox I need to push an array of data, like { 'index':1, 'photo':'sample.png' } to state, and whenever I unselecting the checkbox, I need to remove it from the state. after I need to loop through the state to get index and photo to be used
handleSelection = async (media, index, isSelected) => {
alert(index);
if (isSelected == true) {
this.state.mediaSelected.push(media.photo);
} else {
this.state.mediaSelected.splice(this.state.mediaSelected.indexOf(media.photo), 1);
}
console.warn(this.state.mediaSelected);
}
this is working for single value without the key, is there any way to push it with key and value?
You should always update state with this.setState in your case would be something like this:
handleSelection = async (media, index, isSelected) => {
alert(index);
if (isSelected == true) {
this.setState({
mediaSelected: this.state.mediaSelected.push({
index,
photo: media.photo
})
});
} else {
this.setState({
mediaSelected: this.state.mediaSelected.splice(this.state.mediaSelected.indexOf(media.photo), 1)
});
}
console.warn(this.state.mediaSelected);
}
Try this:
Sorry I am working as well as answering your question so it is taking time.
handleSelection = async (media, index, isSelected) => {
let selectPhotosObj = this.state.selectPhotosObj || [];
if (isSelected == true) {
const data = { index, photo: media.photo };
//this.state.selectedPhotoObj will be the container for your object.
selectPhotosObj.push(data)
//need to set the new Array of Object to the state.
this.setState({ mediaSelected: media.photo, selectPhotosObj });
} else {
const removedPhoto = this.state.mediaSelected.filter(value => value !== media.photo);
selectPhotosObj = this.state.selectedPhotosObj.filter(value => value.index !== index);
this.setState({
mediaSelected: removedPhoto,
selectPhotosObj
})
}
console.warn(selectPhotosObj);
}