Uploading files in Ionic application using Web API
After trying a lot solution I have come with below answer.
Board.html
<ion-view> <ion-nav-bar class="bar"> <ion-nav-title> <h1 class="title"> Create Board </h1> </ion-nav-title> </ion-nav-bar> <form name="boardForm" ng-submit="addBoard(data)"> <ion-content padding="false" scroll="true" has-bouncing="false"> <div id="form"> <div style="text-align: center; padding-top: 2%; padding-bottom: 2%;"> <div id="image-preview"> <label for="image-upload" id="image-label"><img src="{{ImagePrefix}}/task_plus.png" alt=""/></label> <input type="file" name="board_background" id="image-upload" file-model="data.board_background"> </div> <p>Add Cover</p> </div> <ion-list> <ion-item style="background-color: #F8F8F8;"> <label class="control-label" for="board_name">BOARD NAME</label> </ion-item> <ion-item ng-class="{true:'error'}[submitted && boardForm.board_title.$invalid]"> <input type="text" id="board_name" ng-model="data.board_title" placeholder="Add a Name" name="board_title" required> <p ng-show="submitted && boardForm.board_title.$error.required"> Please enter a board name </p> </ion-item> </ion-list> </div> </ion-content> <ion-footer-bar> <button class="button button-block control-button bottomOfPage" ng-click="submitted = true"> CREATE </button> </ion-footer-bar> </form> </ion-view>
directive
.directive('fileModel', ['$parse', function ($parse) { return { restrict: 'A', link: function (scope, element, attrs) { var model = $parse(attrs.fileModel); var modelSetter = model.assign; element.bind('change', function () { scope.$apply(function () { modelSetter(scope, element[0].files[0]); }); }); } }; }])
Controller
.controller('ManageBoardCtrl', function ($scope, $http, $ionicPopup, $state, BoardService) { $scope.submitted = false; $scope.data = {}; $scope.addBoard = function(formData) { BoardService.CreateBoard(formData).then(function(response) { if (response === "success") { $ionicPopup.alert({ title: "Success", template: "Board created successfully" }); } }, function (response) { $ionicPopup.alert({ title: "Failed", template: "Somethings wrong, Can not create boards at now." }); }); } })
Service
.service('BoardService', function ($q, $http) { var getUrl = API_URL + "boards"; var createBoard = function (fData) { var formData = new FormData(); formData.append("board_title", fData.board_title); formData.append("board_background", fData.board_background); return $q(function (resolve, reject) { $http({ transformRequest: angular.identity, method: 'POST', url: getUrl, headers: { 'Content-Type': undefined }, data: formData }).success(function (response) { if (response.success === true) { resolve('success'); } else { reject('fail'); } }).error(function () { reject('requesterror'); }); }); }; return { CreateBoard: createBoard }; })
After deploying application for android / iPhone file selection will handle the browsing Images based on the OS.
One simple thing I can suggest,
Use input["file"] tag to select the image. You will get the file object and a temporary url. with this url you can show the image in the form.
Then use formData to append the image and the other field.
e.g.
var fd = new FormData(); fd.append('board_background', $scope.image, $scope.image.name); fd.append('board_id', 321); fd.append('board_title', 'Dummy title'); var xhr = new XMLHttpRequest(); xhr.open('PUT', YOUR_URL, true); xhr.onload(function(res){ // Write your callback here. }); // Send the Data. xhr.send(fd);
Hope it will help you and meet your requirements.
First of all to need to select the image from device.
vm.getImages = function () { var options = { quality: 70, destinationType: Camera.DestinationType.DATA_URL, sourceType: Camera.PictureSourceType.PHOTOLIBRARY, allowEdit: true, correctOrientation:true, encodingType: Camera.EncodingType.JPEG, targetWidth: 300, popoverOptions: CameraPopoverOptions, saveToPhotoAlbum: true }; navigator.camera.getPicture(onSuccess, onFail, options); function onSuccess(imageURI) { vm.image = "data:image/jpeg;base64," + imageURI; vm.imageURI = imageURI; } function onFail(message) { console.log('Failed because: ' + message); } };
You can change the source type for input if needed.
sourceType: Camera.PictureSourceType.CAMERA,
On success you get ImageURI either use it directly or convert it to base64 as mentioned below for uploading.
vm.image = "data:image/jpeg;base64," + imageURI;
After this you can use the FileTransfer plugin to upload file and track the progress at the same time.
cordovaFileTransfer.upload() .then(function (result) {}, function (err) {}, function (progress) {});