Lodesh Filter is giving mid string data - react-native

I am new with React Native and facing issue with Lodesh Filter. It is giving mid-string data. Ex if I want to search Mitsubishi and start typing "mi" it will not give me mitsubishi but if I start type "sub" then it is giving me mitsubishi.
Below is my code:
import React, { useEffect, useState } from 'react';
import {View, Text, Button, TextInput, FlatList, ActivityIndicator, StyleSheet, Image} from 'react-native';
import filter from 'lodash.filter';
const CarList = () => {
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState([]);
const [error, setError] = useState(null);
const [query, setQuery] = useState('');
const [fullData, setFullData] = useState([]);
useEffect(() => {
setIsLoading(true);
fetch(`https://myfakeapi.com/api/cars/?seed=1&page=1&results=20`)
.then(response => response.json())
.then(response => {
setData(response.cars);
setFullData(response.cars);
setIsLoading(false);
})
.catch(err => {
setIsLoading(false);
setError(err);
});
}, []);
if (isLoading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" color="#5500dc" />
</View>
);
}
if (error) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontSize: 18}}>
Error fetching data... Check your network connection!
</Text>
</View>
);
}
const handleSearch = text => {
const formattedQuery = text.toLowerCase();
const filteredData = filter(fullData, user => {
console.log(contains(user, formattedQuery));
return contains(user, formattedQuery);
});
setData(filteredData);
setQuery(text);
};
const contains = ({ car, car_model,car_color }, query) => {
if (car.includes(query) || car_model.includes(query) || car_color.includes(query)) {
return true;
}
return false;
};
function renderHeader() {
return (
<View
style={{
backgroundColor: '#fff',
padding: 10,
marginVertical: 10,
borderRadius: 20
}}
>
<TextInput
autoCapitalize="none"
autoCorrect={false}
clearButtonMode="always"
value={query}
onChangeText={queryText => handleSearch(queryText)}
placeholder="Search"
style={{ backgroundColor: '#fff', paddingHorizontal: 20 }}
/>
</View>
);
}
return (
<View style={styles.container}>
<Text style={styles.text}>Favorite Contacts</Text>
<FlatList
ListHeaderComponent={renderHeader}
data={data}
keyExtractor={({ id }) => id}
renderItem={({ item }) => (
<View style={styles.listItem}>
<Image
source={{
uri: 'https://picsum.photos/200',
}}
style={styles.coverImage}
/>
<View style={styles.metaInfo}>
<Text style={styles.title}>{`${item.car} ${
item.car_model
}`}</Text>
</View>
</View>
)}
/>
</View>
);
}

Each car record have following fields:
{
"id": 1,
"car": "Mitsubishi",
"car_model": "Montero",
"car_color": "Yellow",
"car_model_year": 2002,
"car_vin": "SAJWJ0FF3F8321657",
"price": "$2814.46",
"availability": false
}
When you write mit, in contain function you are checking if(car.includes(text)...) but car name starts with an uppercase letter. You need to convert the car name in lowerCase before checking the text like this:
const contains = ({ car, car_model, car_color }, query) => {
if (car.toLowerCase().includes(query) || car_model.toLowerCase().includes(query) || car_color.toLowerCase().includes(query)) {
return true;
}
return false;
};

Related

How to put the bottomsheet to the front of the screen?

