Ticket #358 (closed defect: wontfix)
JSON in t:variable - quotes problem
| Reported by: | gdb | Owned by: | mpo |
|---|---|---|---|
| Priority: | major | Milestone: | 0.4 |
| Component: | modules/kauri-forms | Version: | trunk |
| Keywords: | t:variable JSON quotes | Cc: | kauri-discuss@… |
Description
when a JSON t:variable is created it has no quotes on the values
for example in the sample of the dbforms in persons.xml there is a variable personList:
<t:variable name="personList" src="service:/jpaRestlet/person" accept="application/json"/>
When you try to use this variable it gives some trouble beceause there are no quotes arond the values.
For example when you try this:
alert(${personList});
or
kauriform[0].setWireValue(${personList});
Change History
comment:1 follow-up: ↓ 4 Changed 3 years ago by mpo
- Status changed from new to closed
- Resolution set to wontfix
comment:2 Changed 3 years ago by gdb
I'm understanding your point and I already solved it with a ajax call.
But what is the reason why it worked before? (don't know since when this is broken)
comment:3 Changed 3 years ago by mpo
I've just checked the history on the t:variable implementation
Looks like this could be side-wise triggered by r1646 and r1643. (for #175)
So I guess the json lib we used earlier produced a json-specific object (rather then directly mapped Java Objects) when loading from source. Most likely those objects had a toString() triggered from EL that generated proper json I assume. (i.e. probably not simply with "" quotes around as the title of this issue suggested, but with [] and {} for arrays/maps ?)
By the way: it does make sense to report errors/bugs as 'behavior-changes' right away. Such helps in checking out and helping to find the issue. It also adds up to your case of 'expected' behavior. Even if it was an unintended side-effect, the report might thus show a more common use and at least hint about careful documentation and upgrade-warning.
All in all, I feel this could end up as a feature request for some toJson() function in the template language. That way it would also be available for more t:variable cases: (i.e. pointing to java objects set from code rather then showing some side effect if those were loaded from a json source)
I've created the feature request in #361
comment:4 in reply to: ↑ 1 ; follow-up: ↓ 5 Changed 3 years ago by idbr
Replying to mpo:
What you describe is correct behavior, and we shouldn't be doing anything about it.
If this IS the correct and expected behavior, it wasn't before, because the kauri-dbforms-sample was based on this:
<t:variable name="person" src="service:/jpaRestlet/person/${id}" accept="application/json"/>
and later:
testForm.setWireValue(${person});
So, obviously, this sample is now broken (tested in r1696), as this results in the following invalid code snippet
testForm.setWireValue({id=1, street=Ijzerstraat, number=13, bus=B13, postalCode=9800, city=Deinze, country=Belgium, description=home address});
Also note that generating js code from the template engine isn't a particularly good idea: making ajax calls from the client to load your json data is making more sense IMHO.
In this case (populating a form), I don't think it's that bad, saves an unnecessary call to the server.
comment:5 in reply to: ↑ 4 Changed 3 years ago by mpo
Replying to idbr:
Replying to mpo:
What you describe is correct behavior, and we shouldn't be doing anything about it.
If this IS the correct and expected behavior, it wasn't before,
Yes, as acknowledged see previous comments and #361.
Note also that this is not a 'quotes' problem, but a java-2-json-serialization issue that surfaces because of a change in json library. I think the new issue reflects that nature better, so let us work on a solution there.
Also note that generating js code from the template engine isn't a particularly good idea: making ajax calls from the client to load your json data is making more sense IMHO.
In this case (populating a form), I don't think it's that bad, saves an unnecessary call to the server.
Sure. But keep in mind what is going on!
It will create an extra context you need to wrap/unwrap. So you need to think of an extra set of escapes you need to take care off. The template engine knows about java objects in the variables (one side) it knows about how to produce valid character-streams and XML (other side) but we can't automatically make it know what you are doing inside the XML tags.
What you describe is correct behavior, and we shouldn't be doing anything about it.
In the template language variable references point to actual Java Objects (those can be loaded and then interpreted from some @src, but could also be provided as context to the TemplateRepresentation?)
In your case that would be an ArrayList? of HashMap? (test with ${personList.getClass().getName()}), so where should the quotes go?
Seriously, when you put a reference to such high level Java Objects into the template syntax ${...} the el will simply rely on some internal rules to make the object into a stream of characters to include in the output of the template. While in a lot of cases it will just do what you like, it might of course not be willing.
Specially in your case you don't just want a sensible string representation from the java-object, you want it to be in json format and/or even wrapped into double-quotes: so properly escaped to be a ready printabel javascript string.
Also note that generating js code from the template engine isn't a particularly good idea: making ajax calls from the client to load your json data is making more sense IMHO.
So, I do NOT consider the following as a good example of what people _should_ do, but it probably produces what you were expecting:
<t:variable name="json" value="$g{(new org.codehaus.jackson.map.ObjectMapper()).writeValueAsString(personList)}" /> <script> var l = ${json}; alert(\$.org.kauriproject.JSON.stringify(l)); </script>(This expects you have the form-headerlinks included on your page.)
Anyway I hope it explains what is going on, I hope _not_ that you proceed along this path.
Far better approach: let some jaxRs class produce the list and pass it down a TemplateRepresentation? (or even KauriRepresentation? using the representation-builder.