Parse string into JSON - velocity

I have an array of objects $arr and an object has a property named as jsonData which contains json data in a string, how to parse that string to actual JSON object and retrieve lets say value for key name? I tried this:
#foreach ($obj in $arr)
#set ($jsonData = "#evaluate(${obj.jsonData})")
$jsonData.get("name") ## <-- not working
#end

If anyone using velocity in AWS API Gateway ends up here, you can use AWS'
$util.parseJson() to covert a string to JSON.
Make sure you note if your string is using single or double quotes. You may need to use $util.escapeJavaScipt.replaceAll() before parsing the string.

Fixed it like this:
#foreach ($obj in $arr)
#set( $jsonData = '#set( $jsonData = ' + $obj.jsonData + ' )' )
#evaluate ($jsonData)
$jsonData.get("name") ##<-- works now
#end
I was using velocity 1.7

This is mainly AWS lambda (in python) response template related.. so.. if you want to return custom response code with json it is easy to return JSON in node js but when it comes to python as per i know, we cant raise dict as a value. So.. this may help. If you are doing like..
raise Exception({"responseCode": 400, "response": "missing :\"recipientCount\""})
It will throw exception in errorMessage key and value as a string.
To overcome this..
Add response code 400 in Method Response
regExp in Integration Response :
.*'responseCode': 400.*
Add Body Mapping Template as application/json:
$util.escapeJavaScript( $input.path('$.errorMessage')).replaceAll("\\'",'\"')
Make sure you are not using single quotes in value in exception string.
Wrong:
raise Exception({"responseCode": 400, "response": "missing :'recipientCount'"})
Right:
raise Exception({"responseCode": 400, "response": "missing :\"recipientCount\""})
I know it is not best solution... but this is the only solution i have found. Feel free if you have better solution.

Related

How to set array property value in code using Carina Test Framework for API tests?