In ReactNative, the bottomsheet is displayed overlaid on the fragment.
Is there a way to make the bottomsheet rise to the top of the screenenter image description here
The bottom sheet looks opaque as in the picture, so the bottom sheet cannot be touched Please help
The code below is a shortened version
enter image description here
enter image description here
import React, { FC , Component, useState, useEffect, Fragment,useCallback, useMemo, useRef } from "react"
import { FlatList, ViewStyle, StyleSheet, View, Platform, TextInput, TouchableOpacity} from "react-native"
import {
BottomSheetModal,
BottomSheetModalProvider,
BottomSheetBackdrop,
} from '#gorhom/bottom-sheet';
const ROOT: ViewStyle = {
backgroundColor: DefaultTheme.colors.background,
flex: 1,
}
export const ChecklookupScreen: FC<StackScreenProps<NavigatorParamList, "checklookup">> = observer(function ChecklookupScreen() {
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
// variables
const snapPoints = useMemo(() => ['25%', '50%'], []);
// callbacks
const handlePresentModalPress = useCallback((index: string) => {
LOG.info('handlePresentModalPress', index);
bottomSheetModalRef.current?.present();
}, []);
const handleSheetChanges = useCallback((index: number) => {
LOG.info
console.log('handleSheetChanges', index);
}, []);
const renderItem = ({ item, index }) => (
<TouchableOpacity
key={index + item.inspNo + item.spvsNo}
//style={listContainer}
onPress={throttle(() => {
onClickItem(item.inspNo,item.spvsNo);
})}
>
<View>
<Fragment>
</View>
<Button icon="magnify-expand"
mode="elevated"
style={styles.detailButton}
onPress={throttle(() => {
onClickItem(item.inspNo,item.spvsNo);
})}
// onPress={() => navigation.navigate("checkdetail")}
>
</Button>
</View>
</Fragment>
</View>
</TouchableOpacity>
);
const fetchChecklookups = async (offset: number) => {
LOG.debug('fetchChecklookups:' + offset);
setRefreshing(true);
await checklookupStore.getChecklookups(offset)
setRefreshing(false);
};
const onEndReached = () => {
if (checklookupStore?.checklookupsTotalRecord <= checklookups?.length) {
LOG.debug('onEndReached555555555');
} else {
setPage(page + 1)
fetchChecklookups(page + 1);
}
};
const [searchQuery, setSearchQuery] = React.useState('');
const onChangeSearch = query => setSearchQuery(query);
return (
<Screen preset="fixed" style={{ backgroundColor: colors.background, flex: 1, padding: 10,}}>
<View style={{ flex: 1,}}>
<View style={{ flex: 1, }}>
<Searchbar
placeholder="조회조건을 입력해주세요"
onChangeText={onChangeSearch}
value={searchQuery}
onPressIn={() => handlePresentModalPress('touch on')}
/>
<BottomSheetModalProvider>
<BottomSheetModal
backgroundStyle={{ backgroundColor: "gray" }}
style={styles.bottomSheet}
ref={bottomSheetModalRef}
index={1}
snapPoints={snapPoints}
onChange={handleSheetChanges}
>
<View style={{ marginTop: 10, marginLeft: 50, marginRight: 50, flexDirection: "row"}}>
<View style={{ flex: 1, }}>
<Button
mode="outlined"
>소속을 입력하세요
</Button>
</View>
</View>
</BottomSheetModal>
</BottomSheetModalProvider>
</Screen>
)
})
You can try with portal, wrap you bottom sheet to from another package.

Error in uploading image with 'react-native-image-picker' library

