Using angular 1.1.5 and needing to pass urlencoded data to the backend. I've gotten this to work with solution from here: How can I post data as form data instead of a request payload?
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: xsrf
}).success(function () {});
I've embedded this into my controller with success, but the 'cleaner' way is to use a service, and $resource instead of the $http object. It is possible to use transformRequest with $resource after 1.1.2 from this topic: $resource transformResponse not working but I cannot find any working examples. Can anyone provide an example of the above solution as a service object using $resource?
For csrf, In a rails app you have to add <%= csrf_meta_tags %>
in your header layout (if not there by default)
var app = angular.module('app', ['ngResource']);
app.config(["$httpProvider", function(provider)
{
provider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
}]);
Here is a service object
app.factory('$folders', ['$resource', function($resource)
{
return $resource('/folders/:id',
{ id: '@id' },
{
list: { method: 'GET' , isArray: true }, //same as query
create: { method: 'POST' }, // same as save
update: { method: 'PUT' }
// DEFAULT IMPLEMENTATION OF $RESOURCE
// 'get': {method:'GET'},
// 'save': {method:'POST'},
// 'query': {method:'GET', isArray:true},
// 'remove': {method:'DELETE'},
// 'delete': {method:'DELETE'}
});
}]);
Here is an example into a controller
app.controller('projectController', ['$scope', '$folders', function($scope, $folders)
{
$scope.folders = $folders.list();
}]);
Folders.list()
will automatically do GET /folders/
on the server and return the result(that should be json) as an object.
Directly after $scope.folders = Folders.list();
in the controller, $scope.folders
will be empty, it will be populated in time, when the response comes back from the server.
Simple examples with $http and $ressources http://jsfiddle.net/jhsousa/aQ4XX/
here is a form
%form{'ng-submit' => 'create(item)', 'ng-controller' => 'projectController', 'ng-init' => 'item.orientation=1;'}
%input{'ng-model'=>'item.folderName', :type => :text, :placeholder => 'Name', :name => 'folderName'}
%textarea{'ng-model'=>'item.description', :placeholder => 'Description', :required=>true, :name => 'description'}
%input{'ng-model'=>'item.orientation', :type=>'radio', :name=>'orientation', :value=>'1'}
%input{'ng-model'=>'item.orientation', :type=>'radio', :name=>'orientation', :value=>'2'}
%input{:type => :submit, :value => 'Create', :name => 'new-project'}
You'll notice the ng-model
.
'ng-model'=>'item.folderName'
will create a $scope.item
in the projectController
and add a key folderName
in it. Same for the others ng-model
's.
'ng-init'=>'item.orientation=1;'
is going to execute the expression. So it will do the following item.orientation=1
, this way we set a default value for our radio inputs, so simple.
When the form is submitted ng-submit
will catch it and call the create
action from the projectController
with item
as parameter, no need to say that item
will contain the inputs values?
Here is the controller part
app.controller('projectController', ['$scope', '$folders', function($scope, $folders)
{
$scope.create = function(item)
{
f = new $folders(item);
f.$save(function(data,headers)
{
alert('SAVED');
},
function(err,headers)
{
alert('FAILED');
});
};
}]);
$scope.create
is the action that will be called by ng-submit
, item
is the item
parameter from the form as well, so you'll find stuff inside such as item.description
.
Folders
is the service object we talked about earlier.