Search code examples
ruby-on-railsangularjsdeviseangular-resource

How to wrap an object around my data when using Angular $resource


I have a simple angular service that returns a $resource. Lets say it looks like this:

$resource '/users/:id/:options.json', {id: '@id', options: '@options'},
            create_user: {
                method: 'POST'
            }

Now in my controller I use this resource by creating a new instance of my user service:

user = new UserService()
                user.name = $scope.user.name
                user.email = $scope.user.email
                user.password = $scope.user.password
                user.password_confirmation = $scope.user.password_confirmation
                user.$create_user()

But when the last line is executed, the data is sent but it is not in a object.

Now I have Devise managing my user account and looking into their registration controller, it seems they expect me to send the data in an object called: sign_up.

How can I describe in the $resource, that I want my data to be encapsulated in my custom object?

EDIT: This is what server gets. It is not happy with it and says that every value is missing.

Parameters: {"name"=>"foo", "email"=>"foo@bar.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "registration"=>{"name"=>"foo", "email"=>"foo@bar.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}

EDIT2: Working server log with .erb registration:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"xMEDtMWf72yuTwbkaq21c0ZKynoBSWnSypXfm+xJYvNph1d4iKqLIBwwe0DSA3I/YCU+pAHDd23ylc4y7ximEQ==", "user"=>{"name"=>"lol", "email"=>"lol@lol.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}

Solution

  • I would recommend using transformRequest on that route. Your code would look something like this.

    $resource('/users/:id/:options.json',
              {id: '@id', options: '@options'},
              {
                  create_user: {
                      method: 'POST', 
                      transformRequest: function(data, headers) {
                          return angular.toJson({
                              user: data
                          });
                      }
                  }
              });
    

    This allows you to change the data being sent. The data object passed to transformRequest is your User object. The headers will already have the Content-Type application/json so you don't need to add that here.