I am creating an android application and I need to use the react-native-image-picker library but it is showing some error, the error is:
[Unhandled promise rejection: TypeError: null is not an object (evaluating '_reactNative.NativeModules.ImagePickerManager.launchImageLibrary')]
I have tried everything like changing to different versions as well, also I have used expo-image-picker which does not show an error while fetching an image from android but gives an error when uploading it to firebase.
Please help, I have been frustrated with this error.
import {
View,
Text,
Image,
StyleSheet,
KeyboardAvoidingView,
TouchableOpacity,
ActivityIndicator
} from "react-native";
import React, { useState } from "react";
import { TextInput, Button } from "react-native-paper";
import ImagePicker, { launchImageLibrary } from "react-native-image-picker";
import storage from "#react-native-firebase/storage";
import auth from '#react-native-firebase/auth';
import firestore, {getStorage, ref, uploadBytes} from '#react-native-firebase/firestore';
export default function SignUp({ navigation }) {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [image, setImage] = useState(null);
const [shownext, setShownext] = useState(false);
const [loading, setLoading] = useState(false);
if (loading) {
return <ActivityIndicator size='large' />
}
const userSignUp = async () => {
setLoading(true)
if (!email || !password || !image || !name) {
alert('fill all details correctly')
return false;
}
try {
const result = await auth().createUserWithEmailAndPassword(email, password);
firestore().collection('users').doc(result.user.uid).set({
name: name,
email: result.user.email,
uid: result.user.uid,
pic:image
})
setLoading(false)
}catch (err) {
alert('something went wrong from your side')
}
}
const pickImageAndUpload = () => {
console.log(1);
launchImageLibrary({ puality: 0.5 }, async (fileobj) => {
console.log(2);
console.log(fileobj);
const uploadTask = storage().ref().child(`/userprofilepic/${Date.now()}`).putFile(fileobj.uri);
uploadTask.on(
"state_changed",
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
if (progress == 100) alert("image uploaded");
},
(error) => {
alert("error uploading image");
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
setImage(downloadURL);
});
}
);});
};
return (
<KeyboardAvoidingView behavior="position" style={{ alignItems: "center" }}>
<View style={styles.box1}>
<Text style={styles.text}>Welcome to chatapplication</Text>
<Image style={styles.img} source={require("../assets/wa-logo.png")} />
</View>
{!shownext && (
<>
<TextInput
style={{ width: 330, marginTop: 50, marginBottom: 30 }}
label="Email"
value={email}
mode="outlined"
onChangeText={(text) => setEmail(text)}
/>
<TextInput
style={{ width: 330, marginBottom: 30 }}
label="Password"
value={password}
mode="outlined"
onChangeText={(text) => setPassword(text)}
secureTextEntry
/>
</>
)}
{shownext ? (
<>
<TextInput
style={{ width: 330, marginTop: 50, marginBottom: 30 }}
label="Name"
value={name}
mode="outlined"
onChangeText={(text) => setName(text)}
/>
<Button
style={{ marginBottom: 30 }}
mode="contained"
onPress={() => { pickImageAndUpload() }}
>
Upload Profile Pic
</Button>
<Button
disabled={image?false:true}
mode="contained"
onPress={() => { userSignUp() }}>
SignUp
</Button>
</>
) : (
<Button
// disabled={email&&password?false:true}
mode="contained"
onPress={() => {
setShownext(true);
}}
>
Next
</Button>
)}
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text style={{ margin: 10, textAlign: "center", fontSize: 18 }}>
Already have an account?
</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
);
}
const styles = StyleSheet.create({
text: {
fontSize: 22,
color: "green",
margin: 20,
},
img: {
width: 200,
height: 200,
},
box1: {
alignItems: "center",
},
});

How do i pass the value in counter component to the add to the To Cart Button

