Error in JSON.parse() (when called from API Gateway) - arrays

I'm working on AWS lambda + API Gateway, and I need to pass an array of numbers in the url (GET method) for a REST call. It seems a good way is to pass the numbers as string (comma separated) and then use JSON.parse for the conversion to an array of numbers.
Following is the AWS lambda code I'm using;
exports.handler = (event, context, callback) => {
var arr = JSON.parse('[' + event.numbers + ']');
console.log("array: " + arr);
// TODO implement
callback(null, 'Hello from Lambda');
};
I'm testing this function in AWS Lambda using this Input test event;
{
"numbers": "1,5"
}
And everything works as expected; no errors.
However, when I test it via API Gateway, and passing the numbers as string in the query, I get following error (observed via CloudWatch);
*19:19:02
START RequestId: eabab882-8cee-11e7-8e2f-79d3086e061f Version: $LATEST
19:19:02
2017-08-29T19:19:02.688Z eabab882-8cee-11e7-8e2f-79d3086e061f SyntaxError: Unexpected token u in JSON at position 1 at Object.parse (native) at exports.handler (/var/task/index.js:4:20)
19:19:02
END RequestId: eabab882-8cee-11e7-8e2f-79d3086e061f
19:19:02
REPORT RequestId: eabab882-8cee-11e7-8e2f-79d3086e061f Duration: 215.25 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 18 MB
19:19:02
RequestId: eabab882-8cee-11e7-8e2f-79d3086e061f Process exited before completing request*
This is the request passed to lambda as shown in the log;
"body-json" : {},
"params" : {
"path" : {
}
,"querystring" : {
"numbers" : "1,6"
}
,"header" : {
}
},
"stage-variables" : {
},
I can't figure out what the problem is, since I'm passing same string in both cases.
I would appreciate any help.
Thanks
Gus

With this input json informed, you need to get it like this:
var arr = JSON.parse('[' + event.params.querystring.numbers + ']');
rather than:
var arr = JSON.parse('[' + event.numbers + ']');
Or make a body mapping template to stay the way you want:
{ "number": "$input.params('number')" }
http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
I hope I have helped!

Related

How to extract data from an API and create an array to send to the another API in Jmeter?

Example:
API A:
{
"customer":[
{
"name":"Jane",
"phone":"9999999",
"email":"jane#test.com"
},
{
"name":"John",
"phone":"8888888",
"email":"john#test.com"
},
{
"name":"Joe",
"phone":"7777777",
"email":"Joe#test.com"
}
]
}
Using the JSON extractor, I want to get the names of all the customers
so: Jane, John, Joe
How do I get these values and turn them into an array
[{"name":"Jane", "name":"John", "name":"Joe"}]
And pass it onto the next API?
Note: That it has to be dynamic so API A could show different 2 names or 1 name or more and needs to be adjusted into the array
First of all your [{"name":"Jane", "name":"John", "name":"Joe"}] is not a valid JSON, you can check it yourself:
so I strongly doubt that this is the string you need to generate.
So if you really need to construct this value you can do something like:
Add JSR223 PostProcessor as a child of the request which returns this "customers" data
Put the following code into "Script" area:
def response = new groovy.json.JsonSlurper().parse(prev.getResponseData())
def payload = new StringBuilder()
payload.append('[{')
0.upto(response.customer.size - 1, { index ->
payload.append('"name": "').append(response.customer[index].name).append('"')
if (index != response.customer.size - 1) {
payload.append(',')
}
})
payload.append('}]')
vars.put('payload', payload as String)
Refer the generated value as ${payload} where required
Demo:
More information:
JsonSlurper
Apache Groovy - Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

how to pass date in $http.get request

i have list of task in my database. i want to filter by date(completed date)
how to pass date with $http get request.i tried some code.it is giving exception.
can any one help me.
angular:
$scope.date=1468175400000;
var deadline = new Date($scope.date);
$http.get(
'/user/task/gettasks/?status=' + $scope.status
+ '&priority=' + $scope.priority
+ '&projectId=' + $scope.project+'&deadline='+deadline).success(
function(response) {
debugger
$scope.tasks = response;
}).error(function(error) {
console.log(error)
})
service(spring):
#RequestMapping("/gettasks")
#JsonView({ TaskJsonView.Summary.class })
public List<Task> getTasks(#RequestParam(value="status" ) String status,
#RequestParam("priority") String priority,
#RequestParam("projectId") String projectId,#RequestParam("deadline") Long deadline) {
System.out.println(deadline);
return taskControllerService.getTasks(status, priority, projectId,deadline);
}
error:
Object {
timestamp: 1468819101831,
status: 400,
error: "Bad Request",
exception: "org.springframework.web.method.annotation.MethodArgumentTypeMismatchException",
message: "Failed to convert value of type [java.lang.String]… "
MonJul11201600: 00: 00 GMT0530(IndiaStandardTime)
""…
}
error: "Bad Request"
exception: "org.springframework.web.method.annotation.MethodArgumentTypeMismatchException"
message: "Failed to convert value of type [java.lang.String] to required type [java.lang.Long]; nested exception is java.lang.NumberFormatException: For input string: "
MonJul11201600: 00: 00 GMT0530(IndiaStandardTime)
""
path: "/user/task/gettasks/"
status: 400 timestamp: 1468819101831 proto: Object
For deadline you are passing a date object.
Pass this instead new Date($scope.date).getTime() this will send the deadline as long timestamp.
var deadline = new Date($scope.date).getTime();
From the exception i can see the deadline date is not parsed correctly. From UI you are sending Date object and at server side you are accepting as Long value. Please make sure you keep the data type same at both end.
If the date is epochtime format then first convert like this and attach it to request.
var time = new Date(0);
var deadLineDate = deadLineDate / 1000;
time.setUTCSeconds(deadLineDate);
requestObject = time.toISOString().slice(0, 10);
Now requestObject is string, please accept as String # server side.
Let me know if it helps.

