Sending data in 'Request Payload' using amplifyjs - amplifyjs

I have a javascript object to be sent to server as follow :
var input = {a: 'aaa', b: 'bbb', c: 'ccc'};
And I want to send 'a' property in url like this
http://localhost/rest/customer/aaa
That's fine with url substitution feature in amplifyjs as follow :
amplify.request.define('update-customer', 'ajax', {
url : 'rest/customer/{a}',
dataType: 'json',
type : 'PUT'
contentType : 'application/json; charset=utf-8;
});
amplify.request('update-customer', { a : input.a, data : input });
The point I am struggling with is that I would like to send b and c property as a form data in json format as a 'Request Payload', however it is failed becauseof the form data is sent as follow :
Request Payload :
data : {b : 'bbb', c : 'ccc'}
So what I want to achieve is to remove 'data' key in 'Request Payload' as follow :
Request Payload :
{b : 'bbb', c : 'ccc'}
I tested this in REST Client program and was successed.
To wrap up my question, How to send data attached in Request Body without key name using amplifyjs?
Thanks in advance.

Try with:
amplify.request.define('update-customer', 'ajax', {
url: 'rest/customer/{a},
dataType: 'json',
type: 'PUT',
contentType: 'application/json; charset=utf-8',
data: {
b : '{b}',
c : '{c}'
}
});
amplify.request('update-customer', { a : input.a, data : input });
This solution has a problem if input.b or input.c are null. Check this post for further details

Related

Groovy wslite.rest.RestClient post or put results in a 411 Length Required Error

Using the wslite.rest.RestClient, if I use post or put, I'm getting a 411 Length Required error returned from the service. I've added the header Content-Length: (size) but I still get an error. Does anyone have suguestions? Here's the code for a put request:
def builder = new JsonBuilder()
// required json data
def root = builder {
"ActivationDate" "\\/Date(1434563608000-0500)\\/"
"EmailAddress" "ebaa#gmail.com"
"ExpirationDate" "\\/Date(1435686808000-0500)\\/"
"FirstName" "ebaa"
"LastName" "ebaa"
"MiddleName" "ebaa"
"OtherName" "ebaa"
"Password" "abc12345"
"Status" 1
}
RESTClient restClient = new RESTClient('https://serviceBaseUrl')
Response response
try {
restClient.authorization = new HTTPBasicAuthorization(username: 'user', password: 'pass')
restClient.defaultCharset = 'UTF-8'
restClient.defaultContentTypeHeader = 'application/json'
restClient.defaultAcceptHeader = 'application/json'
response = restClient.put(path: "/Location/${locName}/Administrator/${name}",
headers:['Accept': 'application/json',
'Accept-Language':'en-US,en;q=0.5', 'Content-Type': 'application/json; charset=UTF-8',
'Connection':'keep-alive', 'Pragma':'no-cache', 'Cache-Control':'no-cache',
'Content-Length': builder.toString().length()],
data: builder.toPrettyString().getBytes())
return response.json
} catch(ex) {
ex.printStackTrace()
}
I've also tried changing the data: param to body, but I get the same response. Also, If I use the Firefox plugin, HttpRequester (https://addons.mozilla.org/En-us/firefox/addon/httprequester/) and make the same request, I get a 200 status code and the appropriate data is updated. Thanks!
For put or post it is expecting the payload to be in a closure. Try the following, this should send the data and automatically set the right Content-Length:
....
....
response = restClient.put(
path: "/Location/${locName}/Administrator/${name}",
headers:['Accept': 'application/json',
'Accept-Language':'en-US,en;q=0.5',
'Content-Type': 'application/json; charset=UTF-8',
'Connection':'keep-alive',
'Pragma':'no-cache',
'Cache-Control':'no-cache'])
{
text builder.toPrettyString()
//bytes builder.toPrettyString().bytes // or as bytes
//json 'ActivationDate': '...', 'EmailAddress': '...' // or a json string from a map
}
See the Sending Content section of the README.

How to send a boolean to python-eve?

