0

Here is the example of what I have now. Just a restaurant menu with input number. JS allows me to change input number by clicking on + and - signs. enter image description here

But how can I convert this to an OrderDto entity? It's hard for me to understand how can I input both Dish ID and it's quantity in DTO's map.

Here is an example of HTML menu ( just menu class div where multiple single-menu class divs are located ).

<div class="wrapper">
<div class="title">
   <h4><span>Good food and great vibes</span>our menu</h4>
</div>
<div class="menu">
<div class="single-menu" th:each="dish : ${dishList}">
   <img src="https://via.placeholder.com/150" alt="" />
   <div class="menu-content">
      <h4 th:text="${dish.nameEng}">chicken fried salad <span>$45</span></h4>
      <p>
         Aperiam tempore sit,perferendis numquam repudiandae porro
         voluptate dicta saepe facilis.
      </p>
      <div class="myContainer m-1">
         <button class="decrement" data-type="decrement" onclick="stepper(this)">-</button>
         <input
            type="number"
            min="0"
            max="100"
            step="1"
            value="0"
            readonly
            />
         <button class="increment" data-type="increment" onclick="stepper(this)">+</button>
      </div>
   </div>
</div>

Here is an example of DTO:

public class OrderDto {
    private String userEmail;
    private String userName;
    Map<Dish, Integer> DishQuantityMap;
}

1 Answers1

0

It would be better if you could send DishQuantityMap in id to count format, something like Map<Integer, Integer>. Having some custom object as key in the map can be problematic both for frontend and backend sides. Still if you have to do it like that, it is possible.

OrderDto class - as in your example, don't forget getters and setters.

I'll assume Dish class looks something like this:

public class Dish {


  private Long id;
  private String name;
  private String description;

  //default constructor, getters and setters
  //since it is a key in a map you need proper overrides of hashCode() and equals()
}

I'll also assume you are using Jackson for serialization/deserialization. Jackson cannot just deserialize you custom objects into keys, so you need to create and register KeyDeserializer for your Dish. For example like this:

public class DishKeyDeserializer extends KeyDeserializer {

  private static final ObjectMapper MAPPER = new ObjectMapper();

  @Override
  public Object deserializeKey(String key, DeserializationContext context) throws IOException {
    return MAPPER.readValue(key, Dish.class);
  }
}

Here i am using another mapper to make deserialization of the string key easier. You can see how to register the deserializer in the example.

Your working json will look like this:

{
  "userEmail": "mail@mail.mail",
  "userName": "username",
  "dishQuantityMap": {
    "{\"id\":2,\"name\":\"food2\",\"description\":\"yummiest\"}": 19,
    "{\"id\":1,\"name\":\"food1\",\"description\":\"yummy\"}": 11
  }
}

Take a note how key in the map is Dish object turned into json string, with proper escapes of quotes.

And an example to play around:

    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    //add key deserializer in module
    module.addKeyDeserializer(Dish.class, new DishKeyDeserializer());
    //register module
    mapper.registerModule(module);

    //getting the json as project resource, you get it however you need
    InputStream stream = ClassLoader.getSystemResourceAsStream("order.json");
    OrderDto parsedOrder = mapper.readValue(stream, OrderDto.class);
Chaosfire
  • 4,818
  • 4
  • 8
  • 23