I have an issue to solve, last days I was trying to update my DB in Firestore but unfortunately, I can't, I read the documentation and I read another from StackOverflow questions, but don't make my update function, don't know what I make wrong, bellow is my code.
here is my button who send to edit screen he is located in home Screen where I have a list of my information he is inside a map
<IconButton
icon={<Icon as={AntDesign} name="edit" color="success.900" />}
borderRadius="full"
onPress={() =>
navigation.navigate("EditScreen", { userId: user.id }) //here i passing a user id to
editing
}
/>
here is code of my EditScreen
export const EditScreen = ({ navigation }) => {
const [name, setName] = useState("");
const [cep, setCep] = useState("");
const [logradouro, setLogradouro] = useState("");
const [numero, setNumero] = useState("");
const [bairro, setBairro] = useState("");
const [uf, setUf] = useState("");
const usersCollectionRef = collection(db, "users");
const handleChangeName = (value) => setName(value);
const handleChangeCep = (number) => setCep(number);
const handleChangeLogradouro = (value) => setLogradouro(value);
const handleChangeNumero = (number) => setNumero(number);
const handleChangeBairro = (value) => setBairro(value);
const handleChangeUf = (value) => setUf(value);
const updateUser = async (id) => {
const userDoc = doc(usersCollectionRef, id);
const newFields = {
name: handleChangeName,
cep: handleChangeCep,
logradouro: handleChangeLogradouro,
numero: setNuhandleChangeNumeromero,
bairro: handleChangeBairro,
uf: handleChangeUf,
};
await updateDoc(userDoc, newFields);
navigation.navigate("HomeScreen");
};
return (
<SafeAreaView style={{ backgroundColor: "#D4D4D8" }}>
<Center h="100%" bg="dark.600">
<Box ml="-300px" mb="80px" flexDirection="row" alignItems='center'>
<IconButton
size="lg"
icon={<Icon as={AntDesign} name="left" color="orange.600" />}
borderRadius="full"
onPress={() => navigation.navigate("HomeScreen")}
/>
</Box>
<Box mb="25px" w="360px">
<FormControl.Label ml="12px">
<Text bold>Nome</Text>
</FormControl.Label>
<TextInput value={name} onChangeText={handleChangeName} />
</Box>
<Box w="360px">
<FormControl.Label ml="12px">
<Text bold>CEP</Text>
</FormControl.Label>
<TextInput value={cep} onChangeText={handleChangeCep} />
</Box>
<Text fontSize="12px">
busque automaticamente seu edereço atraves do cep
</Text>
<Box flexDirection="row" mt="47px">
<Box w="208px" mr="34px">
<FormControl.Label ml="12px">
<Text bold>Logradouro</Text>
</FormControl.Label>
<TextInput
value={logradouro}
onChangeText={handleChangeLogradouro}
/>
</Box>
<Box w="109px">
<FormControl.Label ml="12px">
<Text bold>Número</Text>
</FormControl.Label>
<TextInput value={numero} onChangeText={handleChangeNumero} />
</Box>
</Box>
<Box flexDirection="row" mt="16px">
<Box w="208px" mr="34px">
<FormControl.Label ml="12px">
<Text bold>Bairro</Text>
</FormControl.Label>
<TextInput value={bairro} onChangeText={handleChangeBairro} />
</Box>
<Box w="109px">
<FormControl.Label ml="12px">
<Text bold>UF</Text>
</FormControl.Label>
<TextInput value={uf} onChangeText={handleChangeUf} />
</Box>
</Box>
<Box mt="50px">
<PrimaryButton onPress={updateUser}>salvar</PrimaryButton>
</Box>
</Center>
</SafeAreaView>
);
};
I'm unaware of the exact issue in this case. However, you do not include where any firebase is updated, only JS for the updating data from the user's perspective. My best advice is to follow the data you care about through console.log() and check whether the data is making to each endpoint.
Best of luck.
Update your updateUser fuction. I think it will work
const updateUser = async (id) => {
const newFields = {
name,
cep,
logradouro,
numero,
bairro,
uf,
};
firestore()
.collection('users')
.doc(id)
.update(newFields)
.then(() => navigation.navigate("HomeScreen"));
.catch(error => console.error('firestore Error', error));
};
Related
I have a react native modal with a search bar and a flatlist that shows results. The search result in the flatlist has to be tapped twice for the click to register. I need to figure out how to make it work on first click. Here is the code
const Item = ({ item, onPress, value }) => (
<TouchableOpacity style={styles.modalItemStyle} onPress={onPress}>
<View style={styles.modalIconStyle}>
{item.id === value && <Icon name="sheep" size={20} color="#68c25a" />}
</View>
<Text style={styles.modalItemTextStyle}>{item.title}</Text>
</TouchableOpacity>
);
const MyDropdown = ({
data,
label,
field,
onSelect,
value,
searchable = true,
}) => {
const [modalOpen, setModalOpen] = useState(false);
const [selectedValue, setSelectedValue] = useState(value);
const [query, setQuery] = useState("");
const [modalData, setModalData] = useState(data);
useEffect(() => {
if (query.length > 0) {
const filteredData = data.filter((item) =>
item.title.toLowerCase().includes(query.toLowerCase())
);
setModalData(filteredData);
} else {
setModalData(data);
}
}, [query]);
const inputRef = useRef(null);
const searchRef = useRef(null);
const renderItem = ({ item }) => {
return (
<Item
item={item}
value={selectedValue.id}
onPress={() => {
inputRef.current.blur();
Keyboard.dismiss();
setQuery("");
setSelectedValue(item);
setModalOpen(false);
}}
/>
);
};
return (
<View style={styles.selectContainer}>
<TextInput
ref={inputRef}
//react native paper text input with value and label
label={label}
value={selectedValue.title}
style={styles.sheepTextInput}
mode="outlined"
onChangeText={(text) => onSelect(text)}
showSoftInputOnFocus={false}
onFocus={() => {
setModalOpen(true);
inputRef.current.blur();
}}
></TextInput>
<Modal height="auto" isVisible={modalOpen}>
<View style={styles.modal}>
{searchable && (
<View>
<TextInput
ref={searchRef}
mode="outlined"
outlineColor="#68c25a"
activeOutlineColor="#68c25a"
style={styles.modalSearch}
value={query}
onChangeText={(q) => setQuery(q)}
placeholder="Search"
//add clear button
right={
<TextInput.Icon
name="close"
color="#68c25a"
onPress={() => {
setQuery("");
}}
/>
}
></TextInput>
</View>
)}
<FlatList
keyboardShouldPersistTaps="always"
data={modalData}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
</Modal>
</View>
);
};
I tried adding keyboardShouldPersistTaps with different options to flatlist, I also tried to blur through refs (searchref), but none of those approaches worked. What am I doing wrong?
keyboardShouldPersistTaps should be "handled" if you want it to work on first tap.
<FlatList
keyboardShouldPersistTaps="handled"
data={modalData}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
I managed to fix this by setting the keyboardshouldpersisttaps property to handled on every scrollview, including the flatlist in question and the component that renders all of those inputs in my form. I also had to wrap the flatlist with the search input in a scrollview. Of course I now have a virtualized lists should never be nested warning, but at least the taps now work.
I'm working on a project that allows users to write anonymous letters addressed to people by name and I want to add a like/dislike functionality to the app. I was confused on how to get the specific document ID for that post and also incrementing the likeCount by 1 (in the areas where the "????" are at in the code below) ? I want it to update the field "likeCount" in firebase by 1 when the thumbs up icon is pressed.
This is the portion of my code that contains the posts (data from firebase) that is mapped for each firebase document:
function Home() {
const [posts, setPosts] = useState([]);
const [searchValue, setSearchValue] = useState("");
const [filteredPosts, setFilteredPosts] = useState([]);
const collectionRef = collection(db, "posts");
useEffect(() => {
const getPosts = async () => {
const data = await getDocs(collectionRef);
const filteredRef = query(
collectionRef,
where(`recipiant`, "==", `${searchValue}`)
);
const querySnapshot = await getDocs(filteredRef);
let posts = [];
querySnapshot.forEach((doc) => {
posts.push(doc.data());
});
setFilteredPosts(posts);
setPosts(
searchValue
? filteredPosts
: data.docs.map((doc) => ({ ...doc.data() }))
);
};
getPosts();
}, [searchValue, filteredPosts]);
return (
<ImageBackground source={image} style={styles.image}>
<SafeAreaView style={styles.container}>
<ScrollView>
<View style={styles.header}>
<Text style={styles.title}>Home</Text>
</View>
<Pressable>
<Input
placeholder="Search for a name"
inputContainerStyle={styles.searchbar}
inputStyle={styles.searchInput}
placeholderTextColor="gray"
onChangeText={(text) => setSearchValue(text)}
/>
</Pressable>
{posts.map((post, key) => {
return (
<View style={styles.postWrapper} key={key}>
<View style={styles.btnWrapper}>
<View style={styles.likeBtn}>
<Icon
name="thumbs-up"
size={25}
color="#fff"
onPress={() => {
const postRef = doc(db, "posts", `????`);
updateDoc(postRef, {
likeCount: ????,
});
}}
/>
<Text style={styles.likeCount}>{post.likeCount}</Text>
</View>
<Icon
name="thumbs-down"
size={25}
color="#fff"
onPress={() => {}}
/>
</View>
<Card
containerStyle={{
backgroundColor: "rgba( 255, 255, 255, 0.5 )",
borderRadius: 50,
height: 300,
marginBottom: 25,
width: 330,
backdropFilter: "blur( 20px )",
padding: 20,
}}
>
<Card.Title style={styles.notepadHeader}>Message.</Card.Title>
<View style={styles.center}>
<ScrollView>
<Text style={styles.notepadText}>
To: <Text style={styles.name}>{post.recipiant}</Text>
</Text>
<Text style={styles.notepadTextLetter}>
{post.letter}
</Text>
<Text style={styles.notepadFooter}>
From:{" "}
<Text
style={{
color: "#9e4aba",
fontSize: 20,
}}
>
{post.displayName}
</Text>
</Text>
</ScrollView>
</View>
</Card>
</View>
);
})}
</ScrollView>
</SafeAreaView>
</ImageBackground>
);
}
This is how my Firestore looks like and I want to retrieve the document id in the circle.
First, you can add the document ID in 'posts' array as shown below:
const posts = querySnapshot.docs.map((d) => ({ id: d.id, ...d.data() }));
setFilteredPosts(posts);
Then you can read post ID when required:
<Icon
name = "thumbs-up"
size = {25}
color = "#fff"
onPress = {() => {
const postRef = doc(db, "posts", post.id);
updateDoc(postRef, {
likeCount: ?? ?? ,
});
}
}
/>
This will give you the particular doc and perform updateDoc query accordingly.
query(collections('collection_name), where(documentId(), '==', 'your_post_id'))
when i try to update my data i see this bug.
const saveResult = async ()=>{
if(akiec=="" || bcc=="" ||bkl=="" ||df=="" ||melanoma=="" ||nv=="" ||vasc==""){
alert("Something is empty!!")
}
else{
await setLoading(true)
await firebase
.firestore()
.collection(`Users/${email}/Results`)
.doc(`${ID}`)
.update({
akiec : akiec,//state
bcc : bcc,//state
bkl : bkl,//state
df : df,//state
melanoma : melanoma,//state
nv : nv,//state
vasc : vasc,//state
})
.then( async() => {
setLoading(false)
alert('Updated!')
});
}
}
And my useEffect()
const {item, userEmail, id} = route.params
useEffect( ()=>{
console.log(item)
setValue(item)
setEmail(userEmail)
setID(id)
return () => {
setAkiec("")
setBcc("")
setBkl("")
setDf("")
setMelanoma("")
setNv("")
setVasc("")
};
},[])
const setValue = (item) => {
setImageURL(item.imageURL)
setAkiec(item.akiec.toString())
setBcc(item.bcc.toString())
setBkl(item.bkl.toString())
setDf(item.df.toString())
setMelanoma(item.melanoma.toString())
setNv(item.nv.toString())
setVasc(item.vasc.toString())
}
I had this bug but I still update successful and I dont know how?
Error: Objects are not valid as a React child (found: object with keys {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}). If you meant to render a collection of children, use an array instead.
This is my all code in this page.
export default function DetailRecord({route, navigation}){
const [ID, setID] = useState("");
const [email, setEmail] = useState("");
const [loading, setLoading] = useState(false);
const [imageURL, setImageURL] = useState("");
const [akiec,setAkiec] = useState("")
const [bcc,setBcc] = useState("")
const [bkl,setBkl] = useState("")
const [df,setDf] = useState("")
const [melanoma,setMelanoma] = useState("")
const [nv,setNv] = useState("")
const [vasc,setVasc] = useState("")
const {item, userEmail, id} = route.params
useEffect( ()=>{
console.log(item)
setValue(item)
setEmail(userEmail)
setID(id)
return () => {
setAkiec("")
setBcc("")
setBkl("")
setDf("")
setMelanoma("")
setNv("")
setVasc("")
};
},[])
const setValue = (item) => {
setImageURL(item.imageURL)
setAkiec(item.akiec.toString())
setBcc(item.bcc.toString())
setBkl(item.bkl.toString())
setDf(item.df.toString())
setMelanoma(item.melanoma.toString())
setNv(item.nv.toString())
setVasc(item.vasc.toString())
}
const saveResult = async ()=>{
if(akiec=="" || bcc=="" ||bkl=="" ||df=="" ||melanoma=="" ||nv=="" ||vasc==""){
alert("Something is empty!!")
}
else{
await setLoading(true)
await firebase
.firestore()
.collection(`Users/${email}/Results`)
.doc(`${ID}`)
.update({
akiec : akiec,//state
bcc : bcc,//state
bkl : bkl,//state
df : df,//state
melanoma : melanoma,//state
nv : nv,//state
vasc : vasc,//state
})
.then( async() => {
setLoading(false)
alert('Updated!')
});
}
}
if(loading){
return <Loading />;
}
return(
<View style={styles.container}>
<SafeAreaView />
<View style={styles.header}>
<TouchableOpacity style={styles.backIcon} onPress={()=>{
navigation.goBack()
}} >
<MaterialIcons name="keyboard-backspace" size={35} color="black" />
</TouchableOpacity>
<TouchableOpacity style={styles.saveIcon} onPress={()=>{
saveResult()
}} >
<MaterialIcons name="save-alt" size={35} color="black" />
</TouchableOpacity>
<Image source={{uri: imageURL}} style={styles.image} />
</View>
<View style={styles.footer}>
<View style={styles.trendContainer}>
<View>
<Text style={styles.trendText}>The proportion of diseases</Text>
</View>
<View>
<MaterialIcons name="add-to-queue" size={25} />
</View>
</View>
<ScrollView
style={styles.scrollView}
contentContainerStyle={styles.contentScrollView}
>
<View style={styles.typeWrapper}>
<FormInput
labelName={"Intraepithelial Carcinoma"}
value={akiec}
autoCapitalize="none"
onChangeText={(value) => setAkiec(value)}
/>
</View>
<View style={styles.typeWrapper}>
<FormInput
labelName={"Basal Cell Carcinoma"}
value={bcc}
autoCapitalize="none"
onChangeText={(value) => setBcc(value)}
/>
</View>
<View style={styles.typeWrapper}>
<FormInput
labelName={"Benign Keratosis-like Lesions"}
value={bkl}
autoCapitalize="none"
onChangeText={(value) => setBkl(value)}
/>
</View>
<View style={styles.typeWrapper}>
<FormInput
labelName={"Dermatofibroma"}
value={df}
autoCapitalize="none"
onChangeText={(value) => setDf(value)}
/>
</View>
<View style={styles.typeWrapper}>
<FormInput
labelName={"Melanoma"}
value={melanoma}
autoCapitalize="none"
onChangeText={(value) => setMelanoma(value)}
/>
</View>
<View style={styles.typeWrapper}>
<FormInput
labelName={"Melanocytic Nevus"}
value={nv}
autoCapitalize="none"
onChangeText={(value) => setNv(value)}
/>
</View>
<View style={styles.typeWrapper}>
<FormInput
labelName={"Vascular Lesions"}
value={vasc}
autoCapitalize="none"
onChangeText={(value) => setVasc(value)}
/>
</View>
</ScrollView>
</View>
</View>
);
}
And my data on firestore
I am receiving this error: Error: Text strings must be rendered within a <Text> component. when I update the state, which is a list that contains components. I am trying to add a component, so I don't see why I would need a <Text> component. This list is used to render drawer components that allow the user to view the pages of the clubs they are a part of.
const [public_list, setPublicList] = useState([]);
const [private_list, setPrivateList] = useState([]);
const [list, setList] = useState([]);
const homeIcon = <Icon name="home-outline" color={'black'} size={20} />;
var user_doc;
async function fetchData() {
user_doc = await firestore()
.collection('users')
.doc(auth_user.uid)
.get()
.catch(function (error) {
console.log(
'There has been a problem with your fetch operation: ' +
error.message,
);
});
const userData = user_doc['_data'];
let public_clubList = userData['public_clubs'];
console.log(user_doc['public_clubs']);
for (let item = 0; item < public_clubList.length; item++) {
let name = public_clubList[item]['clubName'];
const newList = list.concat('hey');
const newPublicList = public_list.concat(
<DrawerItem
icon={({color, size}) => homeIcon}
label={toString(name)}
onPress={() => {
props.navigation.navigate('ClubPage', {hello});
}}
/>,
);
setList(newList);
setPublicList(newPublicList);
console.log(name);
}
console.log(user_doc['public_clubs'][1]['clubName']);
}
The error occurs at setList(newList). I call fetchData during:
useEffect(() => {
if (list.length == 0) {
fetchData();
}
});
If you were wondering, this is what my userData is:
{"email": "johndoe#email.com", "fullName": "John Doe", "id": "JbuhzofKDEe2ImMl9DPYpBbuVzG2", "private_clubs": [{"clubName": "Kool kids ", "id": "1903440d-e06a-4117-bc41-d27fabb80583"}, {"clubName ": "Test", "id": "53fe982f-318e-4903-a439-9e8271035393"}], "public_clubs": [{"clubName": "Testing adding users n stuff", "id": "a6cb1dcb-cfdd-48a4-b673-671519fbe6dd"}, {"clubName": "Hey guyyys", "id": "c219a611-26c3-44d3-9d66-396b0f9a738d"}], "userName": "johndoe"}
This is what my return statement is. The rest of the drawers load fine.
return (
<View style={{flex: 1, flexDirection: 'column'}}>
<DrawerContentScrollView {...props} style={{flex: 10}}>
<DrawerItem
icon={({color, size}) => (
<Icon name="home-outline" color={'black'} size={20} />
)}
label={hello}
onPress={() => {
props.navigation.navigate('ClubPage', {hello});
}}
/>
{list}
{public_list}
{private_list}
</DrawerContentScrollView>
<Drawer.Section style={{flex: 1}}>
<DrawerItem
icon={({color, size}) => (
<Icon name="buffer" color={'black'} size={20} />
)}
label="FeedPage"
onPress={() => {
props.navigation.navigate('FeedPage');
}}
/>
</Drawer.Section>
<DrawerItem
icon={({color, size}) => (
<Icon name="pen-plus" color={'black'} size={20} />
)}
label="Make a Club"
onPress={() => {
props.navigation.navigate('MakeClub');
}}
/>
<DrawerItem
icon={({color, size}) => (
<Icon name="account" color={'black'} size={20} />
)}
label="My Profile"
onPress={() => {
props.navigation.navigate('ProfilePage');
}}
/>
</View>
);
In this section here, it looks like you're trying to render the list directly onto the jsx:
<DrawerContentScrollView {...props} style={{flex: 10}}>
<DrawerItem
icon={({color, size}) => (
<Icon name="home-outline" color={'black'} size={20} />
)}
label={hello}
onPress={() => {
props.navigation.navigate('ClubPage', {hello});
}}
/>
{list} // Here
{public_list} //Here
{private_list} //Here
</DrawerContentScrollView>
If your list is an array like it says in the state declaration, map it and render each text separately. Of course it could be an array of objects, in which case you'd need to use the correct key.
{list.map(item => <Text> {item} </Text>)}
Also, try and comment out those lines and add mock values to see the result and check if it is what you expected.
While using a graphql query, I am calling a showUsers function which is supposed to show all the users (the stying is done so that they can appear as boxes). However, currently nothing shows up.
I am using a functional component, not class component.
This function is called after my handleSubmitForm. Here I call showUsers.
const getFriendId = React.useCallback(
(data) => {
if (data) {
if (data.users.nodes.length == 0) {
Alert.alert('User Not Found');
} else {
const numberOfUsers = data.users.nodes.length;
showUsers(data, numberOfUsers);
addFriend(Number(data.users.nodes[0].id));
}
}
},
[addFriend],
);
showUsers():
const showUsers = React.useCallback(
(data: UsersLazyQueryHookResult, numberOfUsers: Number) => {
for (var i = 0; i < numberOfUsers; i++) {
const userId = data.users.nodes[i].id;
const userName = (data.users.nodes[i].firstName).concat((data.users.nodes[i].lastName));
return(
<View style={styles.friends}>
<View style={styles.item}>
<Text>{userName}</Text>
</View>
</View>
)
}
},
[createUserRelationMutation],
);
This is how my form looks like. I guess I have to make an edit here but I am not sure how.
return (
<Modal
visible={showAddFriendEmailPage}
animationType="slide"
transparent={true}>
<SafeAreaView>
<View style={styles.container}>
<View style={styles.searchTopContainer}>
<View>
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<View style={styles.searchFieldContainer}>
<View style={styles.form}>
<FieldInput
handleChange={handleChange}
handleBlur={handleBlur}
value={values.email}
fieldType="email"
/>
<ErrorMessage
name="email"
render={msg => (
<Text style={styles.errorText}>{msg}</Text>
)}
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={handleSubmit}>
<Text >Add Friend </Text>
</Button>
</View>
</View>
)}
</Formik>
</View>
</View>
</View>
</SafeAreaView>
</Modal>
);
};
Note: I only want them to show up below the button, after I submit the form.
EDIT:
I am trying this but I have a few problems:
Even when there's only one user, I see the LOOPoutput on the console at least 4 times.
Once the query and mutation run successfully and a user is also rendered/displayed, I can no longer press the button again. Which means that I can no longer submit the form and re-run queries or mutations with a different email input.
export const AddFriendEmailPage: React.FunctionComponent<AddFriendEmailPageProps> = ({
toggleShowPage,
showAddFriendEmailPage,
}) => {
const initialValues: FormValues = {
email: '',
};
const [errorMessage, setErrorMessage] = useState('');
const [userData, setUserData] = useState<UsersLazyQueryHookResult>('');
const [numberOfUsers, setNumberOfUsers] = useState('');
const validationSchema = emailValidationSchema;
useEffect(() => {
setUserData(userData);
setNumberOfUsers(numberOfUsers);
}, [userData, numberOfUsers]);
const showAlert = () => {
Alert.alert('Friend Added');
};
useEffect(() => {
if (showAddFriendEmailPage) return;
initialValues.email = '';
}, [showAddFriendEmailPage]);
const _onLoadUserError = React.useCallback((error: ApolloError) => {
setErrorMessage(error.message);
Alert.alert('Unable to Add Friend');
}, []);
const [
createUserRelationMutation,
{
data: addingFriendData,
loading: addingFriendLoading,
error: addingFriendError,
called: isMutationCalled,
},
] = useCreateUserRelationMutation({
onCompleted: (data: CreateUserRelationMutationResult) => {
showAlert();
},
});
const showUsers = React.useCallback(
(data: UsersLazyQueryHookResult, numberOfUsers: Number) => {
console.log('Number of Users in Loop: ', numberOfUsers);
for (var i = 0; i < numberOfUsers; i++) {
const userId = data.users.nodes[i].id;
const userName = ((data.users.nodes[i].firstName).concat(' ')).concat(data.users.nodes[i].lastName);
console.log('Whats the Id', userId);
console.log('UserName', userName);
console.log('Loop');
return(
<View style={styles.friends}>
<View style={styles.item}>
<Text>{userName}</Text>
</View>
</View>
)
}
},
[createUserRelationMutation],
);
const addFriend = React.useCallback(
(id: Number) => {
console.log('Whats the Id', id);
createUserRelationMutation({
variables: {
input: { relatedUserId: id, type: RelationType.Friend, userId: 7 },
},
});
},
[createUserRelationMutation],
);
const getFriendId = React.useCallback(
(data: UsersLazyQueryHookResult) => {
if (data) {
if (data.users.nodes.length == 0) {
setErrorMessage('User Not Found');
Alert.alert('User Not Found');
} else {
setUserData(data);
//const numberOfUsers = data.users.nodes.length;
setNumberOfUsers(data.users.nodes.length);
showUsers(data, Number(numberOfUsers));
addFriend(Number(data.users.nodes[0].id));
}
}
},
[addFriend],
);
const [loadUsers] = useUsersLazyQuery({
onCompleted: getFriendId,
onError: _onLoadUserError,
});
const handleSubmitForm = React.useCallback(
(values: FormValues, helpers: FormikHelpers<FormValues>) => {
console.log('Submitted');
loadUsers({
variables: {
where: { email: values.email },
},
});
values.email = '';
},
[loadUsers],
);
if (!addingFriendLoading && isMutationCalled) {
if (addingFriendError) {
setErrorMessage(addingFriendError.message);
Alert.alert('Unable to Add Friend');
}
}
return (
<Modal
visible={showAddFriendEmailPage}
animationType="slide"
transparent={true}>
<SafeAreaView>
<View style={styles.container}>
<View style={styles.searchTopContainer}>
<View style={styles.searchTopTextContainer}>
<Text
style={styles.searchCancelDoneText}
onPress={toggleShowPage}>
Cancel
</Text>
<Text style={styles.searchTopMiddleText}>
Add Friend by Email
</Text>
<Text style={styles.searchCancelDoneText}>Done</Text>
</View>
<View>
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<View style={styles.searchFieldContainer}>
<View style={styles.form}>
<FieldInput
handleChange={handleChange}
handleBlur={handleBlur}
value={values.email}
fieldType="email"
/>
<ErrorMessage
name="email"
render={msg => (
<Text style={styles.errorText}>{msg}</Text>
)}
/>
</View>
<View style={styles.buttonContainer}>
<Button
rounded
style={styles.button}
onPress={handleSubmit}>
<Text style={styles.text}>Add Friend </Text>
</Button>
</View>
</View>
)}
</Formik>
</View>
{showUsers(userData, Number(numberOfUsers))}
</View>
</View>
</SafeAreaView>
</Modal>
);
};
While using a graphql query, I am calling a showUsers function which
is supposed to show all the users (the stying is done so that they can
appear as boxes). However, currently nothing shows up.
A function call showUsers(data, numberOfUsers); can't just show items. You have to render it somewhere.
<View style={styles.buttonContainer}>
<Button
rounded
style={styles.button}
onPress={handleSubmit}>
<Text style={styles.text}>Add Friend </Text>
</Button>
</View>
{showUsers(data, numberOfUsers)}
But this also don't work straight away because you don't have data variable in this context. You have to use useState. I don't know if you can use React.useCallback function to return component this way. I would change showUsers(data, numberOfUsers) to
separate functional component.