How to Upload File/Image to Server with Form Data in React Native

Uploading File in React Native

In this post, I’ll show you how to Upload File/Image to Server with Form Data in React Native. This example will cover how to pick any file from the file system and upload it to the server. I have also shared the server-side PHP code with the React Native File upload example.

If you noticed the title we are going to use FormData to upload the File on the server because I personally do not like to add third-party dependencies in my projects as long as using those dependencies is the last option.

Why I use FormData for File Uploading in React Native?

If you search for the file uploading examples in React Native over the internet you will find many examples and most of them have used external third party dependencies to upload the file on the server, but I personally try to avoid the third-party dependencies and like to find the other solution and FormData is one of them. The reason for avoiding third-party dependencies and using FormData is

  1. Third-party dependencies can make your project bulky
  2. Managing the proper version of dependencies
  3. After the major update of the dependencies, you need to update the project as well
  4. It is very tough to update others code in case of small update required
  5. The special thing about FormData is that network methods, such as fetch, can accept a FormData object as a body. It is encoded and sent out with Content-Type: multipart/form-data.

These are the primary reasons for which I use FormData for File Uploading.

How to use FormData for File Uploading in React Native?

Uploading a file using FormDate is very simple. It is divided into 3 steps:

  1. Pick a file using any file picker. Here I am using react-native-document-picker for file picking
    const res = await DocumentPicker.pick({
        type: [DocumentPicker.types.allFiles],
    });
    this.setState({ singleFile: res });
  2. Create FormData by creating an object and appending the values you want to send to the server
    const data = new FormData();
    data.append('name', 'Image Upload');
    data.append('file_attachment', fileToUpload);
  3. Using fetch method calling a file upload web service which will send the created FormData as a multipart/form-data to upload the file
    let uploadImage = async () => {
        //Check if any file is selected or not
        if (singleFile != null) {
          //If file selected then create FormData
          const fileToUpload = singleFile;
          const data = new FormData();
          data.append('name', 'Image Upload');
          data.append('file_attachment', fileToUpload);
          let res = await fetch(
            'http://localhost//webservice/user/uploadImage',
            {
              method: 'post',
              body: data,
              headers: {
                'Content-Type': 'multipart/form-data; ',
              },
            }
          );
          let responseJson = await res.json();
          if (responseJson.status == 1) {
            alert('Upload Successful');
          }
        } else {
          //if no file selected the show alert
          alert('Please Select File first');
        }
    };

What We are Going to Create in Uploading File Example?

In this example, We are going to create one Screen with two buttons. One button to pick the file from the file system and another button to upload the file on the server.

If you face any challenge with the file picker then you can see Example of File Picker in React Native it will help you to solve your problems. Now let’s get started with the Example.

To Make a React Native App

Getting started with React Native will help you to know more about the way you can make a React Native project. We are going to use react-native init to make our React Native App. Assuming that you have node installed, you can use npm to install the react-native-cli command line utility. Open the terminal and go to the workspace and run

npm install -g react-native-cli

Run the following commands to create a new React Native project

react-native init ProjectName

If you want to start a new project with a specific React Native version, you can use the --version argument:

react-native init ProjectName --version X.XX.X
react-native init ProjectName --version react-native@next

This will make a project structure with an index file named App.js in your project directory.

Installation of Dependency

As I mentioned, to pick a file we are going to use react-native-document-picker which provides DocumentPicker component. To use react-native-document-picker we need to install it using the following commands

Open the terminal and jump into your project

cd ProjectName

Run the following command

npm install react-native-document-picker --save

Linking of Dependency

After the updation of React Native 0.60, they have introduced autolinking feature means we do not require to link the library but they have also mentioned that some libraries need linking and react-native-document-picker is one of those cases. So for that, we need to link the library using

react-native link react-native-document-picker

CocoaPods Installation

Now we need to install pods

cd ios && pod install && cd ..

Code for the File Upload in React Native

Open App.js in any code editor and replace the code with the following code

App.js

/* Example to Pick and Upload files in React Native */
/* https://aboutreact.com/file-uploading-in-react-native/ */

import React, { useState } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import DocumentPicker from 'react-native-document-picker';

