Angular $ http and Rails 4 params

I am using the rails-api gem to have only Rails API and use Angular to manage my interface. Whenever I use $ http, it will only work if I go to params

instead data

. Here's an example trying to log in a user and create a new session:

'use strict';

app.controller('LoginCtrl', function($scope, $location, $http, tokenHandler) {
  $scope.login = function() {
    $http({
      url: 'http://localhost:3000/api/admins/sign_in',
      method: 'POST',
      params: $scope.admin
    }).success(function(data) {
      if (data.success) {
        $scope.ngModel = data.data.data;
        tokenHandler.set(data.data.auth_token);
        $location.path('/admin/blog');
      } else {
        $scope.ngModel = data;
        $scope.user.errors = data.info;
      }
    }).error(function(msg) {
      $scope.admin.errors = 'Something is wrong. Please try again.';
    });
  };
});

      

If I used params instead data: { admin: $scope.admin }

, Rails complains to me that it params[:admin]

is zero. It doesn't seem to be happening.

However, if I use params, I get this:

Started POST "/api/admins/sign_in?email=raderj89@gmail.com&password=[FILTERED]" for 127.0.0.1 at 2014-09-07 20:08:04 -0400
Processing by Admin::SessionsController#create as HTML
  Parameters: {"email"=>"raderj89@gmail.com", "password"=>"[FILTERED]"}

      

What can I work with. It's just weird that it seems like it only works when the request is being processed as HTML. When I use data

I get this:

Started OPTIONS "/api/admins/sign_in" for 127.0.0.1 at 2014-09-07 20:36:24 -0400
Processing by Admin::SessionsController#create as */*

      

Can we say that processing is done with */*

? I think he should understand that he has to be handled by json on purpose.

My session controller looks like this:

class Admin::SessionsController < Devise::SessionsController
  skip_before_filter :verify_authenticity_token

  before_filter :authenticate_user!, except: [:create]
  respond_to :json

  # ...
end

      

It's weird that I definitely got it the first time just using it data: { admin: $scope.admin }

, but since then the options never seem to fire if I don't use params: $scope.admin

.

and

I am using Devise for authentication and I had to add this to my ApplicationController:

class ApplicationController < ActionController::API
  include ActionController::MimeResponds

  before_filter :set_cors_headers
  before_filter :cors_preflight

  private 

    def set_cors_headers
      headers['Access-Control-Allow-Origin'] = AppConfig.client['origin']
      headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS'
      headers['Access-Control-Allow-Headers'] = '*'
      headers['Access-Control-Max-Age'] = "3628800"
    end

    def cors_preflight
      head(:ok) if request.method == :options
    end
end

      

Has anyone ever dealt with this before?

+3


source to share


2 answers


I finally got it working, and while I'm still confused, I think I have somewhere near what is the problem: My CORS configuration in my Rails API.

From what I've learned, Angular sends data in JSON format by default. This is executed as "Content-Type: application / json; charset = UTF-8" whereas in JQuery AJAX requests it goes through "Content-Type: application / x-www-form-urlencoded; charset = UTF-8" and is converted to a query string with $.param()

. Let's say I have probably heard this before, but have not yet registered this fact and its consequences.

In my application controller, I configured my CORS settings like this:

def set_cors_headers
  headers['Access-Control-Allow-Origin'] = AppConfig.client['origin']
  headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS'
  headers['Access-Control-Allow-Headers'] = '*'
  headers['Access-Control-Max-Age'] = "3628800"
end

def cors_preflight
  head(:ok) if request.method == :options
end

      

AppConfig

is just OpenStruct telling my Rails API which source to accept requests from. And then everything else was to just set the CORS headers.



For some reason, I'm still not sure if this didn't work for JSON requests. I got the above code from a tutorial using Angular and Rails, and in the case of the tutorial, they manually removed the asset pipeline, leaving everything else in Rails, whereas rails-api removes some of the Rails configuration. This is probably why setting CORS headers in ApplicationController didn't work.

What was the work with the gem-resistant , then add this bit to development.rb:

  config.middleware.use Rack::Cors do
    allow do
      origins 'localhost:9000'
      resource '*', :headers => :any, :methods => [:get, :post, :options, :delete]
    end
  end

      

Tells my application to accept requests from localhost: 9000 and accept any headers. I felt like I was doing this with the help headers['Access-Control-Allow-Headers'] = '*'

in my ApplicationController, but I guess not. Once I told Rails to use these staging settings, everything worked fine. Now my Rails API can accept application/json

from my Angular app.

If anyone can fill in the blanks where I am still confused, I would appreciate it. But I hope this helps others.

+1


source


You can send either: params or: data (or both, I think). According to the angularjs docs at https://docs.angularjs.org/api/ng/service/$http

params - {Object.} - Map of strings or objects that will be rotated to? key1 = value1 & key2 = value2 after the url. If the value is not a string, it will be JSONified.

data - {string | Object} - the data that will be sent as the data of the request message.

The controller expects http-type parameters / form data, so passing an object through params works - it gets transformed while still passing the same thing through: the data isn't because it doesn't get transformed.



I don't know if there is a way to unpack the data format at the end of the Rails Controller, but you can convert the object in your $ http request to serialized parameters using $ .param (data) http://api.jquery.com/jQuery.param/

data: $.param($scope.your_data_object) e.g. $scope.admin

      

and then unpack the [: data] parameters on the controller.

0


source







All Articles