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