I'm trying to update a boolean value using python eve, but I always receive the same error,
_issues: {deleted:must be of boolean type}
deleted: "must be of boolean type"
_status: "ERR"
I've tried sending the field as true (setting javascript type) 'True' and 'true' (as text) and 1, but the error is always the same.
startdate=2014-03-25T03%3A00%3A00.000Z&code=dsa&enddate=2014-03-31T03%3A00%3A00.000Z&name=sad&note=&deleted=True
startdate=2014-03-25T03%3A00%3A00.000Z&code=dsa&enddate=2014-03-31T03%3A00%3A00.000Z&name=sad&note=&deleted=true
startdate=2014-03-25T03%3A00%3A00.000Z&code=dsa&enddate=2014-03-31T03%3A00%3A00.000Z&name=sad&note=&deleted=1
Any idea?
Regards
Gaston
settings.py
entity= {
'resource_methods': ['GET', 'POST'],
'schema': schema,
'datasource': {
'filter': {'$or':[{'deleted':{'$exists':0}},{'deleted':False}]}
}
}
schema = {
'name': {
'type': 'string',
'minlength': 1,
'maxlength': 50,
'required': True,
},
'code': {
'type': 'string',
},
'deleted':{
'type':'boolean',
'default':False
}
}
Full Request
Request URL:http://localhost:5000/campaign/532f797da54d75faabdb25d5
Request Method:PUT
Status Code:200 OK
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,no;q=0.6,es;q=0.4
Cache-Control:no-cache
Connection:keep-alive
Content-Length:112
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Host:localhost:5000
If-Match:3c7bc93e3c7d60da62f350ac990c16e29b08660f
Origin:http://localhost:5000
Pragma:no-cache
Referer:http://localhost:5000/static/index.html
X-Requested-With:XMLHttpRequest
Form Dataview parsed
startdate=2014-03-25T03%3A00%3A00.000Z&code=dsa&enddate=2014-03-31T03%3A00%3A00.000Z&name=sad&note=&deleted=True
Response Headersview source
Access-Control-Allow-Headers:
Access-Control-Allow-Max-Age:21600
Access-Control-Allow-Methods:HEAD, GET, PUT, POST, DELETE, OPTIONS, PATCH
Access-Control-Allow-Origin:*
Content-Length:69
Content-Type:application/json
Date:Mon, 24 Mar 2014 00:30:10 GMT
Server:Werkzeug/0.9.4 Python/2.7.5
Set-Cookie:session=eyJfcGVybWFuZW50Ijp0cn
If you change your schema to coerce deleted value to bool, you can send int or str values and have it converted to bool on insert/update
First, create a function to convert whatever comes, to bool:
to_bool = lambda v: v if type(v) is bool else str(v).lower() in ['true', '1']
Then, change the deleted in the schema to use the function to coerce values, like this:
'deleted':{
'type':'boolean',
'coerce': to_bool,
'default':False
}
With this, you can per example send deleted with values such as '0', 0, 'false' or 'False' yelding to boolean false, or '1', 1, 'true' or 'True' resulting in true
This happens only when you send the request in the content type of form-data or application/x-www-form-urlencoded. In case of AJAX requests, sending boolean value works.
var payload = {
"deleted": false
};
var xhr = $.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(payload),
dataType: "json",
url: "some url"
})
Your payload should be a dict like:
payload = {"somebool": False}
then you convert it to a json string:
payload_json = json.dumps(payload)
which results in a lowercased bool value in a string:
'{"f5only": false}'
then you shoulc be able to post or patch it:
requests.post("{0}/endpoint/".format(api_server), headers=headers, data=payload_json)

Error trying to access Paypal API from Parse.com Cloud Code

