How to make uploading files or images using ionicframwork or angularJS

is any one got success to read the file size in onSuccess method after selecting file from gallery and before uploading to server.I am getting only file url in onSuccess method.

I wants to display the file size and actual file name with extention.Even i am not getting extention also only file url getting in onSuccess method like -
content://media/external/images/media/1234

$scope.takePic = function() {
        var options =   {
            quality: 50,
            destinationType: Camera.DestinationType.FILE_URI,
            sourceType: 0,      // 0:Photo Library, 1=Camera, 2=Saved Photo Album
            encodingType: 0     // 0=JPG 1=PNG
        }
        navigator.camera.getPicture(onSuccess,onFail,options);
    }
    var onSuccess = function(FILE_URI) {
        console.log(FILE_URI);
       //How to get file size and actual file name heare
    };
    var onFail = function(e) {
        console.log("On fail " + e);
    }

You will probably just need to add the extension to the name yourself. You know the extension based on the encodingType you specified. Default is JPG.

function resolveLocalFileSuccessHandler(fileEntry) { 
    alert(fileEntry.name);
    alert(fileEntry.fullPath);
    fileEntry.getMetadata(function(metadata) {
         alert(metadata.size); // or do something more useful with it..
   });
 } 

 $window.resolveLocalFileSystemURL(FILE_URI, resolveLocalFileSuccessHandler);

Hi Keithmoore,how and where we can we call resolveLocalFileSuccessHandler method or it will call automaticallyā€¦

As i add it within controller but its not calling.

I would suggest that you add an error handler to the function. And define that error handler. Maybe something like thisā€¦

function resolveLocalFileErrorHandler(error) {
     console.log(error);
}

$window.resolveLocalFileSystemURL(FILE_URI, resolveLocalFileSuccessHandler, resolveLocalFileErrorHandler); 

Thanks its working but still i am getting file name as number not the actual file name.

content://media/external/images/media/1234

This is expected behavior. You might have a look at this: https://github.com/don/cordova-filechooser
I have not used it, but it might help you.

1 Like

I am running into issues trying to implement this and will appreciate any help I can get.

My problem is that the DestinationType object is throwing an error as undefined ā€œCannot read property ā€˜FILE_URIā€™ of undefinedā€.

Is there something I am not getting right?

Cheers

I successfully implemented this with an Express server and ngCordova.

Install this plugin

cordova plugin add org.apache.cordova.file-transfer

Then I used this code

var options =   {
    quality: 100
    , destinationType: Camera.DestinationType.FILE_URI
    , sourceType: Camera.PictureSourceType.PHOTOLIBRARY
    , encodingType: Camera.EncodingType.JPEG
}

$cordovaCamera.getPicture(options).then(

	function(fileURL) {

		var uploadOptions = new FileUploadOptions();
		uploadOptions.fileKey = "file";
		uploadOptions.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
		uploadOptions.mimeType = "image/jpeg";
		uploadOptions.chunkedMode = false;

		$cordovaFile.uploadFile(<path to your server api>, fileURL, uploadOptions).then(
			function(result) {
				// Success!
			}, function(err) {
				// Error
			})
		;

	})

;

I used the multer npm module on my Express server to handle the file upload.
Of course this wonā€™t work in the browser, only on a device.

Even better, I just built a service to do this so that itā€™s easily reusable elsewhere.

You are using this option:

options.fileKey = "post";

However, this option ist backend-specific. I took me a long time to figure it out.

just remove the property if you donā€™t want this

#==================Tutorial=================


You can upload images or any other files in two possible methods:

  1. Convert it to BASE64 string and upload it to the server via REST call.
  2. Directly upload binary file to server using ngCordova File Transfer plugin

The second solution is usually a better one because it doesnā€™t require additional processing power required to convert binary data to BASE64 string. Use the first method only if you specifically need BASE64 representation.

ngCordova File Transfer plugin can be used like this:

// Destination URL, you can use other technologies beside PHP
var url = "http://example.gajotres.net/upload/upload.php";
 
