Based on the example given in the documentation of expo image picker I'm trying to upload multiple images to AWS Amplify. In the example given on github only one picture is being worked with. Setting the allowsMultipleSelection prop to true makes it possible to pick multiple images but though I've been tinkering with the code to suit it to my need I can't seem to get it.
Here's what I'm doing
import { Amplify, Auth, Storage } from "aws-amplify";
import * as Clipboard from "expo-clipboard";
import * as ImagePicker from "expo-image-picker";
import { useState } from "react";
import { Button, Image, Text, View } from "react-native";
import awsconfig from "../aws-exports";
Amplify.configure(awsconfig);
const UploadImageAWS = () => {
const [image, setImage] = useState([]);
const [percentage, setPercentage] = useState(0);
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: "Images",
aspect: [4, 3],
quality: 1,
allowsMultipleSelection: true,
});
this.handleImagePicked(result);
};
handleImagePicked = async (pickerResult) => {
try {
if (!pickerResult.canceled) {
pickerResult.forEach(async (element) => {
setPercentage(0);
const img = await fetchImageFromUri(element.uri);
const uploadUrl = await uploadImage(img.name, img);
downloadImage(uploadUrl);
});
}
} catch (e) {
alert("Upload failed");
}
};
uploadImage = (filename, img) => {
Auth.currentCredentials();
return Storage.put(filename, img, {
level: "public",
contentType: "image/jpeg",
progressCallback(progress) {
setLoading(progress);
},
})
.then((response) => {
return response.key;
})
.catch((error) => {
return error.response;
});
};
const setLoading = (progress) => {
const calculated = parseInt((progress.loaded / progress.total) * 100);
updatePercentage(calculated); // due to s3 put function scoped
};
const updatePercentage = (number) => {
setPercentage(number);
};
downloadImage = (uri) => {
Storage.get(uri)
.then((result) => setImage(result))
.catch((err) => console.log(err));
};
const fetchImageFromUri = async (uri) => {
const response = await fetch(uri);
const blob = await response.blob();
return blob;
};
const copyToClipboard = () => {
Clipboard.setString(image);
alert("Copied image URL to clipboard");
};
return (
<View style={styles.container}>
<Text style={styles.title}>AWS Storage Upload Demo</Text>
{percentage !== 0 && <Text style={styles.percentage}>{percentage}%</Text>}
{image &&
image.map((img) => (
<View>
<Text style={styles.result} onPress={copyToClipboard}>
<Image
source={{ uri: img }}
style={{ width: 250, height: 250 }}
/>
</Text>
<Text style={styles.info}>Long press to copy the image url</Text>
</View>
))}
<Button onPress={pickImage} title="Pick an image from camera roll" />
</View>
);
};
export default UploadImageAWS;
Running a loop on the handleImagePicked function then having a random name being generated for each picture solved the problem. Here's what the code looks like
imports
import { v4 as uuidv4 } from "uuid";
import * as ImagePicker from "expo-image-picker";
methods logic
let imagesArray = [];
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: "Images",
aspect: [4, 3],
quality: 1,
allowsMultipleSelection: true,
});
result.assets.forEach((image) => handleImagePicked(image));
};
const handleImagePicked = async (pickerResult) => {
const imageName = uuidv4();
try {
if (!pickerResult.canceled) {
const img = await fetchImageFromUri(pickerResult.uri);
const uploadUrl = await uploadImage(imageName, img);
console.log("upload url = ", uploadUrl);
downloadImage(uploadUrl);
}
} catch (e) {
console.log("Upload failed", e.message);
}
};
const uploadImage = async (filename, img) => {
Auth.currentCredentials();
return Storage.put(filename, img, {
level: "public",
contentType: "image/jpeg",
})
.then((response) => {
return response.key;
})
.catch((error) => {
console.log(error);
return error.response;
});
};
const downloadImage = (uri) => {
Storage.get(uri)
.then((result) => {
setImages(result);
imagesArray.push(result);
})
.catch((err) => console.log(err));
};
const fetchImageFromUri = async (uri) => {
const response = await fetch(uri);
const blob = await response.blob();
// console.log("blob of URI : " + JSON.stringify(blob));
return blob;
};
Images display
<FlatList
horizontal
showsHorizontalScrollIndicator={false}
data={imagesArray}
renderItem={({ item }) => (
<Image
source={{ uri: item }}
style={{
height: 75,
width: 75,
borderRadius: 10,
marginHorizontal: 10,
resizeMode: "contain",
}}
/>
)}
/>
Related
I have react native app. And I am calling a api url. But I don't want to have all the data from the api call. But some specific data. Like name and image.
So I have a service:
export const fetchCategoryData = async () => {
try {
const response = await fetch("http://10.14.220.60:8000/animal/categories/main_groups/", {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error("Network response was not ok");
}
console.log("RESSPONSE", response);
return await response.json();
} catch (error) {
console.error("There was a problem with the fetch operation:", error);
throw error;
}
};
export const categoryTransform = ({ results = [] }) => {
const mappedResults = results.map((categoryList) => {
//categoryList.images = categoryList.images;
return {
...categoryList,
};
});
console.log("MAPPEDRESULT", fetchCategoryData.response());
return mappedResults;
};
and data context:
import { Children, createContext, useEffect, useState } from "react";
import { categoryTransform, fetchCategoryData } from "./category.service";
export const CategoryContext = createContext();
export const CategoryContextProvider = ({ children }) => {
const [categoryList, setCategoryList] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const retrieveCategories = () => {
setLoading(true);
setTimeout(() => {
fetchCategoryData()
.then(categoryTransform)
.then((results) => {
setLoading(false);
setCategoryList(results);
})
.catch((err) => {
setLoading(false);
setError(err);
});
}, 200);
};
useEffect(() => {
retrieveCategories();
}, []);
console.log(categoryList);
return (
<CategoryContext.Provider
value={{
categoryList,
loading,
error,
}}>
{children}
</CategoryContext.Provider>
);
};
and component dat injects the data context:
import { FlatList, SafeAreaView, StatusBar } from "react-native";
import React, { useContext } from "react";
import { CategoryContext } from "../../../services/category/category.context";
import { CategoryInfoCard } from "../components/category-info-card.component";
import { Searchbar } from "react-native-paper";
import { Spacer } from "../../../components/spacer/spacer.component";
import styled from "styled-components/native";
const SafeArea = styled(SafeAreaView)`
flex: 1;
${StatusBar.currentHeight && `margin-top: ${StatusBar.currentHeight}px`};
`;
const SearchContainer = styled.View`
padding: ${(props) => props.theme.space[3]};
`;
const CategoryList = styled(FlatList).attrs({
contentContainerStyle: {
padding: 16,
},
})``;
export const CategoryScreen = () => {
const { categoryList } = useContext(CategoryContext);
return (
<SafeArea>
<SearchContainer>
<Searchbar />
</SearchContainer>
<CategoryList
data={categoryList}
renderItem={({ item }) => {
console.log("ITEMs", item);
return (
<Spacer position="bottom" size="large">
<CategoryInfoCard categoryList={item} />
</Spacer>
);
}}
keyExtractor={(item) => item.name}
/>
</SafeArea>
);
};
And this is a deault component with hard coded data:
/* eslint-disable prettier/prettier */
import { React, useEffect, useState } from "react";
import { Card } from "react-native-paper";
import { Spacer } from "../../../components/spacer/spacer.component";
import { Text } from "../../../components/typography/text.component";
import styled from "styled-components/native";
const CategoryCard = styled(Card)`
background-color: ${(props) => props.theme.colors.bg.primary};
`;
const CategoryGroupCardCover = styled(Card.Cover)`
padding: ${(props) => props.theme.space[3]};
background-color: ${(props) => props.theme.colors.bg.primary};
`;
export const CategoryInfoCard = ({ categoryList = {} }) => {
const {
name = "Zoogdieren",
images = "https://cdn.pixabay.com/photo/2017/02/20/18/03/cat-2083492_960_720.jpg",
} = categoryList;
return (
<CategoryCard
elevation={5}
style={{
borderTopLeftRadius: 0,
borderTopRightRadius: 0,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
}}>
<Text center variant="h1" style={{ left: 100 }}>
{name}
</Text>
<CategoryGroupCardCover source={{ uri: images }} />
</CategoryCard>
);
};
So it is about the categoryTransform in the service.
Because when I am calling this function it doesn't work. I get empty array back.
But if I comment the categoryTransform method in the categoryContext. Like:
const retrieveCategories = () => {
setLoading(true);
setTimeout(() => {
fetchCategoryData()
//.then(categoryTransform)
.then((results) => {
setLoading(false);
setCategoryList(results);
})
.catch((err) => {
setLoading(false);
setError(err);
});
}, 200);
};
Then it works.
And the api call looks like:
ITEMs Object {
"animals": Array [],
"category": null,
"description": "zoogdieren",
"eaza": "",
"id": 1,
"images": "http://10.14.220.60:8000/media/photos/categories/mammal.jpg",
"legislation": "",
"name": "zoogdieren",
"review": "",
}
Question: how to fix the categoryTransform method, so that it will filter the specif data: name and images?
I'm working on a mobile phone application with Stripe and Expo Bar Code Scanner. When you start the application, if you gave the permissions for using the camera, you will can scan bar codes. Bar Codes only contains the id of the scanned item. If it exists, two buttons (+/-) will appear in order to choose the amount for the item. If it doesn't exists, nothing happens. When the amount changes, I save in SecureStore the id of the item as the key and the amount as the value.
The problem is when I move on others screens (with React Navigation) and I came back to scan and I rescan the same item, the amount resets to 0. If you don't give the permissions for the camera, it displays a list of available items when you can choose the amount (+/-) buttons and similar problem.
Here the concerned two files :
ItemListComponent.tsx
import { Button, FlatList, View, Text } from 'react-native';
import * as SecureStore from 'expo-secure-store';
import { useState } from 'react';
export const ItemComponent = (props: any) => {
const [amount, setAmount] = useState<number>(0);
const getAmount = async () => {
const amount = await SecureStore.getItemAsync(props.item.id.toString());
if (amount) {
setAmount(parseInt(amount));
}
getAmount();
}
const save = async () => {
await SecureStore.setItemAsync(props.item.id.toString(), amount.toString());
}
return (
<View>
<Text>{props.item.name}</Text>
<Button
onPress={() => {
setAmount(amount + 1);
save();
}}
title='+'
/>
{amount > 0 &&
<Button
onPress={() => {
setAmount(amount - 1);
save();
}}
title='-'
/>
}
</View>
);
};
export const ItemListComponent = (props: any) => {
return (
<FlatList
data={props.items}
renderItem={({ item }) =>
<ItemComponent key={item.id} item={item} />
}
/>
);
};
BarCodeScannerComponent.tsx
import { BarCodeScanner } from 'expo-barcode-scanner';
import { useState } from 'react';
import { StyleSheet } from 'react-native';
import { ItemComponent } from './ItemListComponent';
import Items from '../models/ItemsModel';
export const BarCodeScannerComponent = () => {
const [item, setItem] = useState<Items>();
const getItem = async ({ data }: any) => {
const response = await fetch(`http://192.168.1.81:8000/items/${data}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (response.ok) {
const json = await response.json();
setItem(json);
}
}
return (
<View style={styles.container}>
<BarCodeScanner
onBarCodeScanned={getItem}
style={StyleSheet.absoluteFillObject}
/>
{(item !== null && item !== undefined) && <ItemComponent key={item.id} item={item} />}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
},
});
Thanks for help !
It looks like you never call getAmount, and if you did call it you'd get infinite recursion.
const getAmount = async () => {
const amount = await SecureStore.getItemAsync(props.item.id.toString());
if (amount) {
setAmount(parseInt(amount));
}
getAmount();
}
should be
const getAmount = async () => {
const amount = await SecureStore.getItemAsync(props.item.id.toString());
if (amount) {
setAmount(parseInt(amount));
}
}
getAmount();
or, probably even better:
const getAmount = async () => {
const storeAmount = await SecureStore.getItemAsync(props.item.id.toString());
if (amount !== parseInt(storeAmount)) {
setAmount(parseInt(storeAmount));
}
}
useEffect(() => {
getAmount();
}, [props.item.id]);
otherwise, every time it renders you'll call setAmount which will trigger a rerender
I am trying to make a section for my website with a news bar that contains snippets of update posts for my site. To do so, I have successfully created the data schema, routing on my backend for post and get requests. I am routing requests on the client server using axios for my XMLHTTPRequests, Redux for my global state store, and cors. Using my NewsBar component, I wrap my NewsPosts component, which is a collection of rendered NewsPost components.
NewsBar component:
function useQuery() {
return new URLSearchParams(useLocation().search);
}
const NewsBar = () => {
const classes = useStyles();
const query = useQuery();
const page = query.get('page') || 1;
const searchQuery = query.get('searchQuery');
const [currentId, setCurrentId] = useState(0);
console.log(`NewsBar: ${useLocation().search} | query=>${query}`);
console.log(`searchquery: ${searchQuery}`);
return (
<>
<Grow in>
<Grid container direction={'row'} className={classes.newsBar} justifyContent='center'>
<Typography variant='h3'>News Bar</Typography>
<Grid item>
<NewsPosts setCurrentId={setCurrentId} />
</Grid>
</Grid>
</Grow>
</>
)
}
export default NewsBar;
NewsPosts component:
const NewsPosts = ({ setCurrentId }) => {
const { newsPosts, isLoading } = useSelector((state) => state.newsPosts);
const classes = useStyles();
newsPosts.map((newsPost) => {
console.log(newsPost);
})
console.log(new Date().toISOString());
console.log(`newsPosts array: ${typeof newsPosts} ${newsPosts}`)
if (!newsPosts.length && !isLoading) return 'No news posts.';
return (
isLoading ? <LinearProgress /> : (
<Grid container alignItems='stretch' spacing={3}>
{newsPosts?.map((newsPost) => (
<Grid key={newsPost._id} item xs={12} sm={12} md={12} lg={12}>
<NewsPost newsPost={newsPost} setCurrentId={setCurrentId}/>
</Grid>
))}
</Grid>
)
);
};
export default NewsPosts;
I added console logging for each of my routing actions and methods, and unfortunately it seems as though I get an empty array of type Object instead of the page of documents I am supposed to get. Within my console, the only logs that output are from NewsPosts.js.
NewsBar: | query=>
NewsBar.js:27 searchquery: null
NewsPosts.js:17 2022-12-01T20:36:08.958Z
NewsPosts.js:18 newsPosts array: object
On top of that, I checked my network requests and none were made. Could someone attempt to tell me why this is?
Axios code as per request:
import { START_LOADING, END_LOADING, FETCH_POST, FETCH_ALL, DELETE, CREATE } from "../constants/actionTypes";
import * as api from '../api/index.js';
//CREATE ACTIONS -> should follow the standard XMLHTTPRequest operation
export const getNewsPost = (id) => async (dispatch) => {
try {
console.log('actions: action getNewsPost was called');
dispatch({ type: START_LOADING })
const { data } = await api.fetchNewsPost(id);
dispatch({type: FETCH_POST, payload: { newsPost: data }});
console.log(`got post ${data}`);
} catch (error) {
console.log(error);
}
};
export const getNewsPosts = (page) => async (dispatch) => {
try {
console.log('actions: action getNewsPosts was called');
dispatch({ type: START_LOADING });
const {data : {data, currentPage, numberOfPages }} = await api.fetchNewsPosts(page);
dispatch({ type: FETCH_ALL, payload: { data, currentPage, numberOfPages }});
dispatch({ type: END_LOADING });
} catch (error) {
console.log(error);
}
};
export const createNewsPost = (newsPost, history) => async (dispatch) => {
try {
console.log('actions: action createNewsPosts was called');
dispatch({ type: START_LOADING });
const { data } = await api.createNewsPost(newsPost);
dispatch({ type: CREATE, payload: data });
history.push(`/newsPosts/${data._id}`);
} catch (error) {
console.log(error);
}
};
export const deleteNewsPost = (id) => async (dispatch) => {
try {
console.log('actions: action deleteNewsPost was called');
await await api.deletePost(id);
dispatch({ type: DELETE, payload: id });
} catch (error) {
console.log(error);
}
};
index.js
import axios from 'axios';
const API = axios.create({ baseURL: 'http://localhost:5000' });
API.interceptors.request.use((req) => {
if (localStorage.getItem('profile')) {
req.headers.Authorization = `Bearer ${JSON.parse(localStorage.getItem('profile')).token}`;
}
return req;
});
export const fetchPost = (id) => API.get(`/posts/${id}`);
export const fetchPosts = (page) => API.get(`/posts?page=${page}`);
export const fetchPostsByCreator = (name) => API.get(`/posts/creator?name=${name}`);
export const fetchPostsBySearch = (searchQuery) => API.get(`/posts/search?searchQuery=${searchQuery.search || 'none'}&tags=${searchQuery.tags}`);
export const createPost = (newPost) => API.post('/posts', newPost);
export const likePost = (id) => API.patch(`/posts/${id}/likePost`);
export const comment = (value, id) => API.post(`/posts/${id}/commentPost`, { value });
export const updatePost = (id, updatedPost) => API.patch(`/posts/${id}`, updatedPost);
export const deletePost = (id) => API.delete(`/posts/${id}`);
export const signIn = (formData) => API.post('/user/signin', formData);
export const signUp = (formData) => API.post('/user/signup', formData);
export const fetchNewsPost = (id) => API.get(`/news/${id}`);
export const fetchNewsPosts = (page) => API.get(`/news?page=${page}`);
export const createNewsPost = (newNewsPost) => API.post('/news', newNewsPost);
export const deleteNewsPost = (id) => API.delete(`/news/${id}`);
My app keeps crashing when user tries to send photo from camera to API. There were no problem in the android emulator but it crashes on my physical device (Galaxy A30). The console.log doesn't show anything when I used it on the emulator. There were no problem submitting from image gallery but when submitting from the camera, it crashes.
import React, {useState, useContext} from 'react';
import {ScrollView, View, Text, TextInput, TouchableOpacity, Alert} from 'react-native';
import { AuthContext } from '../Context/AuthContext';
import { URLs } from '../constants/links';
import * as ImagePicker from 'expo-image-picker';
import axios from 'axios';
import * as Permissions from "expo-permissions";
import { CAMERA } from "expo-permissions";
const MyScreen = ({navigation}) => {
const { myToken } = useContext(AuthContext)
const [allImage, setAllImage] = React.useState([]);
const [pickedImage, setPickedImage] = useState("");
const [fileName, setFileName] = React.useState("");
const formdata = new FormData();
const cameraPermission = async () => {
const result = await Permissions.askAsync(CAMERA);
if (result.status != "granted") {
Alert.alert(
"Insufficient Permission",
"You need to grant camera permission to use this app",
[{ text: "Okay" }]
);
return true;
}
return true;
};
const useCamera = async () => {
const hasPermissions = await cameraPermission();
if (!hasPermissions) {
return;
}
if(allImage.length < 4){
let result = await ImagePicker.launchCameraAsync({
allowsEditing: true,
quality: 0.5,
});
if (!result.cancelled) {
const name = result.uri.split('/').pop();
let match = /\.(\w+)$/.exec(name);
let type = match ? `image/${match[1]}` : `image`;
let newFile = {
uri: result.uri,
type: type,
name: name
}
setAllImage(newFile)
setPickedImage(result.uri)
if (!pickedImage && allImage.length === 0) {
setAllImage([newFile]);
setFileName("Photo 1")
}else {
setAllImage([...allImage, newFile]);
setFileName(fileName + ", Photo " + (allImage.length + 1))
}
}
} else {
Alert.alert("Image", "You have reach the image upload limit");
}
};
const fetchData = () => {
const abortCont = new AbortController();
allImage.forEach((file) => {
formdata.append('files[]', file);
});
axios({
method: 'post',
url: URLs,
headers: {
Accept: "application/json",
Authorization: myToken,
'Content-Type': "multipart/form-data",
},
data: formdata,
signal: abortCont.signal,
}).then(function (result) {
if(result.data.message === "Successfully added") {
Alert.alert("Upload Successufull", result.data.message);
navigation.goBack()
}
}).catch(function (error) {
Alert.alert("Error", error);
formdata = new FormData();
});
return () => abortCont.abort();
}
return (
<ScrollView>
<View>
<View>
<Text>Attach Receipt File</Text>
<View>
<TextInput
editable={false}
placeholder="Select files.."
value={fileName}
/>
</View>
<View>
<TouchableOpacity activeOpacity={0.8} onPress={useCamera}>
<Text>Camera</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity activeOpacity={0.9} onPress={fetchData}>
<Text>Submit</Text>
</TouchableOpacity>
</View>
</View>
</View>
</ScrollView>
);
}
export default MyScreen;
I still don't know the reason why the app crash when user send photo taken from camera but I found a solution. I change from using camera from expo-permission to Camera from expo-camera. This is the docs: https://docs.expo.dev/versions/latest/sdk/camera/#cameracapturedpicture
import React, {useEffect} from 'react';
import {View, Text, StyleSheet, FlatList, TouchableOpacity} from 'react-native';
import Card from '../components/Card';
import {useState} from 'react';
import {useIsFocused} from '#react-navigation/native';
import AsyncStorage from '#react-native-async-storage/async-storage';
const Orders = ({route, navigation}) => {
const [userID, setUserID] = useState('');
const [orders, setOrders] = useState([]);
const isFocused = useIsFocused();
async function getData() {
try {
const value = await AsyncStorage.getItem('UserID');
if (value !== null) {
console.log('USERID is ' + value);
setUserID(value);
}
} catch (e) {}
}
function fetchOrders() {
fetch(
'https://somewebsite/product/GetOrdersByUserID?userid=' +
//'1249b39a-ded0-4522-a263-f905ac30e5a3',
userID,
)
.then(response => response.json())
.then(responseJson => {
setOrders(responseJson);
})
.catch(error => {
console.error(error);
});
}
getData();
useEffect(() => {
//getData();
fetchOrders();
console.log('UserID inside useffect:: ' + userID);
console.log('inside useEffect');
}, [isFocused]);
return (
<View>
<View style={styles.container}>
<FlatList
scrollEnabled={true}
data={orders}
renderItem={({item}) => (
<TouchableOpacity
onPress={() => {
navigation.navigate('OrderDetails', {
orderID: item.id,
});
}}>
<View style={styles.viewPP}>
<Card style={styles.cardPP}>
<Text style={styles.text}>Order ID:{item.id}</Text>
<Text style={styles.text}>Total: ₹{item.total}</Text>
<Text style={styles.text}>Placed: {item.placed}</Text>
<Text style={styles.text}>Status: Delivered</Text>
</Card>
</View>
</TouchableOpacity>
)}></FlatList>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 10,
},
text: {
fontWeight: 'bold',
alignContent: 'center',
},
cardPP: {
margin: 10,
},
});
export default Orders;
My issue is I am not getting the UserID on first render but when I press Ctrl+S(Save operation) I am able to get the UserID and hence the Orders are displayed.
My issue is I am not able to fetch the UserID on first render.
I have tried console.log(UserID) and it's blank the first time as above.
When I put the UserID directly as 1249b39a-ded0-4522-a263-f905ac30e5a3 in 'https://somewebsite/product/GetOrdersByUserID?userid=' inside fetchOrders() Orders are displayed without any issue on the First render.
Please help me out.
State updates are not synchronous. Like if you call setUserId, it doesn't synchronously set the state, for you to consume it instantly. It's managed asynchronously through React internally. Better if you follow your Promises and pass parameters, etc. Let me know if I missed anything
const Orders = ({route, navigation}) => {
const [userID, setUserID] = useState('');
const [orders, setOrders] = useState([]);
const isFocused = useIsFocused();
async function getData() {
try {
const value = await AsyncStorage.getItem('UserID');
if (value !== null) {
console.log('USERID is ' + value);
setUserID(value);
return value;
}
throw new ReferenceError("UserID is null");
} catch (e) {
return '';
}
}
function fetchOrders(userId) {
fetch(
'https://somewebsite/product/GetOrdersByUserID?userid=' +
//'1249b39a-ded0-4522-a263-f905ac30e5a3',
userID,
)
.then(response => response.json())
.then(responseJson => {
setOrders(responseJson);
})
.catch(error => {
console.error(error);
});
}
useEffect(() => {
getData()
.then((v) => fetchOrders(v));
}, [isFocused]);