Rendering results of filter with react native - react-native

I've this....
renderSearchResults() {
if (!this.props.events.successfully) {
return
}
//This don't work
/*
return (
<View>
{
this.props.events.data.data.filter(flt =>
flt.location.toLowerCase().includes(this.state.searchText.toLowerCase()))
.map(item => {
alert(item)
return (<View style={style.searchResultsWrapper} key={'ev' + item.id}>
<EventItem data={item}></EventItem>
</View>)
})
}
</View>
)
*/
//This Works
return (
<View>
{
this.props.events.data.data.map(item => {
return (
<View style={style.searchResultsWrapper} key={'ev' + item.id}>
<EventItem data={item}></EventItem>
</View>
)
})
}
</View>
)
}
I need to make the non-working code to work. Actually the alert line executes fine, so it means that's iterating fine. However this can't render results. Any clue ?
I just put the working code to demonstrante that this works ok without the filter. Is there something that I did't get it ?

Actually, your code run properly with some change like in the below in my demo code. Maybe you look your all component and try with a component like in the below.
<View>
{
this.props.events.data.data.filter(flt =>
flt.location.toLowerCase().includes(this.state.searchText.toLowerCase()))
.map(item => {
alert(item)
return (<View key={'ev' + item.id}>
<Text>{item.location}</Text>
</View>)
})
}
</View>

Related

nothing was returned from render but can't be fixed

I don't know what I did wrong in this function, I thought I had a return but I don't think it's being considered, and when I change the closing brackets or parenthesis it shows an error :/
Can someone help me?
function PopSheet() {
let popupRef = React.createRef()
const sheet =() => {
const onShowPopup =()=> {
popupRef.show()
}
const onClosePopup =()=> {
popupRef.close()
}
return (
<SafeAreaView style ={styles.container}>
<TouchableWithoutFeedback onPress={onShowPopup}>
</TouchableWithoutFeedback>
<BottomPopup
title="Demo Popup"
ref ={(target) => popupRef =target}/>
onTouchOutside={onClosePopup}
</SafeAreaView>
);
}
};
You need to use the render function which is responsible for rendering or display the JSX element into your app.
render() {
return (
<SafeAreaView style={styles.container}>
<TouchableWithoutFeedback
onPress={onShowPopup}></TouchableWithoutFeedback>
<BottomPopup title="Demo Popup" ref={target => (popupRef = target)} />
onTouchOutside={onClosePopup}
</SafeAreaView>
);
}

ListItem not showing information - React Native Elements

When I use it works fine.
But when I try to use , nothing appears.
That's my code:
export default props => {
//console.warn(Object.keys(props))
function getUserItem({item: user}) {
console.warn(user.name)
return (
<ListItem
leftAvatar={{source: {uri: user.avatarUrl}}}
key={user.id}
title={user.name}
/>
)
}
return (
<View>
<FlatList
keyExtractor={user=>user.id.toString()}
data={users}
renderItem={getUserItem}
/>
</View>
)
}
Can anybody helps me? Thank you!!!
Use this way
<View style={{flex:1}}>
...
</View>
const getUserItem = ({item: user}) => {
...
}

ReactiveSearch how to stop initial query on load

