I was recently asked by one of my subscribers if I knew how to upload files from an Android or iOS device to a remote server using Ionic Framework. My initial response was no, but it didn’t stop me from taking a whack at it.
Using the AngularJS extension set, ngCordova, with Ionic Framework and the Apache Cordova File Transfer plugin, you can easily upload files to a remote server.
This tutorial assumes you already have a functional web application that accepts file uploads from different domains or platforms. I will be using a locally hosted web application created with Node.js and SailsJS, but I won’t be explaining it in this example.
Let’s start by creating a fresh Ionic project using our Terminal:
ionic start IonicProject blank
cd IonicProject
ionic platform add android
ionic platform add ios
Note, if you’re not on a Mac, you cannot add and build for iOS.
We’ll be using ngCordova in this project to make our lives easier, so go ahead and download the latest release and copy the ng-cordova.min.js file into your www/js directory.
Open your index.html file and include the script so it looks something like the code below:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="js/ng-cordova.min.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
It is very important you put ng-cordova.min.js above the cordova.js script include otherwise none of this will work correctly.
Now crack open your js/app.js file because we need to alter the angular.module
to support ngCordova:
var example = angular.module('starter', ['ionic', 'ngCordova']);
We’re not done. At this point we’ve finished including ngCordova into our project, but it is only an extension set to the real plugin. We still need to install the Apache Cordova File Transfer plugin. Run the following from your Terminal:
cordova plugin add org.apache.cordova.file-transfer
Time to start taking care of business. Inside your js/app.js file, we are going to create a new controller with an upload()
method. It will look something like this:
example.controller("ExampleController", function($scope, $cordovaFileTransfer) {
$scope.upload = function() {
}
});
We are going to follow the official File Transfer documentation pretty closely at this point. First we need to construct our options
object which is explained by the following:
Object Key | Object Type | Description |
---|---|---|
fileKey | string | The name of the form element |
fileName | string | The name to use when saving the file on the server |
httpMethod | string | The HTTP method to use |
mimeType | string | The mime type of the data to upload |
params | object | The set of key pairs to pass in the request |
chunkedMode | boolean | Whether to upload the data in chunked streaming mode |
headers | object | The map of header name and values |
Most of the above information was taken from the official documentation. Based on this information our options
object will look like this:
var options = {
fileKey: "avatar",
fileName: "image.png",
chunkedMode: false,
mimeType: "image/png"
};
Only thing left to do is submit the POST request that contains the image file:
$cordovaFileTransfer.upload("http://192.168.56.1:1337/file/upload", "/android_asset/www/img/ionic.png", options)
A few things to note about the above line. $cordovaFileTransfer.upload
will return a promise. In this particular scenario we will be using a file from the Android project’s assets directory. It won’t exist in iOS. I suggest you read my previous post on Apache Cordova files or further explore the File documentation for ngCordova if you want a more cross platform solution. I am just keeping it simple in this example with the assets directory.
Our finished controller should look like this:
example.controller("ExampleController", function($scope, $cordovaFileTransfer) {
$scope.upload = function() {
var options = {
fileKey: "avatar",
fileName: "image.png",
chunkedMode: false,
mimeType: "image/png"
};
$cordovaFileTransfer.upload("http://192.168.56.1:1337/file/upload", "/android_asset/www/img/ionic.png", options).then(function(result) {
console.log("SUCCESS: " + JSON.stringify(result.response));
}, function(err) {
console.log("ERROR: " + JSON.stringify(err));
}, function (progress) {
// constant progress updates
});
}
});
All that’s left is to create the front end for this. Open your index.html file and add the following code:
<ion-content ng-controller="ExampleController">
<button class="button" ng-click="upload()">Upload From Assets</button>
</ion-content>
The above code just creates a button that will be used for uploading the file. Now earlier I said that I was using SailsJS as my locally hosted server. Based on the code from the quickstart, my server will return the following upon a successful upload:
{
"message": "1 file(s) uploaded successfully!",
"path": "assets/images",
"files": [
{
"fd": "/Users/nraboy/Desktop/TestSite/assets/images/9be2fe02-cd32-451c-8e81-b3f9756699c5.png",
"size": 4757,
"type": "image/png",
"filename": "image.png",
"status": "bufferingOrWriting",
"field": "avatar"
}
]
}
You can see how simple that was to get files uploaded. A common use case might be if you’re trying to create the next Instagram. You can have your users upload images and other media to your server directly from their device.
A video version of this article can be seen below.