Let’s consider how to implement image upload in a
react native or expo app using expo-image-picker. The goal here is to upload and display an image from the user’s gallery or take a new
image with the camera when the image button is pressed. As well as provide
a way to delete the uploaded picture. We’ll also talk briefly about how to
proceed with the uploaded image for storage by making API calls and also when
you have other input fields using FormData. In this tutorial, I will demonstrate using
this sample app with the profile page here. The aim will only be on the functionality
so we’ll not be building the UI. However, the source code will be linked in the description. So what will you need? First, you need to install
expo-image-picker in your project. In addition to that, you need to have an image
component on your page. This should be given at least a height and a width, and you can
add any additional styling of your choice. Next, you need a button to trigger the
upload and this can be a touchable opacity. If you want to provide the
multiple options of upload, you need a page or a modal with buttons for
camera, gallery and removing the uploaded image. Finally you’ll need a placeholder image to
be used when no image has been uploaded. Once we have that we are ready to go. The upload process starts with pressing the button
on the profile page. When the button is pressed, we want to display the options of upload.
So in the onPress property of our button, we display the modal with the options or navigate to the screen with the options if
we’re using a full page instead. Now on the options modal screen, the
first option is to use the camera. For this, let’s create an async
function, and we’ll call it uploadImage. For the work here, we need to import
the ImagePicker we installed earlier. To start, we await a request for
permission to access the user’s camera, using the permission method of the ImagePicker. Next, we create a result variable and as value, we await the result of launching the
camera with the ImagePicker method. To this method, we can pass an object of
arguments. First we pass a cameraType. Since we’re working with a profile picture,
we can default to the front camera. Also, we allow editing so that we can
crop, set the aspect ratio to 1:1 and then set the quality to the highest. You
can alter these values to suit your needs. However, on IOS, the aspect ratio is limited to
being a square regardless of the values passed. Now based on the result received, we check if the upload was not canceled.
If that's the case, we want to save it. For this, we create a new state for
the image using the useState hook from react. With that done, we create a
new async function for saving the image. This will accept the image as
a parameter and set it as the value of the image state. After this,
the options modal can be dismissed. Now we call the save function after
uploading and pass the image uri which can be located in the first element
of the assets array under the result. If we catch any error, we can alert
the message and dismiss the modal. We then pass the uploadImage function to the
onPress property of the camera option button. Next, to display the uploaded image, we need
to pass the image state to the image component. Here, my image component
is in the avatar component, so I’ll pass it through the uri property. In my Avatar component, once
I have access to the URI, I pass it as an object to the source
property of the image component. Now if we don’t have any image uploaded,
we want to display our placeholder image. So we can import that from our assets.
Over here, we check if we have a value for uri. If that's true, we pass the uri
object. Otherwise we pass the placeholder. With this done, we should be able to upload
and display an image using the camera option. Now for the gallery option, let
modify the uploadImage function. First, let’s accept a mode parameter. Now we check if the mode is gallery.
If that’s the case we want to await the ImagePicker permission. This time
around, it will be for the media library. After this, we launch the image
library with the image picker. Here, we set the media types to
only images, allow editing, set the aspect ratio to a square and
enable the highest image quality as well. With this done, we want to store the result in
the result variable as well. So we initialize a global result variable to an empty object, and
assign the gallery and camera results to it. Now we need to pass this function to
the gallery option button of the modal. So over here, we call uploadImage
and pass gallery as the mode. With this done, we should be able to upload
and display an image from the gallery as well. Now let’s handle how to
remove the uploaded picture. For this, let’s create an async
function and call it removeImage. Over here, we call the saveImage
function and pass null as the value. In the case of an error, we can alert the
message and hide the modal. We can then pass the function to the onPress
property of the option button. With this done, we should be able to
remove the uploaded image as well. Now a few tips on how to proceed with
the uploaded image. Let’s talk about when you have only the image and when
you have other form inputs as well. When you have only the image, usually, you’ll make an api call right after uploading
the image to store it in a database. So in the saveImage function, right
after updating the image state, we make a call to the backend api. Here
we can do so in a dedicated function. For processing the image data, we need
to use the global FormData interface, which can be declared at the top. Now for the request, we create a new
instance of the form data and append the image. Giving it a key and an object
as value. This will contain the image uri, which will be the image state, the type of
data, which is image and a name for the file. Demonstrating with the Axios API Client,
we also need a config object which contains headers for the request. In this, we set
the content type as multipart or form-data. We also add a transformRequest
function and return the formData. With this done, we can make
the request with Axios, passing the endpoint, formData
and the configuration object. When you remove the uploaded image as well, this will apply and make the api call
since it also uses the saveImage function. In the situation where you have the image
and other form inputs to be processed, the approach will be quite similar. However, right after uploading the image, we only update the image state and
not make the API call to the backend. Similarly, when the uploaded image is removed, we only update the image state and
hide the modal, making no api request. When the other details are provided, we
then proceed with a submit button which will call a save function to make the API call. Just like the initial one, we
create a new formData instance and append all the other input data
in addition to the image. We’ll have the same config and then we can proceed
to make the api call to save the data. Now back on the profile page, when you
want to fetch the details from the API, you can do so in the useEffect hook to get
all the details before the page is ready. In the next video, we’ll look
at how to persist and share data across multiple parts of your app
using secure store and context API. Link to the source code will be in
the description. Thanks for watching.