So I've got ReactiveSearch working fine but I've noticed on the initial load it performs a query to fetch items - given my index will have perhaps a million items in it I'd ideally like to turn this off and only return results from the autosuggest?
<ReactiveBase
app="tths-shop-items"
url="my-es-cluster"
credentials="user:password"
>
<ScrollView>
<View style={styles2.container}>
<DataSearch
componentId="searchbox"
dataField={[
'name'
]}
placeholder="Search"
/>
<ReactiveList
componentId="results"
dataField="name"
size={7}
showResultStats={true}
pagination={true}
react={{
and: "searchbox"
}}
onData={(res) => {
return (
<View style={styles2.result}>
<Image source={{ uri: res.image.replace('http', 'https') }} style={styles2.image} />
<View style={styles2.item}>
<Text style={styles2.title}>{res.name}</Text>
</View>
</View>
)}
}
/>
</View>
</ScrollView>
</ReactiveBase>
EDIT
I also tried adding the default value in order to try and stop the initial query returning data. But it doesn't seem to work as expected.
defaultValue="3245423 kjhkjhkj 2kj34h12jkh 213k4jh12"
EDIT 2:
I've also tried defaultQuery in the following format and added it to the reactiveList and dataSearch components this gives me an error which is undefined is not an object 'this.defaultQuery.sort' - if I add sort to both queries it makes no difference:
defaultQuery={() =>
{
query: {
match_none: {}
}
}
}
I know it's an old question, but I stumbled upon the same problem.
My solution looks a little bit different - with the onQueryChange prop.
onQueryChange={
function(prevQuery, nextQuery) {
if ('match_all' in nextQuery['query']) {
nextQuery['query'] = { match_none: {} }
}
}
}
This will disable the ResultList with all results showing and only show results after you've selected any filter or entered a search term.
So here's one answer, you store the value that you click via the searchbox in state and then fiddle with the defaultQuery from there. Note default query does match_none: {} if there's no search text.
It's a bit inefficient as you still do a query that returns nothing, but it works - I'll leave this question open to give any better answers time to come up.
<ScrollView>
<View style={styles.mainContainer}>
<DataSearch
componentId="searchbox"
dataField={[
'name'
]}
placeholder="Search"
queryFormat="and"
noInitialQuery={true}
onValueChange={(value) => {
if(value === ''){
this.setState({searchText: null})
}
}}
onValueSelected={(value, cause, source) => {
this.setState({searchText: value.value})
}
}
/>
<ReactiveList
componentId="results"
dataField="name"
size={7}
showResultStats={true}
pagination={true}
react={{
and: "searchbox"
}}
defaultQuery={()=> {
if(this.state.searchText !== null){
return {
query: {
match: {
name: this.state.searchText
}
}
}
} else {
return {
query: {
match_none: {}
}
}
}
}}
onData={(res) => {
return (
<View style={styles2.result}>
<Image source={{ uri: res.image.replace('http', 'https') }} style={styles2.image} />
<View style={styles2.item}>
<Text style={styles2.title}>{res.name}</Text>
</View>
</View>
)}
}
/>
</View>
</ScrollView>
The selected answer was very useful but I changed the defaultQuery to use the original query in the event a search term is present:
defaultQuery={()=> {
if(this.state.searchText !== null){
return {
}
} else {
return {
query: {
match_none: {}
}
}
}
}}

how to use if condition in .map function?

Hi, I used if condition like below, but there is nothing rendering on the screen. By the way, there is 'MAVI' in leader array
renderall() {
return this.state.leader.map(alb => {
if(alb.Renk == 'MAVI') {
<View style={styles.container} key={counter = counter + 1}>
<Text style={[styles.textStyle, {marginLeft:'5%'}]}> {alb.Tescil_No} </Text>
<Text style={[styles.textStyle, {marginLeft:'6%'}]}> {alb.GumrukAdi} </Text>
<Text style={[styles.textStyle, { marginLeft:'5%'}]}> {alb.ACIKLAMA} </Text>
</View>
}
});
}
You're missing a return in your .map. Notice that inside the if statement I am returning the items being mapped.
renderall() {
return this.state.leader.map(alb => {
if(alb.Renk == 'MAVI') {
return (
<View style={styles.container} key={counter = counter + 1}>
<Text style={[styles.textStyle, {marginLeft:'5%'}]}> {alb.Tescil_No} </Text>
<Text style={[styles.textStyle, {marginLeft:'6%'}]}> {alb.GumrukAdi} </Text>
<Text style={[styles.textStyle, { marginLeft:'5%'}]}> {alb.ACIKLAMA} </Text>
</View>
);
}
});
}
This article explains in more detail how the .map function works
https://codeburst.io/learn-understand-javascripts-map-function-ffc059264783
Here is a very small example showing how to use the .map function. Notice the return statement.
let leaders = ['Tom','Jerry','Mike'];
let mappedLeaders = leaders.map((leader, index) => {
return `${leader} is number ${index}`; // notice that I am returning here
})
console.log(mappedLeaders)
Here is an example of using a .map with an if statement inside it. Notice we will get undefined for the first item in the mappedLeaders as we are not returning anything for the first item because Tom is excluded due to the fact that his name is too short.
let leaders = ['Tom','Jerry','Mike'];
let mappedLeaders = leaders.map((leader, index) => {
if (leader.length > 3) {
return `${leader} is number ${index}`; // notice that I am returning here
}
});
console.log(mappedLeaders)