//File for Upload
var targetPath = cordova.file.externalRootDirectory + "someFile.png";
 
// File name only
var filename = targetPath.split("/").pop();
 
var options = {
	 fileKey: "file",
	 fileName: filename,
	 chunkedMode: false,
	 mimeType: "image/jpg",
         params : {'directory':'upload', 'fileName':filename} // directory represents remote directory,  fileName represents final remote file name
 };
	  
 $cordovaFileTransfer.upload(url, targetPath, options).then(function (result) {
	 console.log("SUCCESS: " + JSON.stringify(result.response));
 }, function (err) {
	 console.log("ERROR: " + JSON.stringify(err));
 }, function (progress) {
	 // PROGRESS HANDLING GOES HERE
 });

params is most important parameter here because it will tell server side where to store uploaded file(s).

Hereā€™s an example of server-side PHP code:

	<?php
	header('Access-Control-Allow-Origin: *');
	 
	$location = $_POST['directory'];
	$uploadfile = $_POST['fileName'];
	$uploadfilename = $_FILES['file']['tmp_name'];
	 
	if(move_uploaded_file($uploadfilename, $location.'/'.$uploadfile)){
			echo 'File successfully uploaded!';
	} else {
			echo 'Upload error!';
	}
	?>

###Click here for a working example

#========================================

3 Likes

Hi @Gajotres,

Can I transfer file from img source? I am setting the cropped image to a hidden img as follows:

<div><img data-ng-src="data:image/jpeg;base64,{{myCroppedImage}}" ng-hide="true" id="image"/></div>

Best Regards.

Hi Sebastian,

Can u please share your html page of above mentioned controller, that would be a great favor.
Thanks in advance.

hi @Sebastian , the ionic code is really working it hit my server side code right , but i am missing something , can you please share your server side code if it is in express.js

can you please share the express server side code

Hey @nurfarazi in your main node file use the multer library to upload your files.

Their documentation should get you on your way :smile:

i tried multer but i donā€™t know something not right , i am posting my code can you please check.

var express = require('express');
var http = require('http');
var multer = require('multer');
var bodyParser = require('body-parser');
var multerS3 = require('multer-s3');
var aws = require('aws-sdk');
var app = express();

app.use(bodyParser.json({
limit: '50mb'
}));
app.use(bodyParser.urlencoded({
limit: '50mb',
extended: true
}));

app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});


var storage = multer.diskStorage({

destination: function (req, file, callback) {
    callback(null, './uploads');
    console.log('hit storage');
},
filename: function (req, file, callback) {
    callback(null, file.fieldname + '-' + Date.now());
    console.log('hit storage');
}
});

var upload = multer({
storage: storage
}).single('userPhoto');


app.post('/upload2', function (req, res) {
console.log('hit post');
upload(req, res, function (err) {
    if (err) {
        console.log(err);
        //console.log(req);
        return res.end("Error uploading file.");
    } else {
        console.log('done');
        res.end("File is uploaded");
    }

});
});

you can simply copy and paste the above code in server.js and test . and by the my ionic code is given below

angular.module('starter.controllers', ['ngCordova'])

.controller('DashCtrl', function ($scope, $cordovaCamera, $cordovaFileTransfer, $http) {


  $scope.takePic = function () {
    var options = {
        quality: 50,
        destinationType: Camera.DestinationType.FILE_URI,
        sourceType: 0, // 0:Photo Library, 1=Camera, 2=Saved Photo Album
        encodingType: 1 // 0=JPG 1=PNG
    }
    navigator.camera.getPicture(onSuccess, onFail, options);
}

var onSuccess = function (FILE_URI) {
    //console.log(FILE_URI);
    $scope.picData = FILE_URI;
    //$scope.picData = LZString.compressToUTF16(FILE_URI)
    $scope.$apply();
};

var onFail = function (e) {
    console.log("On fail " + e);
}

 $scope.send = function () {

    var options = {
        fileName: $scope.picData.substr($scope.picData.lastIndexOf('/') + 1),
        chunkedMode: false,
        mimeType: "image/png"
    };

    console.log($scope.picData);
    $cordovaFileTransfer.upload('http://localhost:8001/upload2', $scope.picData, options).then(function (result) {
            console.log("SUCCESS: " + JSON.stringify(result.response));
        },
        function (err) {
            console.log("ERROR: " + JSON.stringify(err));
        },
        function (progress) {
            console.log(progress);
        });

 }
})

