ValueMap problem

Hi everyone!

I am having issues with ValueMap when it has more ValueMaps as childs. What I’m trying to do is to send a “complex” model object following a JSON structure so, for each attribute, if it’s not a base type it serializes itself as another Map<?,?>.
This way at the server side I have:

//This map also contains more Map<?,?>
Map<?, ?> modelMap = model.asMap();     
target.addAttribute("model", modelMap);

asMap() looks like:

public Map<?, ?> asMap() {
 HashMap<String, Object> map = new HashMap<String, Object>();
map.put(PictureDrawerConstants.IMAGE, image);
map.put(PictureDrawerConstants.HEIGHT, height);
map.put(PictureDrawerConstants.WIDTH, width);
map.put(LayerType.vegetation.getName(), vegetationLayer.asMap());
map.put(LayerType.manmade.getName(), manmadeLayer.asMap());
map.put(LayerType.water.getName(), waterLayer.asMap());
map.put(LayerType.landcover.getName(), landcoverLayer.asMap());
return map;
}

And the same for the children asMap()

The map is deserialized correctly at the client side

ValueMap map = uidl.getMapAttribute(PictureDrawerConstants.MODEL);
VConsole.log(map.getKeySet().toString());
String image = map.getString(PictureDrawerConstants.IMAGE);
int width = map.getInt(PictureDrawerConstants.WIDTH);
int height = map.getInt(PictureDrawerConstants.HEIGHT);

The console prints the keys ok: [Landcover, Manmade, height, width, Vegetation, image, Water]

The keys Landcover,Manmade, Vegetation and Water correspond to complex objects serialized int maps, so the must be get with the getValueMap(String) method:

ValueMap vegetationLayer = map.getValueMap(LayerType.vegetation.getName());
VConsole.log(vegetationLayer.toString());
VConsole.log(vegetationLayer.getKeySet().toString());

vegetationLayer seems to be ok, at least the JSON:
{index=0, draw0={uid=null, coords=[10, 10, 20, 10, 10, 30]
, close=true}, layerType=Vegetation, uiProperties={visible=true, color=#a7e8b1, opacity=0.8, lineWidth=3}}
BUT
I can’t do anything with the ValueMap object, the keys are lost. The toString log shows:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 …continue until… 163]

If I do

vegetationLayer.containsKey(PictureDrawerConstants.UIPROPERTIES)

I get the error:
JavaScriptException: (TypeError): Cannot use ‘in’ operator to search for ‘uiProperties’ in {index=0, draw0={uid=null, coords=[10, 10, 20, 10, 10, 30]
, close=true}, layerType=Vegetation, uiProperties={visible=true, color=#a7e8b1, opacity=0.8, lineWidth=3}} stack: TypeError: Cannot use ‘in’ operator to search for ‘uiProperties’ in {index=0, draw0={uid=null, coords=[10, 10, 20, 10, 10, 30]
, close=true}, layerType=Vegetation, uiProperties={visible=true, color=#a7e8b1, opacity=0.8, lineWidth=3}}…
Or

int index = vegetationLayer.getInt(PictureDrawerConstants.INDEX);
VConsole.log(index);

Shows “undefined”.

Is there anything I’m doing wrong? Can’t I store maps into maps for Server-Client communication?

Thanks for your help.

I see you are using UIDL based communication, so are you using Vaadin 6 or developing legacy style components for Vaadin 7?

In Vaadin 7, the new communication mechanisms (RPC both ways, shared state from server to client) use the declared types of fields/parameters for generating serialization and deserialization code, so just putting Map there should result in a corresponding Map being received and a Map<String, Map<String, Integer> > should result in a map containing maps.

With the legacy communication mechanism, there are some limitations to how data structures can be nested. If the JSON is correct, though, it looks to me like maps of maps should work and are even used internally (in configuration of redirection in case of errors and in the deprecated class VUIDLBrowser).

Thanks Henri,

I forgot to mention that I’m using Vaadin 6.
I have solved my problem serializing my model object as a JSON String with Gson at the server side, and deserializing it with GWT JSONParser at the client side.

Cheers,
Santi