pyramid not work with angular $http post
Asked Answered
I

6

5
$http({method: 'POST', url: 'http://localhost:5001/products', data: {token: $scope.product.token}}).success(
    function () {
        alert('success');
    }
);

In the pyramid side, request.POST show that NOVars: Not a form request. Not an HTML form submission( Content-Type: application/json)

I am using cornice to provide my api(/products) and I thinks it is pyramid's problem.

Does anyone have a solution?

Impressible answered 22/7, 2013 at 5:46 Comment(0)
H
4

Angular sends the post body (data) as application/json while forms are normally sent as application/x-www-form-urlencoded. Pyramid parses the body and let you access it in request.POST when it's encoded as a normal form.

It is not be possible to represent every data encoded the Angular way (json) as a key/value pair like is provided by pyramid API.

[
  1,
  2,
  3,
  4
]

Solution on Pyramid side

It can be solved per view or globally

Per view

This is the pyramid way and the most flexible way to handle this.

@view_config(renderer='json')
def myview(request):
    data = request.json_body
    # deal with data.
    return {
        "success" : True
    }

Globally

Pyramid can most likely be set to assume a body encoded as application/json is an object and its properties be put in request.POST.

Solution on Angular side

As with the pyramid side, it can be solved per request and globally.

Per request

You need to send the data the way forms are normally sent:

$http({
  method: 'POST',
  url: url,
  headers: {'Content-Type': 'application/x-www-form-urlencoded'},
  transformRequest: function(obj) {
    var str = [];
    for(var p in obj) {
      if (obj.hasOwnProperty(p)) {
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
      }
    }
    return str.join("&");
  },
  data: xsrf
}).success(function () {});

Globally

To send posts as form by default, configure the $httpProvider to do so.

angular.module('httpPostAsForm', [])
.config(['$httpProvider', function ($httpProvider) {
  $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
  $httpProvider.defaults.transformRequest.unshift(function (obj) {
     var str = [];
    for(var p in obj) {
      if (obj.hasOwnProperty(p)) {
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
      }
    }
    return str.join("&");
  });
}]);

Then include this module in your app:

angular.module("app", ["httpPostAsForm"]);
Hispidulous answered 10/12, 2014 at 16:56 Comment(0)
M
2

AngularJS $http.post is different from jquery's. The data you pass is not posted as a form but as json in the request body. So your pyramid view can not decode it as usual. You have to either:

Mena answered 15/4, 2014 at 9:0 Comment(0)
I
1

the answer is angular $post do OPTIONS request first and then do the POST request, get data form the request.json_body

Impressible answered 22/7, 2013 at 7:7 Comment(0)
U
1

Use req.json_body if you post some json-decoded content. req.GET, req.POST, req.params only cope with from submissions. Btw, $http -> ngResource -> restangular ...

Unreeve answered 13/8, 2013 at 9:51 Comment(0)
N
0

Try setting contenttype in $http, something like below.

 $http(
           {
               url: url,
               contentType: "application/json",
               data: data,
               method: method
           })
           .success(function (response) {
               successcb(response);
           }).error(function (data, status, headers, config) { errorcb(data); });
  };
Nuris answered 22/7, 2013 at 5:49 Comment(3)
by default content type is application/json in angular no need to specifyParathyroid
than check , that you are passing correct object to the post service , can you show your post service ?Nuris
my post service checks token params to decide whether the user got the permission to add a product, it works fine using curlImpressible
D
0

You can simply get the POST data this way:

query = json.loads(request.body)
Dispensary answered 27/7, 2013 at 20:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.