I really need a hand here. In the last 2 or 3 hours I tried to simply list a JSON object in freemarker with a javascript backed webscript and no luck.
let's name my script as x, so:
x.get.js
function main(){
//model.data = {'name':'Test Object','size':100};
model.data={
"2012": {
"A": {
"a": "on",
"b": "off",
"list": [
1,
2,
3,
4
]
}
},
"2013": {
"B": {
"c": "on",
"d": "off"
}
}
};
logger.log(jsonUtils.toJSONString(model.data));
}
main();
x.get.html.ftl
<#assign keys = data?keys>
<#list keys as tag>
${jsonUtils.encodeJSONString(tag)}<#if tag_has_next>,</#if>
</#list>
When I try just with the first model.data (commented out) it works fine, and the logger writes out the full JSON, i get the "name, size" in the rendered HTML.
However, when I try like this, I get nothing in the rendered HTML, and logger says weird things:
{"2012":"org.mozilla.javascript.UniqueTag#1a31e0a: NOT_FOUND","2013":"org.mozilla.javascript.UniqueTag#1a31e0a: NOT_FOUND"}
So what? This JSON is valid too, so I miss some conversation or misterious function or what?
Thanks for the help
J.
normally you should fill your model using nornmal objects/values in js and generate the json in your ftl template x.get.json.ftl
Related
I'm trying to set a data model inside my manifest.json within my webapp.
Im using sapui5 and I'm quite new to it.
the resource I'm getting from my api is a jsonObject but somehow the model is not initiated properly. I checked the model with console.log() and it's empty.
when I do the same with an jsonArray it is working.
I should mention that I use a mockserver.js
Here is the code I'm using.
manifest.json:
"sap.app": {
...
"dataSources": {
"invoiceRemote": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"localUri": "localService/metadata.xml"
}
}
}
}
...
"sap.ui5": {
...
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "MyInboxUI5.i18n.i18n"
}
},
"invoice": {
"dataSource": "invoiceRemote"
}
...
and with JsonObject I mean a .json of this style:
{
"field1": value1,
"field2": value2,
"field3": [
{
"field4": value4,
"field5": value5
},
{
"field6": value6,
"field7": value7
} ]
}
(that's the one not working)
and with JsonArray I meant
[
{
"field4": value4,
"field5": value5
},
{
"field6": value6,
"field7": value7
}
]
(This one is working)
To check my model I used the simple console.log()
Component.js (part of it)
init: function() {
console.log(this.getModel("invoice"));
UIComponent.prototype.init.apply(this, arguments);
this.getRouter().initialize();
}
I did not post the mockserver.js or metadata.xml because I'm not sure it's that relevant and they take a lot of space.
So does anyone know if there is a way to load the model of a JsonObject inside the manifest.json?
I'm aware that there are other possibilities to load the model that do work, but I'm only interestet in that specific case.
Without having additional information about what you actually try to achieve it's hard to point you into the right direction.
The important information is that you are using an ODataModel + a mockserver. Thanks to the mockserver you can easily mock your data for the entities of your OData service - actually you can even mock much more...
Basically, the mock data files need to contain flat lists. In other words, you have always an array of flat objects. The mockserver gets the data (i.e. entities by id) from exactly from these files. The mockserver can only find the files if they have the correct name (see walkthrough tutorial for details). As a rule of thumb "1 file contains data for one entity/entityset".
There is no way to model JsonObjects inside the manifest. What you can do is mocking your mockserver (i.e. by reading json files manually), that works perfectly (the explored app has some examples). However, don't forget we are talking about OData!
Hint: your data looks like a tree, so I guess you want to model a tree structure. If you check the explored app there are a few examples for OData Tree binding and there I'm using the mockserver as well. Maybe that helps...
Any ways on how we can convert VALID JSON STRING to actual JSON(sequence) in freemarker. I mean this string is actually returned by a JSON.stringify() call.
I follow what this post says but it seems this is not applicable to mine.
<#assign test = "(record.custpage_lineitems?json_string)">
<#assign m = test?eval>
<#list m as k>
${k.item}
</#list>
ERROR says
Expected collection or sequence. m evaluated instead to freemarker.template.SimpleScalar on line 286, column 32 in template.
Sample JSON String
{
"34952": {
"item": "TRAVEL",
"notes": "Travel Time To Client Site to Perform Repairs.1.0",
"type": "Service"
},
"34963": {
"item": "MECHANIC RECOMMENDATION",
"notes": "MECHANIC RECOMMENDATION\nr&r drive tires 21x7x15 smooth black \nr&r lp tank latch on bracket \nr&r lp hose cupler",
"type": "Service"
},
"9938": {
"item": "T1",
"notes": "Field Service Call Charge75$ labor 124$",
"type": "Service"
},
"34549": {
"item": "GENERAL SERVICE INFO",
"notes": "SERVICE NOTES:\ndrove to customer location found lift found to broken hydraulic hoses had to remove attachment in order to remove broken hoses then drove to get hoses made installed hoses back on lift re installed loose brackets I found out attachment back on lift topped off hydraulic resivoir and lift was ready",
"type": "Service"
},
"36264": {
"item": "FSO PARTS (UN CHECK IF NEEDED)",
"notes": "MARK CHECK IF PARTS NOT NEEDED.",
"type": "Service"
},
"36266": {
"item": "FSO QUOTE (UN CHECK IF NEEDED)",
"notes": "MARK CHECK IF QUOTE NOT NEEDED.",
"type": "Service"
},
"29680": {
"item": "0199992-HY32F",
"notes": "2 x 0199992-HY32F",
"type": "Inventory Item"
}
}
It seems that it is not converting to a valid sequence because if i'll try to print ${m} it displays the escaped json string.
I am looking for a way that I will just say <#assign test=toJSON(record.custpage_lineitems) but I think you have to write methods in java since I am doing this in 'netsuite'
UPDATE: I tried to hard code the json string like
<#assign m = '{"34952":{"item":"TRAVEL","notes":"Travel Time To Client Site to Perform Repairs.1.0","type":"Service"}....}'>
and try to loop through, it seems working. But if I substitute the value of m to myvariable seems not working. I am 100% sure myvariable is not null nor empty but contains the same JSON string.
My assessment is that, if I could just wrap the myvariable to single quote then I think it will solve the issue. I tried
<#assign m = 'myvariable'> and
<#assign m = '(myvariable)'> and
<#assign m = '(${myvariable})'> and
<#assign m = '(myvariable?string)'> etc.
but none is correct. Can someone just direct me into what is the proper syntax on how to wrap existing variable to single quote.
Any help guys? Thanks.
I think the \n inside the json string could cause some problems. Try replacing it first with (or something similar what will suit your needs)
record.custpage_lineitems?replace("\n", "\\n")
and then do the eval
If your record.custpage_lineitems is already a stringified JSON then you do not have to use ?json_string.
Replace your first two lines with this:
<#assign m = record.custpage_lineitems?eval>
See eval documentation for details.
Update:
Your custpage_lineitems is a hash map and #list accepts sequence. Try this:
<#list m?keys as k>
${m[k].item}
</#list>
I'm having trouble properly formatting one particular soap parameter using the node-soap module for node.js as a client, to a 3rd-party SOAP service.
The client.describe() for this method says this particular input should be in the shape of:
params: { 'param[]': {} }
I have tried a bunch of different JSON notations to try to fit my data to that shape.
Examples of formats that do NOT work:
"params": { "param": [ {"myParameterName": "myParameterValue"} ] }
"params": [ "param": { "name": "myParameterName", "_": "myParameterValue"} ]
"params": { "param" : [ {"name": "myParameterName", "_": "myParameterValue"} ] }
"params": { "param[]": {"myParameterName": "myParameterValue" } }
"params": { "param[myParameterName]": {"_": "myParameterValue" } }
I must be overlooking something, and I suspect I'm going to feel like Captain Obvious when some nice person points out what I'm doing wrong.
Here is what DOES work, using other soap clients, and how they handle the "named parameter with a value"
soapUI for this method successfully accepts this particular input via XML in the shape of:
<ns:params>
<ns:param name="myParameterName">myParameterValue</ns:param>
</ns:params>
Also, using PHP, I can successfully make the call by creating a stdClass of arrays like so:
$parms = new stdClass;
$parms->param = array(
array(
"name"=>"myParameterName","_"=>"myParameterValue"
)
);
and then eventually passing
'params' => $parms
to the PHP soap client
Many thanks!
To get a better look at what XML was being generated by node-soap, I added a console.log(message) statement to the node_modules/soap/lib/client.js after the object-to-XML encoding. I then began experimenting with various JSON structures to figure out empirically how they were mapping to XML structures.
I found a JSON structure for node-soap to generate the XML in my 3rd-party's required named-parameter-with-value format. I was completely unaware of the "$value" special keyword. Looks like this may have been added in the 0.4.6 release from mid-June 2014. See the change history
"params": [
{
"param": {
"attributes": {
"name": "myParameterName"
},
$value: "myParameterValue"
}
}
]
(note the outer array, which gives me the luxury of specifying multiple "param" entries, which is sometimes needed by this particular 3rd-party API)
generates this XML:
<tns:params>
<tns:param name="myParameterName">myParameterValue</tns:param>
</tns:params>
which perfectly matches the structure in soapUI (which I already knew worked) of:
<ns:params>
<ns:param name="myParameterName">myParameterValue</ns:param>
</ns:params>
I have a couple of documents in my couchdb database which all are like:
{
"_id":"1234567890",
"name": [
"category1": 5,
"category2": 8
]
}
I want to have a map function which gives me "category1" as key and 5 as value.
I just can't separate "category" and 5.
I tried the following:
function(doc){
if(doc.name){
doc.name.forEach(function(sth) {
emit(sth, null);
});
}
}
Maybe someone can help me find a solution?
Mind that:
CouchDB function emit() takes two parameters, first is a key (eg. "category1"), second is a value (eg. 5). See the view API documented in the CouchDB wiki.
[key:val, ...] is not correct JSON field syntax, did you mean list of single field records ([{"key1": val1}, {"key2": val2}, ...]) or single multi-field record ({"key1": val1, "key2": val2, ...})?
In case of "name": [{ "category1": 5}, {"category2": 8 }] argument of forEach continuation is {"category1": 5}, and you should get somehow "category1" and 5 separately (forEach() or for (var key in sth) {} once more??).
In case of "name": { "category1": 5, "category2": 8 }, remember the JS object ({"field": val, ...}) does not have forEach method, array ([val1, val2, ...]) prototype does.
Assuming you meant "name": { "category1": 5, "category2": 8 } as the name, consider trying the following map:
function (data) {
if (date.name) {
for (var sth in name) {
emit(sth, name[sth]);
}
}
}
If you are JavaScript beginer, try writing proper code in console first. You can use the one found in the web-browser (Firefox, Chrome have build-in, I advise FireBug addon for Firefox). Good luck!
I would like to generate JAVA classes from a given JSON Schema draft 4 version
I evaluated couple of tools and jsonschema2pojo was found to be useful. But it supports json schema draft-3 version only(although json schema draft 4 is in their roadmap).
Can anyone suggest me a tool or a way to generate java classes from a json schema (compliant to json schema draft4)
?
Thanks in advance.
You might try cog, a general purpose code generator written in Ruby. I put a simple project on github called json2java which demonstrates how cog might be used to generate Java classes from json data.
Not sure exactly what you want to do, but here is what I assumed. The json data would look something like this
{
"classname": "Sample",
"methods": [
{
"name": "foo",
"rtype": "void",
"params": [
{
"name": "arg1",
"type": "int"
}
]
},
{
"name": "bar",
"rtype": "int",
"params": []
}
]
}
And the corresponding Java class would look something like this
public class Sample {
void foo(int arg1) {
// keep: foo {
// While the interface in this example is generated,
// the method bodies are preserved between multiple invocations
// of the generator.
// It doesn't have to be done this way, the method bodies can be
// generated aswell, all depends on what your json data encodes
// keep: }
}
int bar() {
// keep: bar {
return 1;
// keep: }
}
}
If you want to try cog, install it like this gem install cog, and run generators like this cog gen. Check out the cog homepage for documentation.