How to get filtered object length - reactjs

I am trying to show that there is no data to display when the size of filtered object is zero. Is there any way to check its size after calling filter method?
this.state.items
.filter(item => {
// filter code
})
.map(item => {
// display data
})
For example, this.state.items has ten items and becomes zero after passing through filter method. I'd like to display the message at this point.

First store the filtered data in a variable:
let filteredData = this.state.items
.filter(item => {
// filter code
});
Now filteredData will contain the filtered data, now you can check the length of this variable and return 'No Data Found' if length = 0, Use either ternary operator:
return filteredData.length ?
filteredData.map(item => {
// display data
})
:
<div>No data found </div>;
Or you can use if-else condition also:
if(filteredData.length)
filteredData.map(item => {
// display data
})
else
<div>No data found </div>

const filteredData = this.state.items((items) => //filter code);
return filteredData.count()
? filteredData.map(item => //data);
: <div>No Data found </div>
Try this one with immutable object.

Related

Order Firebase data returned by collection name

I'm sorry if this has been asked but I have found many questions about ordering by field contents. I would like to order by field names. I have tried orderBy, orderByChild and startAt - none of which worked.
My collection looks like this:
I would like my data to always start with 'All', after that the order does not matter.
Here's how I fetch the data:
const fetchProjects = async() => {
const catRef = doc(db, 'Portfolio', 'Category')
const catSnap = await getDoc(catRef)
if(catSnap.exists()) {
setCategory(catSnap.data())
}
}
And then I create buttons to select certain fields of data as below:
const sortButton = (key) => {
if(filter === key) {
return (<div key={key}>
<button className='prt-act-btn' >{key}</button>
</div>)
} else {
return ( <div key={key}>
<button className='prt-btn' onClick={() => setFilter(`${key}`)}>{key}</button>
</div> )}
}
if(loading || fetching) {
return <p>loading...</p>
}
return (
<>
<p className="pageHeader"> <FaFileArchive/> Portfolio</p>
<div className='center'>
{Object.keys(category).map((key) => (
sortButton(key)
))}
</div>
}
So essentially the problem is that my buttons are randomized in order after each reload and I would like to start with 'All' and then list the other categories like 'API', 'Blockchain', 'Database' etc.
Thank you for any help!
Javascript objects are not meant for ordered data. Object do technically have an order to their keys, but you have little ability to control that order and should not rely on it. So when you do Object.keys(/* some object */), you should mentally treat it as though you're getting the keys in a random order. You happen to be getting this object from a firestore document, but the same thing would happen with any object.
If you want to put the keys into an order you can, but you'll need to add code to do so. The .sort function can help with this. For example, if you want to put 'All' first, and then the rest in alphabetical order you might do:
{Object.keys(category)
.sort((a, b) => {
if (a === 'All') {
return -1;
} else if (b === 'All') {
return 1;
} else {
return a.localeCompare(b);
}
})
.map(key => sortButton(key))
}

How to map the selected data in reactjs

I can get the data from what i selected
const onHandleSelectLocation = async (value) => {
console.log(value)
}
this is the data result from console.log
I am having a hard time getting the Email only, how can i achieve that? i've tried the value.email but it getting undefined.
The value shown in the log is array of objects, if you want to get the email, do the map instead
const onHandleSelectLocation = async (value) => {
console.log(value);
const emails = value.map(({ email }) => email);
console.log(emails);
}
value is an array with two objects, that includes email, id and name. if you want to access one of those, you can use map. you can mapping in array and use what properties that you need from objects.
for example like this:
value.map => ( item => <div key={item.id}> {item.email} </div>)

Manage multiple state array searches and keep the original state array?

I'm trying to build a search function to be able to search an Array in state.
var searchString = "search word"
var updatedList = cases.filter((item) => {
return Object.keys(item).some(
key => (item as any)[key]
.toString()
.toLowerCase()
.search(searchString.toLowerCase()) !== -1
);
});
this.setState({
cases: updatedList
})
This updates state.cases and renders the items found in the Array with objects, which is good. But when I'm doing another search, state.cases is of course updated and contains only the items from the search before.
How can I keep the "old" state before the first search and make multiple searches?
The cases in state is used in a component that renders a table with the result.
Maybe don't set the state for the filtered cases ..? Just set the state for the search string and try this
render() {
const { searchString } = this.state;
const { cases } = this.props;
let filteredCases = cases;
if(!!searchString) {
filteredCases = cases.filter((item) => {
return Object.keys(item).some(
key => (item as any)[key]
.toString()
.toLowerCase()
.search(searchString.toLowerCase()) !== -1
);
});
}
return <>{filteredCases}</>
}
So you will just filter out the cases based on your search string.

Unable to set the value of a variable to state variable in react js

I am getting API response and once after getting that I am applying some filter and want to assign the result to state variables.
Here is what I am trying to do:
filtered = this.state.result
.filter(value => value.Date == bar.Date)
.reduce((acc, e) => acc.concat(e.FailureDeatils), []);
this.setState({ failureResultValue: filtered });<-- Here I am able to set the filtered to failureResultValue.
Again on this failureResultValue,I am applying filter and able to achieve the result i.e.
failureResultTransactions = this.state.failureResultValue
.filter(data => data.name == pie.name)
.reduce((acc, item) => acc.concat(item.TransactionDetails) , []).map(item => ({ ...item, checked: false }));
console.log(failureResultTransactions );<- It has value
this.setState({ items: failureResultTransactions });<- This is not working
console.log(this.state.items)<- is returning empty
Can anyone figure out where I am going wrong?
this.setState({ items: failureResultTransactions },()=>
console.log(this.state.items));
You can check like this

How to filter react table based on drop down data selected?

const filterRowItem = filterRows.filter((row) => row.status === event.target.value);
this.setState({data:filterRowItem})
/////////////////////
<ReactTable data={data}
As denoted into the snippet I have one react table in which data is there,This data is giving from the state.
Now into the select dropdown there are values means if user select the item from the drop down based on selected value the react table data is filters on status column.
Here data is already filtered but its only filtered first time not second time,
Because first time again I am setting the state as shows in to snippet.How the data array filter without mutating ?
You should store not filtered list, but filter condition. And filter the list on render:
onFilterChange(event) {
this.setState({filterByStatus: event.target.value})
}
render() {
const { sourceRows } = this.props;
const { filterByStatus } = this.state;
const filteredRowsByStatus = sourceRows.filter((row) => row.status === filterByStatus);
// so we filtering each render by filterByStatus stored in the state.
return (<ReactTable data={filteredRowsByStatus} />);
}

Resources