Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Spring variable in javascript

I'm trying to use a Spring variable in javascript:

Map<String, List<String>> states;

and I found some information here

so I tried:

<script th:inline="javascript">
  /*<![CDATA[*/ 
    var xxx = ${states};
    console.log(xxx);
  /*]]>*/
</script>

In my browser's source tab I have something like:

var xxx = {STATE1=[a, b, c, d]};
console.log(xxx);

and the error is: Uncaught SyntaxError: Invalid shorthand property initializer.

I also tried with: var xxx = /*[[${states}]]*/ 'foo'; and if i print console.log(xxx), I got 'foo'.

like image 218
NikNik Avatar asked Aug 29 '17 08:08

NikNik


People also ask

Can I use Thymeleaf in JavaScript?

Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text.

How do you add JavaScript to Thymeleaf?

By default, Thymeleaf expects us to place those templates in the src/main/resources/templates folder. We can create subfolders, so we'll be using a subfolder called cssandjs for this example. For CSS and JavaScript files, the default directory is src/main/resources/static.

How do I use onclick in Thymeleaf?

How do I use onclick in Thymeleaf? 10, thymeleaf doesn't support variables of type other than Boolean and Integer inside th:onclick="" . So if you want to pass a non-boolean and non-integer argument to the onclick() method, th:onclick="" won't work. You have to use th:attr="onclick=" as shown in this answer.


2 Answers

This error is due to {STATE1=[a, b, c, d]} is invalid Javascript object.

The explanation is very trivial: you're seeing the product of server side rendering (you're using Thymeleaf as fat as I can suggest by th:inline tag). So on the server your map object get's rendered as {STATE1=[a, b, c, d]} string. On your client (browser) you get the page with this string, nothing else. There is already no any Java object. Just string. And this string is invalid initialization of an object in Javascript.

So you simply cannot use map this way. You cannot parse this with JSON.parse because it is invalid JSON (there should be : used instead of =).

Hope this helps!

P.S. If you will try to replace = with : in Javascript it will work the other way than you expect: the array [a, b, c, d] will be treated as an array of variables with the names a, b, c and d so you will have to ecnlose it in ''. But I suggest to throw away this idea and rethink you approach. It is not the way it should be used.

like image 67
Dmitry Senkovich Avatar answered Sep 23 '22 18:09

Dmitry Senkovich


I solved my problem using your comments:

1) There was missing single quote:

<script th:inline="javascript">
  /*<![CDATA[*/ 
    var xxx = '${states}';
    console.log(xxx);
  /*]]>*/
</script>

2) The object must be parsed so:

  var hashmap = $.parseJSON(xxx);

3) And before I need to serialize my object (this is not ajax call so I need to serialize it manually):

Map<String, List<String>> states...
  model.addAttribute("states", new ObjectMapper().writeValueAsString(states));

So now I'm able to read my object:

var myList = hashmap['STATE1'];
console.log(myList ) 

will print [a, b, c, d] and I can loop over:

for(i in myList ){
  console.log(myList[i]);
}
like image 41
NikNik Avatar answered Sep 22 '22 18:09

NikNik