In my play framework project I have a confirmed functional Java map of the form Java that is passed to a html page home.scala.html
The map variable is passed in as other (working) variables are, at the top of the page:
#(workingVar1: String, workingVar2: Int, mapVar: Map[Long, Integer])
But developer tools in google chrome highlights this part of the javascript (embedded in home.scala.html's head):
var myMap = #mapVar;
With the error Uncaught SyntaxError: Unexpected token =
So none of the javascript works. What is the correct way to pass this map in?
You can use Java/Scala variables in Twirl Scala templates and both are executed on the server side.
Now on server side Twirl engine translates Java object to something (which probably isn't what you want) and in this form is passed to client, and then this JavaScript is executed.
You want to make sure that client will receive valid JavaScript code.
To assign proper value, you will have to mix some JSON libraries, which will help you assign value in a proper way.
Eg. on the controller side:
...
Map<Long, Integer> map = new HashMap<>();
map.put(1L, 2);
map.put(3L, 3);
String yourMap = Json.stringify(Json.toJson(map));
Now you want to pass yourMap to view, and then you will assign to myMap
using #Html as we want it as raw content fragment:
#(workingVar1: String, workingVar2: Int, mapVar: String)
var myMap = #Html(mapVar);
Try and let me know if it helped.
An inelegant but functional solution is as follows:
Bring in the Java Map as a string:
var stringMap = "#mapVar";
Removes the braces and spaces inserted into the string unnecessarily
stringMap = stringMap.replace(/{/g,'');
stringMap = stringMap.replace(/}/g,'');
stringMap = stringMap.replace(/ /g,'');
Split the mapString by , and for every pair split again by =, extracting keys and values as you go. These will need to be parsed to their correct data-types before adding to a javascript array jsArr:
var pairArray = mapString.split(",");
pairArray.forEach(function(pair) {
var values = pair.split("=");
var longString = values[0];
var intString = values[1];
var myLong = parseFloat(longString);
var myInt = parseInt(intString);
jsArr.myLong = myInt;
}
Where jsArr has been defined previously.
Related
I have written a C++ module for my Node/Typescript/Javascript frontend and use JSON to pass data back and forth, e.g.
let response = myModule.addCommand("{\"cmd\":\"LoadFile\", \"path\":\"D:\\\\folder\\\\file.abc\"}");
However, I have trouble passing variables, as they are loosing the backslashes each time and so I am currently storing the path variable and use regex to add back the "lost" backslashes each time.
On the C++ side:
std::filysystem::path cppPath = doc["path"].GetString(); // using rapidjson::Document doc
// do stuff
std::string response ="{\"path\":\"" +
std::regex_replace(cppPath.string(), std::regex(R"(\\)"), R"(\\\\)") +
"\"}";
And on the JS/TS side:
// from cpp:
let response = myModule.addCommand(`{\"cmd\":\"LoadFile\", \"path\":\"D:\\\\folder\\\\file.abc\"}`);
let regex = /\\/g;
let usedPath = response.path.replace(regex, "\\\\");
let response = myModule.addCommand(`{\"cmd\":\"SaveFile\", \"path\":\"${usedPath}\"}`);
Is there a more elegant way to do this to pass the variable directly so that it can be used on the other "side"?
Thank you in advance.
i have an issue with my logged Json String as it replaces the double quotes with "
Controller Code :
var message = new SuccessMessagesVM()
{
Title = successMessageType == (int)EnumHelper.SuccessMessageTypes.Add ? "It's beautiful" : CustomModel.Resources.SuccessMessagesResources.EditFormSuccess,
Message = successMessageType == (int)EnumHelper.SuccessMessageTypes.Add ? CustomModel.Resources.SuccessMessagesResources.AddFormSuccess : CustomModel.Resources.SuccessMessagesResources.EditFormSuccess,
ColorCode = (int)EnumHelper.MessagesCodes.Success
};
var json = JsonConvert.SerializeObject(message);
ViewBag.SuccessMessage = successMessageType == 0 ? null : json;
Javascript just logs the ViewBag.SuccessMessage as following:
console.log('#ViewBag.SuccessMessage');
and the object is displayed as {"Message":"تم إضافة النموذج بنجاح","Title":"It's beautiful","ColorCode":3}
replacing all single quotes with ' and all double quotes with "
I expect the output to be {"Message":"تم إضافة النموذج بنجاح","Title":"It's beautiful","ColorCode":3}
This is because you are using ViewBag variable.
In order to use ViewBag, you can write it as followed:
First, in view:
#{
var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
var successMessageJson = jss.Serialize(ViewBag.SuccessMessage);
}
Then use it:
<script>
//use Json.parse to convert string to Json
var successMessageInfo = JSON.parse('#Html.Raw(successMessageJson)');
</script>
There's a few different issues and a few different approaches, and the OP doesn't give us any view code, so it's a bit of guesswork.
My feeling is that you should just return the SuccessMessagesVM from your method, and access the properties individually in your view (probably using #Html.DisplayFor and HTML). This will ensure that any redundant quotation marks are never created in the first place, and will give you total control over how the values are displayed.
You should not expect console.log(#ViewBag.Anything) to display properly. If you need the data as a JavaScript object, don't stick it in the ViewBag, as it will get rendered as HTML.
If you must write to a JavaScript object you can, but it begs the question why are you not using an ajax request if all you want is data?
I am using IBM BPM 8.6
I have an input string as follows:
"\"RECORD_CONTACT\":\"Maram\" , \"DRUG\":\"Panadol\"
In a script on server side, I want to dynamically create a business object like this:
tw.local.recordContact = Maram;
tw.local.drug = Panadol;
How can I dynamically create the business object?
There are a few problems with your request. The first is that you are not creating a business object, you are creating variables. In IBM BPM the variables have to be declared at design time or you will get an error, so invoking attempting to call something like -
tw.local.myVariable = 'Bob';
Will throw an exception if tw.local.myVariable has not been declared. Base on your other question you asked here (link), I'm going to assume you actually have an ANY variable declared called "return" so that
tw.local.return.myVariable = 'Bob'
will work. Given that I based on Sven's answer I think something like the following will work (you will need to validate)
var str = "\"RECORD_CONTACT\":\"Maram\" , \"DRUG\":\"Panadol\"";
var jsonStr = "{" + str.replace(/\\\"/g,'\"') + "}";
var tempValue = JSON.parse(jsonStr);
var keyArray = Object.keys(tempValue);
var valueArray = Object.values(tempValue);
for(var keyCount=0; keyCount<keyArray.length; keyCount++{
var evalString = "tw.local.return."+keyArray[keyCount]+"="+valueArray[keyCount];
eval(evalString);
}
I'll note that doing this is a very bad idea as it would be very brittle code and that using eval() in this manner opens you up to all sorts of possible exploits. It will also fail badly if the value for one of the keys is not a simple type.
-Andrew Paier
One should know what you are going to do with dynamically created Business Objects (BO) to answer you better. Like a very generic way would be - creating JSON object instead of BO.
But if you want to stick with BO then this is only possible when you know all the BO structure (schema) beforehand during design time.
var str = "\"RECORD_CONTACT\":\"Maram\" , \"DRUG\":\"Panadol\"";
vat objArray = str.split("reg ex to split each object string")
foreach (obj in objArray ){
if(obj.indexOf( "RECORD_CONTACT")!=-1)
tw.local.recordContact = new tw.object.RECORD_CONTACT();
//below goes code get value of each attribute of BPM from string
}
else if(obj.indexOf( "DRUG")!=-1){
//similar code to create BO DRUG
}
Don't forget to create BO before using those :)
I want to pass an entire object right into javascript, but it doesn't seem to work.
I tried the {{{data}}} approach and the {{data}} approach like recommended in another post.
I'm doing something like this in the handlebars file:
<script>
var myData = {{data}}; // or even {{{data}}}
</script>
Both of these give me the exception: Uncaught SyntaxError: Unexpected Identifier.
However if I do a
var myDataUrl = "{{data.url}}";
It works fine, but for the first case it prints out "[Object Object"]. Any thoughts on how I can make case 1 work?
To insert Javascript data directly into template, you need to make it into a legal javascript string and pass that string into the template. It needs to be legal Javscript before it gets to the template. Using something like JSON.stringify() is one such way to make legal Javascript, but it isn't the only way.
Here's a piece from a handlebars template of mine that inserts some javascript data structures into the HTML file:
<script>
// temperature data - array of arrays of the form [dateTime, atticTemp, outsideTemp]
var temperatureData = {{{temperatures}}};
// onOffData is an array of [dateTime, str] - where str is "on" or "off"
var onOffData = {{{onOffData}}};
</script>
And, the data passed to the template looks like this (the two method calls return JSON strings):
app.get('/chart', function(req, res) {
var tempData = {
temperatures: data.getTemperatureDataSmallJSON(),
onOffData: data.getFanOnOffDataSmallJSON(),
units: req.cookies.temperatureUnits
};
res.render('chart', tempData);
});
This results in a piece of an HTML file that looks like this:
<script>
// temperature data - array of arrays of the form [dateTime, atticTemp, outsideTemp]
var temperatureData = [[1412752013861,22.19,16.35],[1412753505591,22,16.15],[1412754286561,21.85,15.94]];
// onOffData is an array of [dateTime, str] - where str is "on" or "off"
var onOffData = [[1411786960889,"off"],[1411790853867,"off"]];
</script>
Note, I'm turning the data into JSON and passing that JSON string into the template.
In JScript, why do I get the error "Object doesn't support this property or method" when I try to convert request.querystring to a string using toString()?
var params = Request.QueryString;
var params = params.toString();
Background info:
I'm trying to convert the querystring to a string so that I can perform a regex replace and remove certain items when they appear in the url.
var param = param.replace(/([?&])(allow)=[\w-]+/g, "");
I recently discovered the solution to this problem.
var params = Request.QueryString;
should be:
var params = Request.QueryString.Item;
There is no need to convert params to a string after that to manipulate the query string. Further you have access to everything in the query string by calling Request.QueryString("param").Item.
Example:
http://www.mysite.com?q=query&name=george
var name = Request.QueryString("name").Item;
I don't know -- weird Microsoft JScript implementation.
I had the same problem.
var strParams = new String(params);
seems to work though.