Upload image on cloudinary

I want to upload a picture from my device in a back-end storage. I think that more attractive to use cloudinary. But, I don’t know how I use this framework with ionic. Can’t you give me a easy example?

I have add on my Utils.js the service:

`(function () {
    function ius($q, $ionicLoading, $cordovaFile ) {  //$translate
        var service = {};
        service.uploadImage = uploadImage;
        return service;
        function uploadImage(imageURI) {
            var deferred = $q.defer();
            var fileSize;
            var percentage;
            // Find out how big the original file is
            window.resolveLocalFileSystemURL(imageURI, function (fileEntry) {
                fileEntry.file(function (fileObj) {
                    fileSize = fileObj.size;
                    // Display a loading indicator reporting the start of the upload
                    $ionicLoading.show({ template: 'Uploading Picture : ' + 0 + '%' });
                    // Trigger the upload
                    uploadFile();
                });
            });
            function uploadFile() {
                // Add the Cloudinary "upload preset" name to the headers
                var uploadOptions = {
                    params: { 'upload_preset': CLOUDINARY_CONFIGS.UPLOAD_PRESET }  //CLOUDINARY_CONFIGS.UPLOAD_PRESET
                };
                $cordovaFile
                  // Your Cloudinary URL will go here
                  .uploadFile(CLOUDINARY_CONFIGS.API_URL, imageURI, uploadOptions)  //

                  .then(function (result) {
                      // Let the user know the upload is completed
                      $ionicLoading.show({ template: 'Upload Completed', duration: 1000 });
                      // Result has a "response" property that is escaped
                      // FYI: The result will also have URLs for any new images generated with 
                      // eager transformations
                      var response = JSON.parse(decodeURIComponent(result.response));
                      deferred.resolve(response);
                  }, function (err) {
                      // Uh oh!
                      $ionicLoading.show({ template: 'Upload Failed', duration: 3000 });
                      deferred.reject(err);
                  }, function (progress) {
                      // The upload plugin gives you information about how much data has been transferred 
                      // on some interval.  Use this with the original file size to show a progress indicator.
                      percentage = Math.floor(progress.loaded / fileSize * 100);
                      $ionicLoading.show({ template: 'Uploading Picture : ' + percentage + '%' });
                  });
            }
            return deferred.promise;
        }
    }
    angular.module('App').factory('ImageUploadService', ius);
})();`

And on my controller:

'Use Strict';
angular.module('App').controller('editeventController', function ($scope,ImageUploadService) {


    $scope.upload = function () {
      
        ImageUploadService.uploadImage("img/test.jpg").then(  
        function (result) {

            var url = result.secure_url || '';
            var urlSmall;

            if (result && result.eager[0]) urlSmall = result.eager[0].secure_url || '';

            // Do something with the results here.

            $cordovaCamera.cleanup();

        },
        function (err) {

            // Do something with the error here
            $cordovaCamera.cleanup();

        });
      
    }

But I have this error :

TypeError: window.resolveLocalFileSystemURL is not a function
at Object.uploadImage (http://localhost:8100/js/services/utils.js:78:20)
at Scope.$scope.upload (http://localhost:8100/views/editevent/editevent.js:183:28)
at fn (eval at (http://localhost:8100/lib/ionic/js/ionic.bundle.js:26457:15), :4:209)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:62386:9
at Scope.$eval (http://localhost:8100/lib/ionic/js/ionic.bundle.js:29158:28)
at Scope.$apply (http://localhost:8100/lib/ionic/js/ionic.bundle.js:29257:23)
at HTMLButtonElement. (http://localhost:8100/lib/ionic/js/ionic.bundle.js:62385:13)
at HTMLButtonElement.eventHandler (http://localhost:8100/lib/ionic/js/ionic.bundle.js:16583:21)
at triggerMouseEvent (http://localhost:8100/lib/ionic/js/ionic.bundle.js:2948:7)
at tapClick (http://localhost:8100/lib/ionic/js/ionic.bundle.js:2937:3)

Can you help me?

Here is how I do it. I didn’t use the same approach you did and don’t really have time to debug your code, so I will give you my way and hope this will be able to help you.

After getting the local path to the image through the plugin I use (later referred as mediaUrl) I call this function, stored in a factory :

manageMediaObj.simpleUploadToCloudinary = function (mediaUrl) {
    var deferred = $q.defer();

    // This is the call to my server to get the signing key. Tags are just for convenience, userid is for security check (does that user has rights to upload things ?) and mode is for me to know whether I'm uploading to my dev or prod environment.
    $http({
        url: 'http://myserver.com/cloudinary/cloudinary_call.php',
        method: "POST",
        data: "tag=wantedTags&user=" + userid + '&mode=dev'
    }).
        success(function(signData, status, headers, config) {
            // Now signData contains the needed signature for upload to work !

            var options = new FileUploadOptions();
            options.fileKey = "file";
            options.fileName = mediaUrl.substr(mediaUrl.lastIndexOf('/') + 1);

            options.params = signData;

            // This is the upload itself. Change MYCUSTOMID, of course
            $cordovaFileTransfer.upload('https://api.cloudinary.com/v1_1/MYCUSTOMID/auto/upload', mediaUrl, options).then(function(result) {
                deferred.resolve(result);
            }, function(err) {
                deferred.reject(err);
            }, function (progress) {
            // I use this to show a progress bar to the user
                if( progress.lengthComputable ) {
                    var uploadProgress = progress.loaded / progress.total;
                    deferred.notify(uploadProgress);
                }
            });
        }).
        error(function(data, status, headers, config) {
            console.log("error", data, status, headers, config);
        });

    return deferred.promise;
};

Now on the server side, I used Cloudinary’s PHP open source library and a custom PHP script, that’s the cloudinary_call.php in the above code. I can’t post the whole document for security reasons, but what you would do is something like this :

// Cloudinary resources to include
require "lib/Cloudinary.php";
require 'lib/Uploader.php';

// Do every needed security check, and store sanitized inputs - like $_POST['tag'] in $tag after sanitization, then load Cloudinary config like that
\Cloudinary::config(array(
    "cloud_name" => "MYCUSTOMID",
    "api_key" => "MYAPIKEY",
    "api_secret" => "MYAPISECRET"
));

// Sign the upload to authorize it
$options = array("tags" => ($tag ? $tag : ""), "html" => array("multiple" => true));
$params = Cloudinary\Uploader::build_upload_params($options);
$params = Cloudinary::sign_request($params, $options);

// Send back the data
echo json_encode($params);

And this works. Hope it helps.

[EDIT] of course you will need ngCordova. The fileTransfer and the File plugins as well.

@JerryBels, In the abouve mentioned code, what is the mediaUrl? Can you post a sample?
Because I am using almost the same code to upload and it gives me unsupported source url.
I am trying to upload image.

1 Like

It’s really basic local path, like /storage/path/to/the/selecteditem.jpg - you simply need to make sure you have the file plugin and the filetransfer plugin up to date, and it should work. I don’t remember me being bothered by anything else like user rights or things like this so I can’t really help much further…

This link will helppful