Rectangle 27 1

angularjs Sending an Angular post request with parameter to Rails API?


function($resource){          
    var businesses =
     $resource('http://127.0.0.1\\:3000/:business', {business:'businesses'}, {      
        query: {method:'GET', isArray: true},
        save: {method:'POST', isArray: false}
     });        
     return businesses;           
  }
$scope.createBusiness = function() {

        $scope.business.type = $scope.type; 
        $scope.business.plan = $scope.plan;     
        $scope.business = Business.save($scope.business);           
        $location.path('/user-dashboard');                              
    };
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers', 'myApp.i18n', 'demo']).
config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) {

$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common["X-Requested-With"];
match "/businesses" => "application#index", via: :options
  • In my view: <form novalidate="" name="createBusinessForm" ng-submit="setBusinessInformation()" class="css-form"> <label>* {{'BUSINESS_NAME' | translate}}</label> <input type="text" name="name" ng-model="business.name" class="input-xxlarge input-height-large" placeholder="{{'BUSINESS_NAME_PLACEHOLDER' | translate}}" required maxlength="80"> <span ng-show="createBusinessForm.name.$dirty && createBusinessForm.name.$error.required" class="text-error">Mandatory field.</span> <label>* {{'ID' | translate}}</label> <input type="text" ng-model="business.cif_nif" class="input-xlarge input-height-large" placeholder="{{'BUSINESS_ID_PLACEHOLDER' | translate}}" required maxlength="60"> <label>* {{'ADDRESS' | translate}}</label>
  • My Rails controller def create puts 'Businesses_controller.create!!!!!' puts business_params.inspect # business_type object is recovered from db businessTypeName = params[:type] businessType = BusinessType.where(:name => businessTypeName).first ... end
  • application_controller.rb class ApplicationController < ActionController::Base before_filter :set_headers def index puts "Do nothing." render nothing: true end def set_headers puts 'ApplicationController.set_headers' if request.headers["HTTP_ORIGIN"] # better way check origin # if request.headers["HTTP_ORIGIN"] && /^https?:\/\/(.*)\.some\.site\.com$/i.match(request.headers["HTTP_ORIGIN"]) headers['Access-Control-Allow-Origin'] = request.headers["HTTP_ORIGIN"] headers['Access-Control-Expose-Headers'] = 'ETag' headers['Access-Control-Allow-Methods'] = 'GET, POST, PATCH, PUT, DELETE, OPTIONS, HEAD' headers['Access-Control-Allow-Headers'] = '*,x-requested-with,Content-Type,If-Modified-Since,If-None-Match,Auth-User-Token' headers['Access-Control-Max-Age'] = '86400' headers['Access-Control-Allow-Credentials'] = 'true' end end end

I love you guys, @Rober you made me understand more about CORS with your solution. I applied and it works. .@david-tresner-kirsch, thanks for share that gem I applied too and I'm keeping that solution.

I will explain all my config in Angular and Rails 4 as I would have liked to read it.

Note: All the attributes you need to send in the post request. Apart from the form, you can assign some new attributes to the object before sending to Rails API. We will use a service with a resource object to send the POST request.

Note: I have a GET request to get the business from DB through Rails API and the POST one.

Note: New entry to match the OPTIONS request the Angular server will send to pre-negociate the start of sending the POST request.

Note: You can define as many fields as you need and with data bingind assign the values to an object.

There's a cleaner way to do this, using the rack-cors gem rather than hardcoding the headers. Check out the newer answer from @matthew-coarr

Note
Rectangle 27 1

angularjs Sending an Angular post request with parameter to Rails API?


gem 'rack-cors', :require => 'rack/cors'
  • edit config/application.rb to add the following block: config.middleware.insert_before "ActionDispatch::Static", "Rack::Cors", :debug => true, :logger => Rails.logger do allow do origins '*' resource '*', :headers => :any, :methods => [:get, :post, :delete, :put, :options], :max_age => 0 end end

Here are the quick steps that I followed:

Now in my case, I just wanted to open this up to any host, but you could be more restrictive. You can also limit headers and http methods too.

See more details on readme at the github page: https://github.com/cyu/rack-cors (The rack-cors author has example rails apps under examples/rails3 and examples/rails4)

The big benefit for me was that this takes care of both simple CORS requests (GET request and response) and preflighted requests that use OPTION requests (OPTIONS request and response and then POST request and response).

The quick rundown of what I did was use to the ruby library "rack-cors" (https://github.com/cyu/rack-cors) to manage all the CORS headers.

This means I didn't have to stick a bunch of hardcoded header name/values in my code.

We had the same problem and took a similar but hopefully simpler/quicker/more flexible approach.

Note