How to implement a collapsible box in react native?

I am trying to implement a collapsible box in react native.Its working fine for dummy data. But when i tried to list the data response from server i'm getting error.I'm using map method over the response for listing the details.But showing error evaluating this.state.details.map.Also i'm confused to where to place the map method.Below is the code that i've tried.I refer this doc for collapsible box.
Example
class DetailedView extends Component{
constructor(props){
super(props);
this.icons = {
'up' : require('../Images/Arrowhead.png'),
'down' : require('../Images/Arrowhead-Down.png')
};
this.state = {
title : props.title,
expanded : true,
animation : new Animated.Value()
};
}
toggle(){
let initialValue = this.state.expanded? this.state.maxHeight + this.state.minHeight : this.state.minHeight,
finalValue = this.state.expanded? this.state.minHeight : this.state.maxHeight + this.state.minHeight;
this.setState({
expanded : !this.state.expanded
});
this.state.animation.setValue(initialValue);
Animated.spring(
this.state.animation,
{
toValue: finalValue
}
).start();
}
_setMaxHeight(event){
this.setState({
maxHeight : event.nativeEvent.layout.height
});
}
_setMinHeight(event){
this.setState({
minHeight : event.nativeEvent.layout.height
});
}
state = {details: []};
componentWillMount(){
fetch('https://www.mywebsite.com' + this.props.navigation.state.params.id )
.then((response) => response.json())
.then((responseData) =>
this.setState({
details:responseData
})
);
}
render(){
let icon = this.icons['down'];
if(this.state.expanded){
icon = this.icons['up'];
}
return this.state.details.map(detail =>
<Animated.View
style={[styles.container,{height: this.state.animation}]}>
{detail.data.curriculum.map(curr =>
<View onLayout={this._setMinHeight.bind(this)}>
<Card>
<CardSection>
<View style={styles.thumbnailContainerStyle}>
<Text style={styles.userStyle}>
Hii
</Text>
</View>
<TouchableHighlight onPress={this.toggle.bind(this)}
underlayColor="#f1f1f1">
<Image style={styles.buttonImage} source={icon}></Image>
</TouchableHighlight>
</CardSection>
</Card>
</View>
<View style={styles.body} onLayout={this._setMaxHeight.bind(this)}>
{this.props.children}
<Card>
<CardSection>
<Text>{this.props.navigation.state.params.id}</Text>
</CardSection>
</Card>
</View>
)}
</Animated.View>
);
}
}
This is the screenshot for working code with dummy data
1. Solving the Error :
The API call you are making is asynchronous and once the API is called, the code continues to execute before getting the response from the API. The component tries to map through this.state.details before there are any details.
A solution here is that you need to set an ActicityIndicator/Loader initially when component is mounted and once you get the details/response from the API, the state changes and then you can map through this.state.details
Add empty details array to your initial state.
state = { details:[] }
Then put your return this.state.details.map(detail.... Inside an if condition like this
if(this.state.details.length > 0) {
<map here>
} else {
return <ActivityLoader />
}
2. Where to place the map methiod
You need to put it inside a function and call that function from within you render method.
showDetailsFunction() {
return this.state.details.map(detail =>
}
render() {
return(
{this.showDetailsFunction()}
)
}