Bruno,

What about the following ?

json := '{ "id" : 1, "level1" : { "level2" : { "name" : "foo" } } }'.

In the JSON above there is a nesting level1.level2.name that you want to skip 
over.

One solution would be:

NeoJSONReader new
  on: json readStream;
  for: #Foo customDo: [ :mapping |
    mapping decoder: [ :x |
          (x at: #id) -> (((x at: #level1) at: #level2) at: #name) ] ];
  nextAs: #Foo.

The returned type is an Association, but it could be a domain object. #Foo is 
just an identifier. The disadvantage is that anything deeper is not mapped, but 
comes in as a plain dictionary, in a sense defeating the concept of mapping 
(but for leaf like structures this might be what you want).

Alternatively, if you use NeoJSONObject instead of Dictionary, it becomes 
easier to access a nested path:

NeoJSONReader new
  on: json readStream;
  mapClass: NeoJSONObject;
  for: #Foo customDo: [ :mapping |
    mapping decoder: [ :x |
          (x at: #id) -> (x atPath: #(level1 level2 name)) ] ];
  nextAs: #Foo.

HTH,

Sven

PS: Note also that mappings can live on the class side (where they are global), 
but also inside specific NeoJSONReader instances (where they are local), like 
here.

> On 26 Feb 2019, at 03:50, BrunoBB <smallt...@adinet.com.uy> wrote:
> 
> Hi,
> 
> The following implementation do what i want without the need to create a
> class for each level of the JSON, however i really dislike my solution.
> neoJsonMapping: mapper "class side"
>       "Map the receiver to a json with <NeoJSONObjectMapping> <mapper>"
>       mapper for: self do: [ :mapping |
>               (mapping mapProperty: 'booking' getter: [:obj | obj locator] 
> setter: [
> :obj :value | obj setLocator: value]) valueSchema: self.
>       ].
> 
>       mapper for: self do: [ :mapping |
>               mapping mapProperty: '@locator' getter: [:obj | obj locator] 
> setter: [
> :obj :value | obj locator: value]
>       ]
> 
> The first part map 'booking' property to the class locator inst var. The
> second part have access to the "second json level" and the value i'm looking
> for.
> 
> But setLocator: anObject is the ugly thing :(
> setLocator: anObject
>       (anObject class == PmsJsonInput) ifTrue: [^locator := anObject locator].
>       locator := anObject
> 
> I'm sure there must be another way to do this.
> 
> regards,
> bruno
> 
> 
> 
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html
> 


Reply via email to