My current issue is filtering through a array of "lessons" with a search input. When a user first goes to the lessons components all the lessons are loaded if the search input text is nothing. When i type something though(if if it matches it) it will not show up and everything will just not show.
my code:(lessonCard is the component of each lesson)**took away the database query because it was too long
export default function Learn() {
const [lessons,setLessons] = useState([])
const [searchinput,setSearchInput] = useState("")
return (
<View style={learnStyle.maincont}>
<View style={learnStyle.learncont}>
<Text style={learnStyle.even}>EVVENNTI</Text>
<Text style={learnStyle.learn}>Learn</Text>
</View>
<View style={{marginTop:20,flexDirection:"row", width:"100%",alignItems:"center",backgroundColor:"#F3F5F9",borderRadius:20,paddingLeft:15}}>
<Feather name="search" size={24} color="#FF802C"style={{flex:0.1}} />
<TextInput style={{padding:20,borderRadius:20,flex:0.9}} placeholder="type lesson keyword" placeholderTextColor="grey" color="#000" value={searchinput} onChangeText={(val) => setSearchInput(val)}/>
</View>
{li ? <View style={{width:"100%",flexDirection:"row",marginTop:30,borderRadius:20,backgroundColor:"#CFECFE"}}>
<View style={{flex:0.5,padding:20}}>
<Text style={{fontSize:20,fontWeight:"700",marginBottom:20}}>What do you want to learn Today?</Text>
<View style={{backgroundColor:"#FF7F2D",padding:8,borderRadius:20}}>
<Button title='Get Started' color="#fff"/>
</View>
</View>
<View style={{flex:0.5,marginLeft:10}}>
<Image source={{uri:"https://cdn.discordapp.com/attachments/783336191529320498/1048439876741251072/Screen_Shot_2022-12-02_at_10.25.38_PM.png"}} style={{width:"100%",height:200,borderRadius:20}}/>
</View>
</View> : null}
<View>
<Text style={{fontSize:28,marginTop:20}}>Courses</Text>
<ScrollView style={{paddingBottom:200}}>
{searchinput === "" ? lessons.map((doc,key) =>
<>
<LessonCard key={key} setModalVisible={setModalVisible} title={doc.title} desc={doc.desc} img1={doc.imgURL} modalVisible={modalVisible} />
</>): lessons.filter((lessons) => {
if(searchinput.toLocaleLowerCase().includes(lessons.title)) {
<LessonCard key={key} setModalVisible={setModalVisible} title={doc.title} desc={doc.desc} img1={doc.imgURL} modalVisible={modalVisible} />
} else {null}
})}
<View style={{height:600,width:"100%"}}></View>
</ScrollView>
</View>
</View>
)
}
so basically im trying to see weather or not my search input includes the lesson title and if it does to show it like in this code below
{searchinput === "" ? lessons.map((doc,key) =>
<>
<LessonCard key={key} setModalVisible={setModalVisible} title={doc.title} desc={doc.desc} img1={doc.imgURL} modalVisible={modalVisible} />
</>): lessons.filter((lessons) => {
if(searchinput.toLocaleLowerCase().includes(lessons.title)) {
<LessonCard key={key} setModalVisible={setModalVisible} title={doc.title} desc={doc.desc} img1={doc.imgURL} modalVisible={modalVisible} />
} else {null}
})}
what would be the correct javascript/react syntax to fully show the lessons that match the search input?
CodePudding user response:
.filter returns an array based on the condition (which is .includes in your case). So you should write your filter logic and then calling .map on the filtered array to return your components.
<div>
<InfoBlock data={DATASET} />
<InfoBlock data={RAW_MEDIA} />
{
searchinput === "" ?
lessons.map((lesson, key) =>
<LessonCard key={key} setModalVisible={setModalVisible} title={lesson.title} desc={lesson.desc} img1={lesson.imgURL} modalVisible={modalVisible} />
)
:
lessons.filter((lesson) => searchinput.toLocaleLowerCase().includes(lesson.title) ? 1 : -1).map((lesson) => {
if(searchinput.toLocaleLowerCase().includes(lesson.title)) {
return <LessonCard key={key} setModalVisible={setModalVisible} title={lesson.title} desc={lesson.desc} img1={lesson.imgURL} modalVisible={modalVisible} />;
} else {
return null;
}
})
}
</div>
CodePudding user response:
Expanding on my comment (demo):
import React, { useEffect, useState } from 'react';
import { Text, View, StyleSheet, ScrollView,Image } from 'react-native';
import Constants from 'expo-constants';
import { TextInput } from 'react-native-paper';
export default function App() {
const [lessons, setLessons] = useState([]);
const [filteredLessons, setFilteredLessons] = useState([]);
const [searchinput, setSearchInput] = useState('');
useEffect(() => {
// fetch data on mount
const getData = async () => {
const results = await fetch('https://dummyjson.com/products');
const json = await results.json();
setLessons(json.products);
console.log(json.products[0])
};
getData();
}, []);
useEffect(() => {
// when lessons or searchinput changes update filteredLessons
const newLessons = lessons.filter((lesson) =>
lesson.title.toLowerCase().includes(searchinput.toLowerCase())
);
setFilteredLessons(searchinput.length < 1 ? lessons : newLessons);
}, [lessons, searchinput]);
return (
<View style={styles.container}>
<TextInput
value={searchinput}
onChangeText={setSearchInput}
label="Search"
dense
mode="outlined"
/>
<View style={{ flex: 1 }}>
<ScrollView
style={{ flex: 1 }}
>
{filteredLessons.map((item,i)=>{
return (
<View style={styles.item}>
<Text>{item.title}</Text>
<Image
source={{uri:item.images[0]}}
style={styles.image}
/>
</View>
);
})}
</ScrollView>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
image:{
width:150,
height:100
},
item: {
padding: 5,
margin: 5,
justifyContent:'center',
alignItems:'center'
},
});