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 |
Hi Milan,
On 20 Aug 2012, at 14:02, Milan Mimica <[hidden email]> 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 |
That you very much for your input and a great library. I will use a variation of the second solution.
On 20 August 2012 15:34, Sven Van Caekenberghe <[hidden email]> wrote: Hi Milan, Milan Mimica http://sparklet.sf.net |
Free forum by Nabble | Edit this page |