0

I have a problem with $https.post parameters on AngularJS. I read that AngularJS is creating a JSON for the params. So I applied the solution found here:

AngularJS - Any way for $http.post to send request parameters instead of JSON?

http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

But I still have problem with Python CGI.

[Edit]

Output of the console.log for objData:

Object {hostname: "test", id_venue: 20}

inspecting Request Payload:

action: "insert",
objData: { first: "test", second:"test2" }

[/Edit]

Website call

angular.module('myApp.services', [])
    .service('MyService', ['$http', '$q', function ($http, $q) {
        this.insert = function (objData){
            console.log(objData);
            var deferred = $q.defer();
            $http.post('api/api.py', { action: 'insert', objData: objData }).success(function (data, status, headers, config) {
                deferred.resolve(data);
            }).error(function (response) {
                deferred.reject("error");
            });
            return deferred.promise;
        };
   }])

Server side code is made with Python and CGI. It is unfortunately a constraint that I cannot use web frameworks.

api/api.py

import cgi
params = cgi.FieldStorage()

print 'Content-type: application/json'
print
print params
print params['objData'].value

Inspective the request headers and response, and I have obviously a KeyError:

FieldStorage(None, None, [MiniFieldStorage('action', 'insert'), MiniFieldStorage('objData[first]', 'test'), MiniFieldStorage('objData[second]', 'test2')])
KeyError: 'objData'

Any solution on how to correctly read params on Python CGI FieldStorage. Or any way to send them correctly with AngularJS? With $http.get I don't have any problem.

Maybe one solution could be to handle POST request directly in Python without using cgi.FieldStorage.

Community
  • 1
  • 1
Nicola
  • 425
  • 4
  • 17

1 Answers1

0

As far as I can see, on the js side, objData seems to contain {"first": "test", "second": "test2"}.

As a 1st recommendation, I would recommend to make your life easier by using objData keys as POST keys by doing sth like this on the js client side (I'm assuming objData keys don't start with a underscore so that on the server side, you can make a difference between action and obj keys) :

params = {_action:'insert'};
_.extend(params, objData); // using underscore or lodash
[...]
$http.post('api/api.py', params)

The potential problem is that your insert function is quite generic, objData could be anything (so sth else than a js dictionnary), my second recommendation would be to first serialize your objData as a json string (you can find js libs for this), then send {action: 'insert', 'jsondata': json_string}. On the python side, you will have to deserialize the json_string which is quite easy with json module.

Thus, you can both use a classical POST (<-> not full json encoded form data) and some json stuff.

HTH

Raphaël Braud
  • 1,489
  • 10
  • 14
  • About the 2nd recommendation, thanks, it perfectly works. I don't know why I didn't thought about that before! About the 1st recommendation, could you please clarify? What's the real benefit? – Nicola Jan 10 '14 at 10:25
  • If you're sure that objData is a Javascript dictionnary, 1st recommandation avoids to JSON-serialize on the JS side and deserialize on the Python side thus giving you some microseconds :p and another point is that it is a "normal" POST whereas 2nd reco creates some coupling between client and server (which must speak the same language). – Raphaël Braud Jan 10 '14 at 20:39