Hi I have a add minus component button that I want to pass the value to selected value to the "To Cart" button. If the value is zero the orders will not be added but if the value is > 0 then it will be added to cart.
below is my Add Minus button component
AddMinusButton.js
import React, { useState } from "react";
import { View, TouchableOpacity, Text, StyleSheet } from "react-native";
import Colors from "../../constants/Colors";
const AddMinusButton = () => {
const [value, setValue] = useState(0);
const minusValue = () => {
if (value > 0) {
setValue(value - 1);
} else {
setValue(0);
}
};
const plusValue = () => {
setValue(value + 1);
};
return (
<View style={styles.container}>
<TouchableOpacity style={styles.buttonLeft} onPress={minusValue}>
<Text>-</Text>
</TouchableOpacity>
<Text style={styles.quantity}> {value}</Text>
<TouchableOpacity style={styles.buttonRight} onPress={plusValue}>
<Text>+</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: "row",
alignItems: "center",
borderWidth: 1,
borderRadius: 10,
height: 35,
overflow: "hidden",
borderColor: "black",
},
quantity: {
paddingHorizontal: 10,
marginRight: 3,
},
buttonLeft: {
alignItems: "center",
backgroundColor: Colors.primary,
borderRightWidth: 1,
borderRightColor: "black",
padding: 10,
},
buttonRight: {
alignItems: "center",
backgroundColor: Colors.primary,
borderLeftWidth: 1,
borderLeftColor: "black",
padding: 10,
},
});
export default AddMinusButton;
This is my Product Screen. I want to pass the value that is selected by the AddMinusButton component to the "To Cart". I am only able to made the button click and it will add one by one.
ProductOverviewScreen.js
import React, { useState, useEffect, useCallback } from "react";
import {
View,
Text,
FlatList,
Button,
Platform,
ActivityIndicator,
StyleSheet,
} from "react-native";
import { useSelector, useDispatch } from "react-redux";
import { HeaderButtons, Item } from "react-navigation-header-buttons";
import HeaderButton from "../../components/UI/HeaderButton";
import ProductItem from "../../components/shop/ProductItem";
import * as cartActions from "../../store/actions/cart";
import * as productsActions from "../../store/actions/products";
import Colors from "../../constants/Colors";
import * as AddMinusButton from "../../components/UI/AddMinusButton";
const ProductsOverviewScreen = (props) => {
const [isLoading, setIsLoading] = useState(false);
const [isRefreshing, setIsRefreshing] = useState(false);
const [error, setError] = useState();
const products = useSelector((state) => state.products.availableProducts);
const dispatch = useDispatch();
const loadProducts = useCallback(async () => {
setError(null);
setIsRefreshing(true);
try {
await dispatch(productsActions.fetchProducts());
} catch (err) {
setError(err.message);
}
setIsRefreshing(false);
}, [dispatch, setIsLoading, setError]);
useEffect(() => {
const willFocusSub = props.navigation.addListener(
"willFocus",
loadProducts
);
return () => {
willFocusSub.remove();
};
}, [loadProducts]);
useEffect(() => {
setIsLoading(true);
loadProducts().then(() => {
setIsLoading(false);
});
}, [dispatch, loadProducts]);
const selectItemHandler = (id, title) => {
props.navigation.navigate("ProductDetail", {
productId: id,
productTitle: title,
});
};
if (error) {
return (
<View style={styles.centered}>
<Text>An error occurred!</Text>
<Button
title="Try again"
onPress={loadProducts}
color={Colors.primary}
/>
</View>
);
}
if (isLoading) {
return (
<View style={styles.centered}>
<ActivityIndicator size="large" color={Colors.primary} />
</View>
);
}
if (!isLoading && products.length === 0) {
return (
<View style={styles.centered}>
<Text>No products found. Maybe start adding some!</Text>
</View>
);
}
return (
<FlatList
onRefresh={loadProducts}
refreshing={isRefreshing}
data={products}
keyExtractor={(item) => item.id}
renderItem={(itemData) => (
<ProductItem
image={itemData.item.imageUrl}
title={itemData.item.title}
price={itemData.item.price}
onSelect={() => {
selectItemHandler(itemData.item.id, itemData.item.title);
}}
>
<AddMinusButton />
<Button
color={Colors.primary}
title="To Cart"
onPress={() => {
dispatch(cartActions.addToCart(itemData.item));
}}
/>
</ProductItem>
)}
/>
);
};
ProductsOverviewScreen.navigationOptions = (navData) => {
return {
headerTitle: "All Products",
headerLeft: (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Menu"
iconName={Platform.OS === "android" ? "md-menu" : "ios-menu"}
onPress={() => {
navData.navigation.toggleDrawer();
}}
/>
</HeaderButtons>
),
headerRight: (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Cart"
iconName={Platform.OS === "android" ? "md-cart" : "ios-cart"}
onPress={() => {
navData.navigation.navigate("Cart");
}}
/>
</HeaderButtons>
),
};
};
const styles = StyleSheet.create({
centered: { flex: 1, justifyContent: "center", alignItems: "center" },
});
export default ProductsOverviewScreen;

React Native - Data is not loaded in the screen but if reload the page I am able to see the data