the above code is complete controller code , so you dont have to worry about , can you please help me with this .

and the error i get is this

{ [Error: Unexpected field]
  code: 'LIMIT_UNEXPECTED_FILE',
  field: 'file',
  storageErrors: [] }

FYI: i use chrome inspect device feature to run the localhost in my android .
(chrome://inspect/#devices).

another thing, why i am getting image url like this
> ā€œcontent://com.android.providers.media.documents/document/image%3A42ā€

formate missing , does it make any sense ?

Hello,
please provide server side upload code. If anyone has working code please share with me.
I am trying to select image form gallery and upload with php
@yafraorg I have refer your code but there is no server side file available pls share with us .

Thank You.

regards,
Mahesh

Hi sebastian i am not able to understand the options object and i am also trying to do the file transfer but i invoke only error call not success call i am not sure what i am doing wrong please help me if you find any error.

i have posted my question in stack overflow http://stackoverflow.com/questions/36981211/how-to-transfer-the-taken-image-using-ngcordova-file-transfer-plugin-to-my-ftp but no reply .

here is my controller and services part

app.service('MyService',function(){
  var imgPath = [];

  this.getImgPath = function(){
    return imgPath;
  }
  this.setImgPath = function(path){
    console.log(path);
    imgPath = path ;

  }
});

app.controller('mycontroller',function($scope,$cordovaCamera,$cordovaFileTransfer,MyService){

  $scope.takePicture = function(){

    var options = { 
            quality : 75, 
            destinationType: Camera.DestinationType.FILE_URI,
            sourceType: Camera.PictureSourceType.CAMERA,
            allowEdit : false,
            encodingType: Camera.EncodingType.JPEG,
            mediaType: Camera.MediaType.PICTURE,
            targetWidth: 250,
            targetHeight: 250,
            popoverOptions: CameraPopoverOptions,
            saveToPhotoAlbum: false
        };
 
    

        $cordovaCamera.getPicture(options).then(function(imageURI) {
          console.log('invokeing cordovaCamera');
          $scope.image =  imageURI;
           MyService.setImgPath(imageURI);
          console.log($scope.image);
          console.log(imageURI);
          $scope.upload();        
        }, function(err) {
            // An error occured. Show a message to the user
            console.log(err);
        });
        
    };

    $scope.upload =function(){

      var options = {
         fileKey: "file",
         fileName: "gopi",
         chunkedMode: false,
         mimeType: "image/jpeg",
         params : {'user_token':'Chandru@123', 'user_email':'wepopusers'} // directory represents remote directory,  fileName represents final remote file name
       };
       console.log(options);
      $cordovaFileTransfer.upload('ftp://308.3d8.myftpupload.com/gopi/',  MyService.getImgPath(), options)
        .then(function(result) {
          // Success!
          console.log(result);
          console.log("SUCCESS: " + JSON.stringify(result.response));
          alert('ftp success');
        }, function(err) {
          // Error
          console.log(err);
          alert('ftp fail');
          console.log("ERROR: " + JSON.stringify(err));
        }, function (progress) {
          // constant progress updates
          console.log(progress);
        });

    };
  });

Hi Sebastian, I was able to upload the files to the server (node server) and now I deployed my server in heroku, but I was not able to upload the file when the server is running in heroku. Its because heroku does not provide storage space for storing files or images at run time. I noticed that you have used the heroku platform and can you help me with how did you solve this issue. Any help would be appreciated. :slight_smile: