Hi Milan,

On 20 Aug 2012, at 14:02, Milan Mimica <[email protected]> wrote:

> Hello
> 
> I have obtained a json from a HTTP response which looks like:
> {"login":{"verified":true,"authCookie":"2eb62b41-5156-4056-9b5d-9252b52c93a2"}}
> 
> I want to map this into a Smalltalk class LoginResponse which has two 
> instance variables: verified and authCookie. So I need the mapper to ignore 
> the root property name "login". I think that is a quite common use case. How 
> can it be done?
> 
> 
> -- 
> Milan Mimica
> http://sparklet.sf.net

I understand your question, but currently there is no out of the box support 
for class/type mapping using maps like in your example (there are other 
variation too, like class/type properties, nested or not). The reason is that 
this involves schema checking which I didn't want to do due to the added 
complexity and lack of standardization (this is intentionally outside the JSON 
spec proper).

You have 2 options:

- either use generic parsing and do the conversions and schema checking after 
the parsing (which is what most JSON parser make you do anyway)

NeoJSONReader fromString: 
'{"login":{"verified":true,"authCookie":"2eb62b41-5156-4056-9b5d-9252b52c93a2"}}'.

- write a custom mapping that looks a bit like a hack

(NeoJSONReader on: 
'{"login":{"verified":true,"authCookie":"2eb62b41-5156-4056-9b5d-9252b52c93a2"}}'
 readStream)
        for: #LoginResponseWrapper customDo: [ :mapping |
                mapping reader: [ :jsonReader | | result |
                        result := nil.
                        jsonReader parseMapKeysDo: [ :key |
                                key = #login
                                        ifTrue: [ result := jsonReader next ] ].
                        result ] ];
        nextAs: #LoginResponseWrapper

the above example will go into the login element if it is present and return a 
dictionary.

To make it return your class, this should do the trick

(NeoJSONReader on: 
'{"login":{"verified":true,"authCookie":"2eb62b41-5156-4056-9b5d-9252b52c93a2"}}'
 readStream)
        mapInstVarsFor: LoginResponse;
        for: #LoginResponseWrapper customDo: [ :mapping |
                mapping reader: [ :jsonReader | | result |
                        result := nil.
                        jsonReader parseMapKeysDo: [ :key |
                                key = #login
                                        ifTrue: [ result := jsonReader nextAs: 
LoginResponse ] ].
                        result ] ];
        nextAs: #LoginResponseWrapper

I can image a more general purpose LoginResponseWrapper that maps multiple 
types at once.

HTH,

Sven



--
Sven Van Caekenberghe
http://stfx.eu
Smalltalk is the Red Pill





Reply via email to