Sending an image via a post request from an Ionic app to a rails endpoint

I am currently working on an Ionic mobile application which will eventually take photos, attach a location and send them inside a post request to a rails endpoint. After looking at this link and this link and countless others, I have been unable to find any solid information on implementing this particular feature.

I can upload photos through the browser using a html input form, which is then added to the database and is displayed on the app via a get request.

However at the moment when taking a photo on the phone and attempting to send it via a post request directly from the app, only the location information is being received, the image is not being correctly encoded.

Here is the jSON data that has been received, its returning "image_url":"/images/main/missing.png".

    { "id":6,"city":"Greater London",
      "country":"United Kingdom","created_at":"2015-05-14T21:22:22.825Z",
      "updated_at":"2015-05-14T21:22:22.825Z","image_file_name":null,
      "image_content_type":null,"image_file_size":null,
      "image_updated_at":null,"image_url":"/images/main/missing.png" }

Here is the code:

Angular factory making post request:

.factory('Posts', function($http) {

  var o = { posts: [] };

  o.getAll = function() {
    return  $http.get('http://localhost:8100/posts').success(function(data) {
      angular.copy(data, o.posts);
    });
  };

  o.addPost = function(post) {
    return $http.post('https://shielded-hamlet-4665.herokuapp.com/posts', post);
  };

  return o;
})

Angular Controller taking photo:

.controller("CameraCtrl", function($scope, $cordovaCamera, $http, Posts) {

  var id = 0;

  var options = { 
    quality : 75, 
    destinationType : Camera.DestinationType.FILE_URI, 
    sourceType : 1, 
    allowEdit : true,
    encodingType: 0,
    targetWidth: 380,
    targetHeight: 450,
    popoverOptions: CameraPopoverOptions,
    saveToPhotoAlbum: false
  };

  function getLocCoords(position) {
    $scope.lat = position.coords.latitude;
    $scope.lon = position.coords.longitude;

    $http.get('http://maps.googleapis.com/maps/api/geocode/json?latlng=' + $scope.lat +',' + $scope.lon + '&sensor=true')
      .success(function(data) {

        var home = data.results[0].address_components;

        for (var i = 0; i < home.length; i++) {
          if(home[i].types.indexOf("administrative_area_level_2") > -1) {
            $scope.city = home[i].long_name;
            break;
          };
        };

        for (var i = 0; i < home.length; i++) {
          if(home[i].types.indexOf('country') > -1) {
            $scope.country = home[i].long_name;
            break;
          };
        };
      })
  };

  $scope.takePicture = function() {

    navigator.geolocation.getCurrentPosition(getLocCoords);

    $cordovaCamera.getPicture(options).then(function(imageData) {
      $scope.imgURI = imageData;
      id ++;
      var post = { id: id, country: $scope.country, city: $scope.city, image: $scope.imgURI, likes: 0, comments: [] }
      Posts.addPost(post);
    }, function(err) {

    });
  }

Post Controller from the Rails Database:

class PostsController < ApplicationController

  skip_before_filter :verify_authenticity_token

  def index
    @posts = Post.all
    render json: @posts, :callback => params['callback'], :content_type => 'application/javascript', :methods => [:image_url]
  end

  def new
    @post = Post.new
  end

  def create
    Post.create(post_params)
    redirect_to '/posts'
  end

  def post_params
    params.require(:post).permit(:city, :country, :image)
  end

end

I have not done a great deal of work with the ionic framework so please forgive my ignorance. Any help would be greatly appreciated.

Managed to solve this using the cordovaFileTransfer.upload method.

The rails end point was also filtering params and looking for a post object, with a image string, and only an image string was being provided.

The following code is now working

Angular factory making post request:

.factory('Posts', function($http, $cordovaFileTransfer) {

  var o = { posts: [] };

  o.getAll = function() {
    return $http.get('https://shielded-hamlet-4665.herokuapp.com/posts').success(function(data) {
      angular.copy(data, o.posts);
    });
  };

  o.addPost = function(post) {

    var options = {
      fileKey: "image",
      fileName: "image.jpeg",
      chunkedMode: false,
      mimeType: "image/jpeg",
      params: { city: post.city, country: post.country, lat: post.lat, lon: post.lon }
    };

    $cordovaFileTransfer.upload('http://shielded-hamlet-4665.herokuapp.com/posts', post.image, options)
      .then(function(result){
        console.log("Code = ok");
      }, function(error){
        console.log("Code = " + error);
      }, function(progress){});
  };

  return o;
})

Angular Controller taking photo:

.controller("CameraCtrl", function($scope, $cordovaCamera, $http, Posts) {

  post = {};

  var options = { 
    quality : 75, 
    destinationType : Camera.DestinationType.FILE_URI, 
    sourceType : 1,
    allowEdit : true,
    encodingType: 0,
    targetWidth: 380,
    targetHeight: 450,
    popoverOptions: CameraPopoverOptions,
    saveToPhotoAlbum: false
  };

  function getLocCoords(position) {
    post.lat = position.coords.latitude;
    post.lon = position.coords.longitude;

    $http.get('http://maps.googleapis.com/maps/api/geocode/json?latlng=' + post.lat +',' + post.lon + '&sensor=true')
      .success(function(data) {

        var home = data.results[0].address_components;

        for (var i = 0; i < home.length; i++) {
          if(home[i].types.indexOf("administrative_area_level_2") > -1) {
            post.city = home[i].long_name;
            break;
          };
        };

        for (var i = 0; i < home.length; i++) {
          if(home[i].types.indexOf('country') > -1) {
            post.country = home[i].long_name;
            break;
          };
        };
      })
  };

  $scope.takePicture = function() {

    navigator.geolocation.getCurrentPosition(getLocCoords);

    $cordovaCamera.getPicture(options).then(function(imageData) {
      post.image = imageData;
      Posts.addPost(post);
    }, function(err) {});
  };
});

Post controller from rails database:

class PostsController < ApplicationController

  skip_before_filter :verify_authenticity_token

  def index
    @posts = Post.all
    render json: @posts, :callback => params['callback'], :content_type => 'application/javascript', :methods => [:image_url]
  end

  def new
    @post = Post.new
  end

  def create
    Post.create(post_params)
    redirect_to '/posts'
  end

  def post_params
    params.permit(:city, :country, :image, :lat, :lon)
  end

end