I have the following request json body:
{
...
"attachmentIds": "${attachments}"
...
}
I have a properties file that includes the declaration of the corresponding placeholder
I want to set array of strings in code instead of "attachments" placeholder, but getProperties().setProperty() expects only string value.
How can I achieve it other way or is it possible at all?
Thanks!
As an option you can transform your array into the String in java code. And then pass this String as property value.
Another option, you can pass String array from code and then parse it in your json template.
For example:
String[] arr = { "1", "2", "3" };
apiMethod.addProperty("attachments", arr);
And then in your json:
{
"attachmentIds": [<#list attachments as val>"${val}"<#if val?has_next>,</#if></#list>]
}
Check freemarker documentation to get more details:
https://freemarker.apache.org/docs/ref_builtins_loop_var.html
Also please note that some of freemarker functions (including has_next) are available only in newest versions of library. So make sure to add into your dependencies list. Carina is now in process of migrating to latest freemarker version.

vTiger webservice update operation

im trying to do an update operation from angular 2 but i dont know how to pass the element parameter
in the vtigercrm.log i see DEBUG webservice -
array ('element' => NULL)
which leads to this
"error": {
"code": "ACCESS_DENIED",
"message": "Permission to perform the operation is denied for id",
i tryied passing the following object as a JSON
{
"subject":"test2",
"assigned_user_id":"19x1",
"date_start":"2016-11-15",
"time_start":"12:00:00",
"due_date":"2016-11-15",
"time_end":"14:00:00",
"recurringtype":"",
"duration_hours":"2",
"duration_minutes":"0",
"parent_id":"",
"eventstatus":"Planned",
"sendnotification":"0",
"activitytype":"Call",
"location":"",
"createdtime":"2016-11-15 11:31:19",
"modifiedtime":"2016-11-15 11:31:19",
"taskpriority":"",
"notime":"0",
"visibility":"Public",
"modifiedby":"19x1",
"description":"",
"reminder_time":"",
"contact_id":"",
"latitud":"",
"longitud":"",
"id":"18x22029"
}
the same thing as encodeURI and encodeURIComponent but nothing works
I had a similar error, and I found a subtle difference in the JSON. When a result was returned, the json object is the first element in an array. But for sending, it needs to be just the object, not an array.
<?php
//decode the json encode response from the server.
$jsonResponse = json_decode( $response->getBody(), true );
//Get first array element for sending back with update
$objectJson = json_encode($jsonResponse[ 'result' ][0]);
?>
Whenever I tried sending the original response, I received an error: {"success":false,"error":{"code":"ACCESS_DENIED","message":"Permission to perform the operation is denied for id"}}
This error message can be due to:
Object ID not mentionned/correct in the JSON objet that you send as the parameter "element"
Vtiger Session ID not sent/correct in the parameter "sessionName"
See here an example (in PHP) of how to pass the object to perform an update

JSON result problems in ASP.NET Web API when returning value types?

I'm learning aspnet mvc 4 web api, and find it very easy to implement by simply returning the object in the apicontrollers.
However, when I try to return value types such as bool, int, string - it does not return in JSON format at all. (in Fiddler it showed 'true/false' result in raw and webview but no content in JSON at all.
Anyone can help me on this?
Thanks.
Some sample code for the TestApiController:
public bool IsAuthenticated(string username)
{
return false;
}
Some sample code for the jQuery usage:
function isAuthenticated(string username){
$.getJSON(OEliteAPIs.ApiUrl + "/api/membership/isauthenticated?username="+username,
function (data) {
alert(data);
if (data)
return true;
else
return false;
});
}
NOTE: the jquery above returns nothing because EMPTY content was returned - however if you check it in fiddler you can actually see "false" being returned in the webview.
cheers.
Before your callback function is called, the return data is passed to the jquery parseJSON method, which expects the data to be in the JSON format. jQuery will ignore the response data and return null if the response is not formatted correctly. You have two options, wrap you return boolean in a class or anonymous type so that web api will return a JSON object:
return new { isAuthentication = result }
or don't use getJSON from jQuery since you're not returning a properly formatted JSON response. Maybe just use $.get instead.
Below is a quote for the jQuery documentation:
Important: As of jQuery 1.4, if the JSON file contains a syntax error,
the request will usually fail silently. Avoid frequent hand-editing of
JSON data for this reason. JSON is a data-interchange format with
syntax rules that are stricter than those of JavaScript's object
literal notation. For example, all strings represented in JSON,
whether they are properties or values, must be enclosed in
double-quotes. For details on the JSON format, see http://json.org/.

An interesting Restlet Attribute behavior

Using Restlet 2.1 for Java EE, I am discovering an interesting problem with its ability to handle attributes.
Suppose you have code like the following:
cmp.getDefaultHost().attach("/testpath/{attr}",SomeServerResource.class);
and on your browser you provide the following URL:
http://localhost:8100/testpath/command
then, of course, the attr attribute gets set to "command".
Unfortunately, suppose you want the attribute to be something like command/test, as in the following URL:
http://localhost:8100/testpath/command/test
or if you want to dynamically add things with different levels, like:
http://localhost:800/testpath/command/test/subsystems/network/security
in both cases the attr attribute is still set to "command"!
Is there some way in a restlet application to make an attribute that can retain the "slash", so that one can, for example, make the attr attribute be set to "command/test"? I would like to be able to just grab everything after testpath and have the entire string be the attribute.
Is this possible? Someone please advise.
For the same case I usually change the type of the variable :
Route route = cmp.getDefaultHost().attach("/testpath/{attr}",SomeServerResource.class);
route.getTemplate().getVariables().get("attr") = new Variable(Variable.TYPE_URI_PATH);
You can do this by using url encoding.
I made the following attachment in my router:
router.attach("/test/{cmd}", TestResource.class);
My test resource class looks like this, with a little help from Apache Commons Codec URLCodec
#Override
protected Representation get() {
try {
String raw = ResourceWrapper.get(this, "cmd");
String decoded = new String(URLCodec.decodeUrl(raw.getBytes()));
return ResourceWrapper.wrap(raw + " " + decoded);
} catch(Exception e) { throw new RuntimeException(e); }
}
Note my resource wrapper class is simply utility methods. The get returns the string of the url param, and the wrap returns a StringRepresentation.
Now if I do something like this:
http://127.0.0.1/test/haha/awesome
I get a 404.
Instead, I do this:
http://127.0.0.1/test/haha%2fawesome
I have URLEncoded the folder path. This results in my browser saying:
haha%2fawesome haha/awesome
The first is the raw string, the second is the result. I don't know if this is suitable for your needs as it's a simplistic example, but as long as you URLEncode your attribute, you can decode it on the other end.

Linqpad - Outputting into anchor to use title

I have a db that stores exception messages.
I would like to create a query that gets these exceptions but instead of dumping huge amounts of text i would prefer it to be "on demand".
I figured putting the exception into an anchor tag like so and then reading the message when needed by mousing over it would work... apparently not.
var logsForErrors = (from error in Logs
select new {
error = LINQPad.Util.RawHtml("<a title='"+ error.Exception+"'></a>"),
errorDate = error.Date,
errorMessage = error.Message
}).Take(10);
logsForErrors.Dump();
This is throwing an exception (lol) - "Cannot parse custom HTML: "
Encoding the exception message
...RawHtml("<a title='"+ Uri.EscapeDataString(error.Exception)+"'></a>")
Message Could not translate expression 'RawHtml((("h__TransparentIdentifier0.error.Exception)) +
"'>"))' into SQL and could not treat it as a local expression.
will generate a new error
Any ideas? - I am open to alternative solutions to this also.
I just want a container for the message instead of it just dumping right into the output as it it so huge!.
Thanks,
Kohan
Have you tried using the "Results to DataGrids" mode in the recent betas? It might do just what you need without having to write anything else.
Edit: your error was probably due to emitting HTML without escaping the text. The easiest solution is to call Util.RawHtml with an XElement instead of a string. You could write an extension method that does what you want like this:
public static class Extensions
{
public static object Tooltipize (this string data)
{
if (string.IsNullOrEmpty (data) || data.Length < 20) return data;
return Util.RawHtml (new XElement ("span", new XAttribute ("title", data), data.Substring (0, 20)));
}
}
Put this into My Extensions and you can use it from any query.