I am new to React Native.
I am storing the some data like GUID, userID, company name , in AsyncStorage when user login to the apps for the first time. I want to load the department details in department page based on selected company name which tag to unique GUID.
I am able to get the data from the AsyncStorage. Now I need to pass the GUID to "setDepartment(GUID)" store then pass to fetch API to get the data from server.
Problem : The data not able to load open when I open the department page but if I refresh the page , I am able to see the data in the screen. I am not sure where I make the mistakes. I think it something do with useEffect and useCallback. Please Guide Me. Thank You.
const DepartmentScreen = (props) => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(false);
const departments = useSelector((state) => state.departments.allDepartment);
const dispatch = useDispatch();
const [GUID, setGUID] = useState("");
const getData = useCallback(async () => {
try {
AsyncStorage.getItem("companyData").then((companyData) => {
let parsed = JSON.parse(companyData);
setGUID(parsed.GUID);
console.log(GUID);
});
} catch (error) {
console.log(error);
}
}, []);
useEffect(() => {
getData();
}, [dispatch, getData]);
const loadDepartment = useCallback(async () => {
setError(null);
setIsLoading(true);
try {
//getData();
await dispatch(departmentAction.setDepartment(GUID));
} catch (err) {
setError(err.message);
}
setIsLoading(false);
}, [dispatch, setIsLoading, setError]);
useEffect(() => {
loadDepartment();
}, [dispatch, loadDepartment]);
if (error) {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>
AN ERROR OCCURRED {error} + {GUID}
</Text>
<Button title="Reload" onPress={loadDepartment} />
</View>
);
}
if (isLoading) {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<ActivityIndicator size="large" />
</View>
);
}
if (!isLoading && departments.length === 0) {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>NO DEPARTMENT FOUND</Text>
</View>
);
}
return (
<View style={{ flex: 1 }}>
<View style={styles.ButtonView}>
<View>
<Button title="Listed" />
</View>
<View>
<Button title="De-Listed" />
</View>
</View>
<FlatList
data={departments}
renderItem={(itemData) => (
<DepartmentItem
name={itemData.item.deptName}
code={itemData.item.deptCode}
/>
)}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
};

Searchable flat list react native

I am trying to search items in a flatlist, whenever i type in the search bar it only take one letter and closes the keyboard and the value inside the search bar disappear,
example when i type "george" it only takes the letter g and re-render a list of names containing the letter g and delete what's inside the search bar
how can i fix this ?
import React, { useState, useEffect } from 'react';
import { ScrollView } from 'react-native';
import { View, Text, FlatList, ActivityIndicator, SafeAreaView, TouchableOpacity } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { Divider, SearchBar } from 'react-native-elements'
const Item = ({ name, lastName }) => (
<View>
<Text style={{ fontSize: 17, color: '#666', marginBottom: 10 }}>Full name: {name} {lastName}</Text>
</View>);
function Clients({ navigation }) {
const [isLoading, setLoading] = useState(true);
const usersApi = 'https://reqres.in/api/users'
const [users, setUsers] = useState([]);
const [search, setSearch] = useState("");
const [masterData, setMasterData] = useState("");
const fetchJson = async (userApi) => {
const response = await fetch(userApi);
return response.json()
}
useEffect(() => {
fetchJson(usersApi)
.then((users) => {
setUsers(users.data);
setMasterData(users.data);
})
.catch((error) => (alert(error)))
.finally(() => setLoading(false));
}, []);
const itemSeparator = () => {
return (
<Divider style={{ width: "105%", marginVertical: 3, alignSelf: 'center' }} />
)
}
const renderHeader = () => {
return (
<SearchBar
placeholder="Type Here..."
lightTheme
round
onChangeText={text => searchFilterFunction(text)}
autoCorrect={false}
/>
);
};
const searchFilterFunction = text => {
setSearch(text);
const newData = masterData.filter(item => {
const itemData = `${item.first_name.toUpperCase()} ${item.last_name.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setUsers(newData);
};
const renderItem = ({ item }) => (
<TouchableOpacity style={{
flex: 1,
padding: 10
}}
onPress={() => { navigation.navigate('Client', { item: item }); }}
underlayColor='#ccc'
activeOpacity={0.1} >
<Item name={item.first_name} lastName={item.last_name} />
</TouchableOpacity>
);
console.log(search)
console.log(users)
return (
<SafeAreaProvider>
<SafeAreaView>
<Text style={{ color: '#666', margin: 15, fontSize: 20 }}>Clients actuels</Text>
<View style={{
width: '96%',
backgroundColor: 'white',
borderRadius: 5,
alignSelf: 'center',
marginTop: 20,
}}>
<View style={{ margin: 15 }}>
{isLoading ? <ActivityIndicator size="large" /> :
<FlatList
data={users}
renderItem={renderItem}
ItemSeparatorComponent={itemSeparator}
ListHeaderComponent={renderHeader}
keyExtractor={item => item.id.toString()}
value={search}
/>}
</View>
</View>
</SafeAreaView>
</SafeAreaProvider>
);
}
export default Clients;