I'm trying to call Paypay from Parse.com Cloud Code.
I'm getting the following error on Firebug:
{"code":141,"error":"Uncaught Error: Can't form encode an Object"}
I'm using the example straight out of the Paypal example code. My cURL snippet works fine. When I try it with Parse Cloud Code, I get the above error. Here's my Parse Cloud Code:
Parse.Cloud.httpRequest({
url: 'https://svcs.sandbox.paypal.com/AdaptiveAccounts/CreateAccount',
method: 'POST',
headers: { "X-PAYPAL-SECURITY-USERID": "XXXXXXXXX",
"X-PAYPAL-SECURITY-PASSWORD": "XXXXXXXX",
"X-PAYPAL-SECURITY-SIGNATURE": "XXXXXXXXXXXXX",
"X-PAYPAL-REQUEST-DATA-FORMAT": "JSON",
"X-PAYPAL-RESPONSE-DATA-FORMAT": "JSON",
"X-PAYPAL-APPLICATION-ID": "APP-NNNNNNNNNNN",
"X-PAYPAL-DEVICE-IPADDRESS": "<my_actual_IP_address>",
"X-PAYPAL-SANDBOX-EMAIL-ADDRESS": "XXXXXXXXXXXXXX"
},
body: { "sandboxEmailAddress":"xyz#me.com",
"accountType":"PERSONAL",
"name": {"firstName":"Lenny","lastName":"Riceman"},
"address":{"line1":"123 Main St", "city":"Austin", "state":"TX", "postalCode":"78759", "countryCode":"US"},
"citizenshipCountryCode":"US",
"contactPhoneNumber":"512-555-5555",
"dateOfBirth":"1968-01-01Z",
"createAccountWebOptions": {"returnUrl":"http://www.example.com/success.html"},
"currencyCode":"USD",
"emailAddress":"lr12345#example.com",
"preferredLanguageCode":"en_US",
"registrationType":"Web",
"requestEnvelope": {"errorLanguage":"en_US"}
},
success: function() {
response.success("Paypal made!");
},
error: function(err) {
response.error(err);
console.error('Request failed with response code ' );
}
Update: May 9, 2014
OK. I don't know if this will help, but here is the exact code that is working for me.
Parse.Cloud.httpRequest({
method: 'POST',
url: 'https://api-3t.paypal.com/nvp -d',
body: {
USER: 'sr1.me.com',
PWD: 'LEgfdgfsdg8',
SIGNATURE: 'gfdgh',
METHOD: 'MassPay',
VERSION: '93',
RECEIVERTYPE: 'EmailAddress',
CURRENCYCODE: 'USD',
EMAILSUBJECT: 'You have a new payment from ',
L_EMAIL0: sellerEmail,
L_AMT0: paypalPmt,
L_NOTE0: paypalNote,
L_UNIQUEID0: bumpSoldTrans
}
Parse.Cloud.define("getUserPayPalToken", function(request, response){
//Setup private varaibles for paypal request to user
var receivers = new Array();
//Setup Receivers for Paypal when payment begins
//Primary Receiver --- Created first array for primary receiver
receivers[0] = new Array();
receivers[0][0] = {'amount':'1.00', 'email':'email-test-1#gmail.com'};
//receivers[0][0] = {'email':request.params.email};
//Secondary Receiver --- Created second array for secondary receiver
receivers[1] = new Array();
receivers[1][0] = {'amount':'2.00', 'email':'test-email#gmail.com'};
var receiverListParams = [{'receiver': receiverParams}];
var receiverParams = JSON.stringify(receiverListParams);
//Set Parse to call PayPal Adaptive Payments
Parse.Cloud.httpRequest({
method:'POST',
url: 'https://svcs.sandbox.paypal.com/AdaptivePayments/Pay',
headers: {
//Setting PayPal request headers
'X-PAYPAL-SECURITY-USERID' : 'xxxxx',
'X-PAYPAL-SECURITY-PASSWORD' : 'xxxxx',
'X-PAYPAL-SECURITY-SIGNATURE' : 'xxxxx',
// Global Sandbox Application ID
'X-PAYPAL-APPLICATION-ID ' : 'APP-80W284485P519543T',
// Input and output formats
'X-PAYPAL-REQUEST-DATA-FORMAT' : 'JSON',
'X-PAYPAL-RESPONSE-DATA-FORMAT' : 'JSON'
},
body:{
'actionType' : 'PAY',
'cancelUrl' : 'http://www.cancel.com',
'currencyCode' : 'USD',
'returnUrl' : 'http://www.return.com',
'requestEnvelope' : {"errorLanguage":"en_US"},
'receiverList' : receiverParams
},
success: function(httpResponse) {
console.log(httpResponse.text);
response.success(httpResponse.text);
},
error: function(httpResponse) {
console.error('Request failed with response code ' + httpResponse.status);
response.error(httpResponse.text);
}
});
});

Posting (by streaming?) with mikeal request

I'm trying to post a photo using mikeal request library, but the post comes emp
request = require('request')
fs = require("fs")
fs.createReadStream('zebra.jpg').pipe(request.post('http://localhost:2000'))
(on localhost:2000 I've got a simple echo for now)
Now, this works but I want to pass additional parameters using standard POST format.
What I'm actually trying to do is to post an image to Facebook via API, which means I'd like to include a title and possibly some more fields.
If streaming is not the right approach (although I see many benefits such as getting away without temporary files and buffers), what would be the right one?
Thanks for ideas.
UPD:
I've got this far:
fs.createReadStream('zebra.jpg').pipe(graph.post('418533674856800/photos',
{message:"I'm a new API photo!", name:"API Photo",privacy:{value:"EVERYONE"}},
function(err, res) {
console.log(res);
}));
but it returns
dest.on('drain', ondrain);
^
TypeError: Object #<Graph> has no method 'on'
at [object Object].pipe (stream.js:52:8)
at Request._callback (c:\My Stuff\Creatiff\PRAGmatiki\Web-node.js\postaspage.js:66:36)
at Request.callback (c:\My Stuff\Creatiff\PRAGmatiki\Web-node.js\node_modules\request\main.js:119:22)
at Request.<anonymous> (native)
at Request.emit (events.js:70:17)
at Request.<anonymous> (c:\My Stuff\Creatiff\PRAGmatiki\Web-node.js\node_modules\request\main.js:521:16)
at Request.emit (events.js:67:17)
at IncomingMessage.<anonymous> (c:\My Stuff\Creatiff\PRAGmatiki\Web-node.js\node_modules\request\main.js:483:14)
at IncomingMessage.emit (events.js:88:20)
at HTTPParser.parserOnMessageComplete [as onMessageComplete] (http.js:130:23)
Is this happening because I'm streaming? Any help please!
var path = require('path'),
mime = require('mime');
request({
url: 'http://localhost:2000',
headers: {
'content-type' : 'multipart/form-data'
},
method: 'POST',
multipart: [{
'Content-Disposition' : 'form-data; name="inputname"; filename="' + path.basename('zebra.jpg') + '"',
'Content-Type' : mime.lookup('zebra.jpg'),
body: fs.readFileSync('zebra.jpg')
},{
'Content-Disposition' : 'form-data; name="input[array]"; filename="' + path.basename('zebra1.jpg') + '"',
'Content-Type' : mime.lookup('zebra1.jpg'),
body: fs.readFileSync('zebra1.jpg')
},{
'Content-Disposition' : 'form-data; name="input[array]"; filename="' + path.basename('zebra2.jpg') + '"',
'Content-Type' : mime.lookup('zebra2.jpg'),
body: fs.readFileSync('zebra2.jpg')
},{
'Content-Disposition' : 'form-data; name="text"',
body: "text input"
}]
},
function(err, res, body){
});
I don't know what graph is (doesn't appear in mikeael's documentation), but it doesn't implement the Stream interface so can't be used with pipe().
To send multiple parts in a POST you need to use a request of type multipart/form-data. The latest version of mikeal/request has experimental support for this (with examples). Other modules also support it (needle for example, though stream support was a little lacking last time I looked).

Google Docs API: cannot set document title

I am trying to upload a file using Node and Google Docs REST API. I can upload the file just fine if I don't include the metadata, but it will always be uploaded as 'Untitled'.
But when I include the meta data I get the following error after sending my atom data and attempting to continue with the file upload:
ParseException - Content is not allowed in prolog
This is my first request to create an upload session and get a resumable-media-link
var meta = '<?xml version="1.0" encoding="UTF-8"?>'
meta+= '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007">'
meta+= '<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/docs/2007#document"/>'
meta+= '<title>Test</title></entry>'
var options = {
host: 'docs.google.com',
path: '/feeds/upload/create-session/default/private/full',
method: 'POST',
headers: {
'Host' : 'docs.google.com',
'Content-Length' : meta.length,
'Content-Type': 'application/atom+xml',
'GData-Version' : 3,
'Authorization' : 'GoogleLogin auth=' + authToken,
'X-Upload-Content-Type' : 'application/msword',
'X-Upload-Content-Length' : 31232
}
}
var req = https.request(options, function (res) {
// make 2nd request
});
req.end(meta);
This is what my 2nd request looks like after getting the resumable-media-link
var options = {
host: 'docs.google.com',
path: resumableMediaLink,
method: 'PUT',
headers: {
'Content-Length': data.length,
'Content-Type': 'application/msword',
'Content-Range': 'bytes 0-' + (data.length-1) +'/'+ data.length
}
}
var req = https.request(options, function (res) {
res.on('data', function (chunk) {
// ...
});
});
req.write(data);
req.end();
It seems like I am sending the atom data incorrectly. Any ideas of what I could be doing wrong?
I figured out what I was doing wrong.
I needed to set the 'Slug' header in the first POST request to initiate a resumable session.
I had it in the following request.