How to search again in data state after set state function - reactjs

Hello everyone I am beginner at react. I want to search i my state which array of object I write the following function for the search. It works perfectly fine to search for the first time.
But when I try to search for the second time it does't work because "tempdata" is now in state. Can anyone please help me to sort?
Here are my code please have a look thanks in Advance.
categorySearch(event){
let tempdata=[];
this.state.data.map((categoryObject,index) => {
if(categoryObject.name.includes(event.target.value)){
tempdata.push(categoryObject);
}
this.setState({data:tempdata});
});
}

I think filter is a better option here instead of map?
Filter returns a new array with all the items that passed the internal conditional - in your case the String includes method.
categorySearch(event){
const filteredElements =
this.state.data.filter(categoryObject => categoryObject.name.includes(event.target.value));
this.setState({filteredElements: filteredElements});
}
Additionally, I suggest keeping your original data unmodified and use a new key in your state filteredElements to store all the search results that match the search query. That way if you want to do a second search, all the original data is still available.

Related

React - freeze piece of the state?

I have pecuilar input field which on click opens dropdown with checkboxes options. When I type in this input, I need to show only the options that include typed characters. It works fine as I add characters, but as I empty an array of options (which is stored in state), I don't get values back.
I tried freezing piece of state (options), by using Object.freeze, and use this "frozen" array as starting point. But it doesn'r freeze, and I have no clue how to do this. Here's the code
let coppiedOptions = [...state.inputs.names.options];
coppiedInputs.forEach(el => Object.freeze(el));
let newOptions = coppiedOptions.filter(opt => opt.value.includes(action.value));
I am using use Reducer, so I get value as an action payload. And this "newOptions" is being passed into state in reducer
The only solution was writting another options array, with different name, with same data, to coppy it and use it for filtering, while changing only the first one. I quest it is impossible to do with only one set of options. I am an idiot

Improvements to Recently Viewed Component in React

I have this small app I created using a REST Countries API.
https://rest-country-react.netlify.app/
If you click on one country card then it is displayed under the "Recently Viewed" header. So far it works fine, but I wanna tune it a little bit. What I thought I'd do:
#1 Add a limit of three recently viewed countries, so basically if the user clicks on 4,5,6 countries, only the three most recent clicked countries are displayed.
#2 Visited countries are currently sorted in an "oldest" to "newest" order. I wanna reverse that so the newest gets the first spot, then the second newest, then the third and so on.
I am stuck because I am not sure how to implement these tweaks. For the first one I thought I'd filter the state array before mapping it in the component, saying something like... if index > 2, filter it out the element.
But for the second, I haven't found a solution yet. Maybe instead of using concat() method, I should use unshift()? From what I read in the React documentation, it's not advised to directly edit the state or its array, so I don't know what to do.
onCountryClick(country) {
const uniqueRecent = [
...new Set(this.state.recentlyViewed.concat(country)),
];
this.setState({
// ... other state updates here
recentlyViewed: uniqueRecent
});
}
There are actually multiple solutions, but let's take the one which is very clean and understandable:
onCountryClick(country) {
const { recentlyViewed } = this.state;
const newState = {}; // add your other updates here
if (!recentlyViewed.includes(country)) {
// firstly take first two items as a new array
newState.recentlyViewed = recentlyViewed.slice(1);
// add country into beginning of new array
newState.recentlyViewed.unshift(country);
}
this.setState(newState);
}
Firstly we check if country already exists in the recentlyViewed array and if no - then continue.
We must use new array when updating the state, so simply calling unshift() method will not work for us as it modifies original array and doesn't return new one. Instead, we firstly call .slice() method which solves two main things for us: it takes a portion of original array (in our case items with index 0 and 1) and return new array with them. Great! Now we can easily use unshift to add country into beginning of new array. Then simply update the state.
With this solution you always get a new array with max of 3 countries, where the first item is the newest.

How to retrieve specific value of an array from firestore

I am retrieving specific data as an array from firestore, the value is the there on the console.log(), but i cant seems to retrieve the specific data from the array itself,
here's my event.ts
import { Event } from '../../models/event';
invitedEvents: Event[] = [];
this.invitedEvents = invitedEvents;
console.log(invitedEvents, invitedEvents.name);
on console.log()
as you can see the invitedEvents.name return value of undefined, i'm sure you guys know the proper way of retrieving the value of name, send help.
The object is in the array, so you have to access object from array first invitedEvents[0]
console.log(invitedEvents, invitedEvents[0].name);
Here you have to invitedEvents is an array. So if you need to access you can't directly like invitedEvents.name like this, here is the few ways to access.
for(let item of invitedEvents){
console.log("Data",item);
console.log("Specific Name",item.name);
}
This example is used to print multiple values.
If you have only one value.Simply do like this.
console.log("Specific Name Second way", invitedEvents[0].name);
I hope its helps you.
Thanks,
Muthu

How do I use the last value in an array as a path for .child() when retrieving a snapshot?

I'm new to Firebase and have a function that writes all of my event ID's to an array. I want to use the last value in that array (the last event ID) to lookup the children of that specific eventID.
I know how to get the last item in the array but how do I put that into my .child() path?
I tried the code below, but it doesn't seem to work. I'm guessing that because .child("(lastEvent)") isn't a valid path.
let lastEvent = eventIDArray.last
refHandle = ref.child("Bouts").child("\(lastEvent)")
How do I plug the lastEvent value in as my path? Or is that even possible? Again, total newbie- alternatives welcome.
Sorting and filtering data
you can use sorting and filtering function to get the item.
To get the last item you can write the query like this.**
let recentBoutsQuery = (ref?.child("Bouts").queryLimited(toLast: 1))!
This will return 1 entry from last of your database which the last entry.
You can learn more from the firebase documentation. Work with Lists of Data

why splice not working correctly in react?

I am trying to delete row from my list using delete button .I do like this
if (state.indexOf(action.payload) > -1) {
console.log('iff----')
state.splice(state.indexOf(action.payload), 1);
}
console.log(state)
return state
but it is not deleting the row .here is my code
https://plnkr.co/edit/bpSGPLLoDZcofV4DYxPe?p=preview
Actually using add button I am generating the list of item and there is delete button I am trying to delete item from list using delete button
could you please tell me why it is not working ?
Avoid using Array#splice when working with state in React or Redux. This mutates your state, which you never want to do. Instead, favour immutable methods like Array#slice. e.g.
const index = state.indexOf(action.payload);
if (index === -1) {
return state;
}
return [...state.slice(0, index), ...state.slice(index + 1)];
The flaw of this approach is that in JavaScript, objects and arrays are reference types, so when we get an array, we actually get a pointer to the original array's object managed by react. If we then splice it, we already mutate the original data and whilst it does work without throwing an error, this is not really how we should do it, this can lead to unpredictable apps and is definitely a bad practice. A good practice is to create a copy of the array before manipulating it and a simple way of doing this is by calling the slice method. Slice without arguments simply copies the full array and returns a new one which is then stored. And we can now safely edit this new one and then update to react state with our new array. let me give you and example:
We have an array like this const arr=[1,2,3,4,5]. This is original array.
As I told you before, we can do that like this:
const newVar=arr.slice();
newVar.splice(Index,1);
console.log(newVar);
Or
An alternative to this approach would be to use it a ES6 feature, it is the Spread Operator
Our prior code can be something like this:
const newVar=[...arr]
newVar.splice(Index,1);
console.log(newVar);
That's it. Good luck

Resources