1

From what I have searched and found this very well may not be possible but any help would be appreciated.

I have a spring controller that accepts a DTO that I have created and one of the attributes is a Map. On my html page I am trying to bundle a map from the page into the JSON but the only way I have found to do this is to convert the map into an array. This causes the deserialization to fail because of incompatible types.

E.G.

Controller:

@PostMapping("/mapping")
public ResponseEntity addThing(@Validated @RequestBody Dto dto, BindingResult result){
    //Do some stuff
}

Dto:

public class Dto {
     ...
     private Map<Integer, String> map;
     ...
}

Javascript:

...
var map = new Map();
$("#mapBody tr").map(function () {
     var value = $(this).find( "input[name=value]").val();
     var index = $(this).find("input[name=index]").val();
     map.set(index, value);
});
...
var data = {
//other values
"map": Array.from(map.entries()), //This is what I have found so far but 
                                  //this is what I believe needs to be changed
//Some more values
}
...
$.ajax({
   url: "/mapping",
   type: "POST",
   data: JSON.stringify(data),
   ...
});

As mentioned above, the changing into an array makes the deserialization fail, but otherwise the stringify makes the map into just: {} which I know is the expected behavior.

Is there anyway I can change this to make it do what I would like it to?

EDIT: This is the result of the stringify with the Array.from()

"{
  //values
  "map":[["0","value"],["1","another value"],["2","third value"]], 
  //more values
 }"

And like I mentioned above, if I just use "map":map then the resulting parsing is "map":{}

8
  • 2
    Please post what your JSON actually looks like. Commented Nov 30, 2018 at 16:13
  • Looks you have key as string in JSON, but you are trying to assign it to Map<Integer, String> Commented Nov 30, 2018 at 16:36
  • @vlad324 That's a good point. Any idea how I can make sure that those are integers instead of strings after the Array.from(map.entries())? Commented Nov 30, 2018 at 16:40
  • @G.Blandin try this one map.set(parseInt(index), value); never mind, stupid idea Commented Nov 30, 2018 at 16:46
  • @vlad324 I found using Number($(this).find("input[name=index]").val()); made it a number so that works, however this still does not fix the deserialization issue. Commented Nov 30, 2018 at 16:51

1 Answer 1

1

I just thought a little about your problem. We can't serialize JS Map() properly (Problems with JS map serialization), so my preposition is to change your code in this way:

...
var map = {}; // using object instead of map 
$("#mapBody tr").map(function () {
     var value = $(this).find( "input[name=value]").val();
     var index = $(this).find("input[name=index]").val();
     map[index] = value; // setting property of object
});
...
var data = {
//other values
"map": map, // using map object instead of array
//Some more values
}
...
$.ajax({
   url: "/mapping",
   type: "POST",
   data: JSON.stringify(data),
   ...
});

So resulting JSON looks like this:

'{"id":1,"map":{"1":"val1","2":"val2","3":"val3"},"otherProperty":"otherValue"}'

And this one is parsable to DTO with HashMap<Integer, String> map inside. Try it please and let me know if it works.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a bunch! This solved the issue. I didn't think just using an object would map correctly but it did. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.