const App = () => {
  let [singleFile, setSingleFile] = useState(null);

  let uploadImage = async () => {
    //Check if any file is selected or not
    if (singleFile != null) {
      //If file selected then create FormData
      const fileToUpload = singleFile;
      const data = new FormData();
      data.append('name', 'Image Upload');
      data.append('file_attachment', fileToUpload);
      //Please change file upload URL
      let res = await fetch(
        'http://localhost/upload.php',
        {
          method: 'post',
          body: data,
          headers: {
            'Content-Type': 'multipart/form-data; ',
          },
        }
      );
      let responseJson = await res.json();
      if (responseJson.status == 1) {
        alert('Upload Successful');
      }
    } else {
      //if no file selected the show alert
      alert('Please Select File first');
    }
  };

  let selectFile = async () => {
    //Opening Document Picker to select one file
    try {
      const res = await DocumentPicker.pick({
        //Provide which type of file you want user to pick
        type: [DocumentPicker.types.allFiles],
        //There can me more options as well
        // DocumentPicker.types.allFiles
        // DocumentPicker.types.images
        // DocumentPicker.types.plainText
        // DocumentPicker.types.audio
        // DocumentPicker.types.pdf
      });
      //Printing the log realted to the file
      console.log('res : ' + JSON.stringify(res));
      //Setting the state to show single file attributes
      setSingleFile(res);
    } catch (err) {
      setSingleFile(null);
      //Handling any exception (If any)
      if (DocumentPicker.isCancel(err)) {
        //If user canceled the document selection
        alert('Canceled from single doc picker');
      } else {
        //For Unknown Error
        alert('Unknown Error: ' + JSON.stringify(err));
        throw err;
      }
    }
  };
  return (
    <View style={styles.mainBody}>
      <View style={{ alignItems: 'center' }}>
        <Text style={{ fontSize: 30, textAlign: 'center' }}>
          React Native File Upload Example
        </Text>
        <Text
          style={{
            fontSize: 25,
            marginTop: 20,
            marginBottom: 30,
            textAlign: 'center',
          }}>
          www.aboutreact.com
        </Text>
      </View>
      {/*Showing the data of selected Single file*/}
      {singleFile != null ? (
        <Text style={styles.textStyle}>
          File Name: {singleFile.name ? singleFile.name : ''}
          {'\n'}
          Type: {singleFile.type ? singleFile.type : ''}
          {'\n'}
          File Size: {singleFile.size ? singleFile.size : ''}
          {'\n'}
          URI: {singleFile.uri ? singleFile.uri : ''}
          {'\n'}
        </Text>
      ) : null}
      <TouchableOpacity
        style={styles.buttonStyle}
        activeOpacity={0.5}
        onPress={selectFile}>
        <Text style={styles.buttonTextStyle}>Select File</Text>
      </TouchableOpacity>
      <TouchableOpacity
        style={styles.buttonStyle}
        activeOpacity={0.5}
        onPress={uploadImage}>
        <Text style={styles.buttonTextStyle}>Upload File</Text>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  mainBody: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
  buttonStyle: {
    backgroundColor: '#307ecc',
    borderWidth: 0,
    color: '#FFFFFF',
    borderColor: '#307ecc',
    height: 40,
    alignItems: 'center',
    borderRadius: 30,
    marginLeft: 35,
    marginRight: 35,
    marginTop: 15,
  },
  buttonTextStyle: {
    color: '#FFFFFF',
    paddingVertical: 10,
    fontSize: 16,
  },
  textStyle: {
    backgroundColor: '#fff',
    fontSize: 15,
    marginTop: 16,
    marginLeft: 35,
    marginRight: 35,
    textAlign: 'center',
  },
});

export default App;

Server Side PHP Code

Please find the server-side PHP code below. You will need to set up a local server to use this Script.

Core PHP Code (upload.php)

<?php
  if(!empty($_FILES['file_attachment']['name'])) {
    $target_dir = "uploads/";
    if (!file_exists($target_dir)) {
      mkdir($target_dir, 0777);
    }
    $target_file = $target_dir . basename($_FILES["file_attachment"]["name"]);
    $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    // Check if file already exists
    if (file_exists($target_file)) {
      echo json_encode(array("status" => 0, "data" => array() ,"msg" => "Sorry, file already exists."));
      die();
    }
    // Check file size
    if ($_FILES["file_attachment"]["size"] > 50000000) {
      echo json_encode(array("status" => 0, "data" => array() ,"msg" => "Sorry, your file is too large."));
      die();
    }
    if (move_uploaded_file($_FILES["file_attachment"]["tmp_name"], $target_file)) {
      echo json_encode(array("status" => 1, "data" => array() ,"msg" => "The file ". basename( $_FILES["file_attachment"]["name"]). " has been uploaded."));
    } else {
      echo json_encode(array("status" => 0, "data" => array() ,"msg" => "Sorry, there was an error uploading your file."));
    }
  }
?>

PHP CodeIgniter Code

/*  Update Images*/
public function uploadImage() {	
  if(!empty($_FILES['file_attachment']['name'])) {
    $res        = array();
    $name       = 'file_attachment';
    $imagePath 	= 'assets/upload/file_attachment';
    $temp       = explode(".",$_FILES['file_attachment']['name']);
    $extension 	= end($temp);
    $filenew 	= str_replace($_FILES['file_attachment']['name'],$name,$_FILES['file_attachment']['name']).'_'.time().''. "." .$extension;  		
    $config['file_name']   = $filenew;
    $config['upload_path'] = $imagePath;
    $this->upload->initialize($config);
    $this->upload->set_allowed_types('*');
    $this->upload->set_filename($config['upload_path'],$filenew);
    if(!$this->upload->do_upload('file_attachment')) {
      $data = array('msg' => $this->upload->display_errors());
    } else {
      $data = $this->upload->data();	
      if(!empty($data['file_name'])){
        $res['image_url'] = 'assets/upload/file_attachment/'.$data['file_name']; 
      }
      if (!empty($res)) {
	echo json_encode(array("status" => 1, "data" => array() ,"msg" => 'upload successfully', 'base_url' => base_url(), "count" => '0'));
      }else{
	echo json_encode(array("status" => 1,"data" => array() ,"msg" => 'not found', 'base_url' => base_url(), "count" => '0'));
      }
    }
  }
}

To Run the React Native App

Open the terminal again and jump into your project using.
cd ProjectName
To run the project on an Android Virtual Device or on real debugging device
react-native run-android
or on the iOS Simulator by running
react-native run-ios (macOS only).

Output Screenshots

File Upload 1         

This is how you can upload File/Image to Server with Form Data in React Native. If you have any doubts or you want to share something about the topic you can comment below or contact us here. There will be more posts coming soon. Stay tuned!

Hope you liked it. 🙂


Related Posts

2 thoughts on “How to Upload File/Image to Server with Form Data in React Native”

  1. I’m always getting “‘Unknown Error: {}” when I use select file. Is the Promise handled correctly? I’m not sure what is wrong. I’m just trying to run App.js

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.