how to access this complex json object with angular js?

$scope.data = {
"statusCode": 200,
"message": "success",
"result": {
"data2": [
{
"viewTitle": "one",
"viewType": 1,
"viewData": "{\"data3\":{\"_id\":\"one\"," +
"\"channelId\":\"0\",\"channelName\":\"animals\"," +
"\"rate\":3.5,\"visited\":21,\"meta\":{\"currency\":\"t\"" +
",\"size\":\"5 mb\",\"updatedAt\":\"2 2 2016\"" +
",\"createdAt\":\"2 2 2016\",\"duration\":\"3 minutes \"}" +
",\"thumbnail\":\"127.0.0.1\"" +
",\"banner\":\"127.0.0.1\"" +
",\"trailerUrl\":\"\",\"url\":\"127.0.0.1\"" +
",\"desc\":\"my informations \"" +
",\"title\":\"my videos number 4\",\"packages\"" +
":[{\"_id\":\"1\",\"price\":500" +
",\"type\":\"purchase\"}],\"packageId\":\"2\"" +
",\"packagePrice\":500,\"userFavorite\":0,\"userRate\":0,\"locked\":1}}"
}
]
}
};`
I try to access for example chanelName or size please help to resolve.
first, turn the JSON string into an object via JSON.parse();
var data = JSON.parse();
//data is now the result of JSON.parse
and then access the property you want to use in $scope.data
I have created a CodePen for your Problem:
http://codepen.io/JohannesFerner/pen/PNmmBd/
You have JSON.parse(<escaped JSON property>) or angular.fromJson(<escaped JSON property>) (see the comment above) your escaped JSON.
Without further knowledge of your backend I would suggest that you do not deliver escaped JSON to the client.
First level objects can be accessed like this.
person.result.data2[0].viewTitle
JSON.parse is the easiest way here to disassemble the complex object. I have given my example below
http://jsfiddle.net/MisterFantastic/u8bhc1ds/1/
JSON.parse(person.result.data2[0].viewData)
For complex objects please refer this link.
AngularJS format JSON string output

How to send an array using QWebSocket?

I created a client-server system including:
a node.js server (with module ws);
a WebClient;
a QtClient (using Qt5.4 and QWebSocket).
The QtClient sends and receives strings via the method QWebSocket.sendTextMessage (QString s). How can I send an array of strings?
OTHER INFO:
The WebClient sends an array using JSON:
# index.html (WebClient)
socket.onopen = function() {
var array = {
value1: "WebClient value1 = v1",
value2: "WebClient value2 = v2"
};
socket.send(JSON.stringify(array), {binary: true, mask: false});
};
# server.js
socket.on('connection', function(ws) {
ws.on('message', function(message) {
var array = JSON.parse(message);
console.log(array["value1"]);
console.log( array["value2"]);
});
});
# console node
C:\Users\PietroP\Desktop\cs\v0.3>node server.js
Server connect on http://192.168.1.60:3000/
a user connected
WebClient value1 : v1
WebClient value2 : v2
QWebSocket class does not have direct implementation for sending arrays. You can send binary or text messages. For details please refer to:
http://doc.qt.io/qt-5/qwebsocket.html
Here is an alternative approach:
You can convert your array into a long string using something like
str = array.toString() // This is psuedo code
in a loop and send from the sender side. Then on the receiver side you can get parse it using a method such as
str.split(...);
Hope that heps!
Edit: You've probably already noticed that: in your sample code what JSON.stringify(array) and JSON.parse(message) do is nothing but converting array to string and then parse the string into array again.

Collect errors with Gatling?

In my long, but simple awesome Gatling simulation, I have few responses that ended with error 500. Is it possible to tell gatling to collect these error responses messages in a file during the simulation?
No in production mode. You only have them when debug logging is enabled.
It is possible to collect what ever you want and save it into simulation.log file. Use extraInfoExtractor method when you define protocol:
val httpProtocol = http
.baseURL(url)
.check(status.is(successStatus))
.extraInfoExtractor { extraInfo => List(getExtraInfo(extraInfo)) }
Then define in your getExtraInfo(extraInfo: ExtraInfo) method whatever criteria you want. Example bellow outputs request and response in case of debug is enables via Java System Property OR response code is not 200 OR status of request is KO (it can be KO if you have setup some max time and this max time gets increased)
private val successStatus: Int = 200
private val isDebug = System.getProperty("debug").toBoolean
private def getExtraInfo(extraInfo: ExtraInfo): String = {
if (isDebug
|| extraInfo.response.statusCode.get != successStatus
|| extraInfo.status.eq(Status.valueOf("KO"))) {
",URL:" + extraInfo.request.getUrl +
" Request: " + extraInfo.request.getStringData +
" Response: " + extraInfo.response.body.string
} else {
""
}
}

Resources