I was recently working on an Ionic/AngularJS app which needed to do the following:
– Upload a base64 image file (taken with the camera) to the Parse servers using the REST API.
– Associate the uploaded image file with an object and save the object to Parse using the REST API.
The Parse documentation didn’t seem to explain this specific case and other examples online seemed to all offer different details on how to get this done… so I ended up jumping through a few hoops until I eventually got it working. Below is an example of what I used to achieve this.
ImageSubmissionCtrl
// camera is simply an injected service, wrapping the cordova APIs .controller('ImageSubmissionCtrl', function($scope, $http, camera) { var vm = $scope; var imageData; // Object to save to Parse that includes an image var object = { text: "", image: null }; // Function to take a picture using the device camera vm.takePicture = function() { // Define various properties for getting an image using the camera var cameraOptions = { quality : 75, // This ensures the actual base64 data is returned, and not the file URI destinationType: Camera.DestinationType.DATA_URL, encodingType : Camera.EncodingType.JPEG }; // Use the Cordova Camera APIs to get a picture. For brevity, camera // is simply an injected service camera.getPicture(cameraOptions).then(function(returnedImageData) { imageData = returnedImageData; }, function(err) { console.log("Error taking picture: " + err); }); }; // Function to submit the object to Parse using the REST API vm.submitObject = function() { // This part is important. As part of the JSON that we send to Parse, // we need to specify the content type here as a field(__ContentType) // along with the image data. Notice that the Content-Type specified // in the headers is actually "plain/text" var dataToSubmit = {__ContentType : "image/jpeg", base64 : imageData}; // First upload the image file $http.post("https://api.parse.com/1/files/image.jpg", dataToSubmit, { headers: { "X-Parse-Application-Id": PARSE_APP_ID, "X-Parse-REST-API-Key": PARSE_REST_API_KEY, "Content-Type": "plain/text" } }) .success(function(result) { // Now associated the image file with the object coupleImageFileWithObject(result.name); }) .error(function(result) { console.log("Error uploading image file: " + err); }); }; // Function to associate the image file with an object and save the // object to Parse using the REST API function coupleImageFileWithObject(fileName) { // Assign the filename to our object prior to saving it to Parse object.image = {name : fileName, __type : "File"}; // The 'ObjectClass' in the url should be replaced by the class name // of the object you are saving $http.post("https://api.parse.com/1/classes/ObjectClass", object, { headers: { "X-Parse-Application-Id": PARSE_APP_ID, "X-Parse-REST-API-Key": PARSE_REST_API_KEY } }) .success(function(result) { console.log("Object successfully saved."); }) .error(function(result) { console.log("Error coupling image file with object: " + err); }); }; });
It’s important to understand that the first step is to upload the file to Parse independently of the containing object, and then only on a successful response associate the file handle with the object and save the object itself to Parse.