nested json problem

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

nested json problem

Roelof Wobben
Hello,

I try to use the rijksmuseum api.
This gives json back for 10 paintings and the json looks like this :

{
  "elapsedMilliseconds": 164,
  "count": 359,
  "artObjects": [
    {
      "links": {
        "self": "https://www.rijksmuseum.nl/api/nl/collection/SK-C-5",
        "web": "https://www.rijksmuseum.nl/nl/collection/SK-C-5"
      },
      "id": "nl-SK-C-5",
      "objectNumber": "SK-C-5",
      "title": "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ‘Nachtwacht’",
      "hasImage": true,
      "principalOrFirstMaker": "Rembrandt Harmensz. van Rijn",
      "longTitle": "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ‘Nachtwacht’, Rembrandt Harmensz. van Rijn, 1642",
      "showImage": true,
      "permitDownload": true,
      "webImage": {
        "guid": "92253da1-794d-49f4-9e3c-e4c160715f53",
        "offsetPercentageX": 50,
        "offsetPercentageY": 100,
        "width": 2500,
        "height": 2034,
        "url": "http://lh6.ggpht.com/wwx2vAS9DzFmmyeZefPjMtmCNOdjD80gvkXJcylloy40SiZOhdLHVddEZLBHtymHu53TcvqJLYZfZF7M-uvoMmG_wSI=s0"
      },
      "headerImage": {
        "guid": "29a2a516-f1d2-4713-9cbd-7a4458026057",
        "offsetPercentageX": 50,
        "offsetPercentageY": 50,
        "width": 1920,
        "height": 460,
        "url": "http://lh5.ggpht.com/SgH3Qo-vYI8GGm7-b-Qt6lXgsCAIoU2VDRwO5LYSBVNhhbZCetcvc88ZPi518MTy0MHDrna4X4ZC1ymxVJVpzps8gqw=s0"
      },
      "productionPlaces": []
    },
    // more results...
  ]
}


Artobjects is the part that I want to use because that is the part that contains data from 10 paintings. 

I have tried to parse it like this :  

Painting class >> fromJSON: json [
| instance |
instance := self new.
instance
title: (json at: 'title');
painter: (json at: 'principalOrFirstMaker');
imageUrl: ((json at: 'webImage') at: 'url').
^ instance
]
and

PaintingCollection class >> fromJSON: json [
| instance artObjects |
instance := self new.
artObjects := json at: #artObjects.
artObjects
do: [ :eachArtObject | instance addPainting: (Painting fromJSON: eachArtObject) ].
^ instance
]

but that does not work.

Is there a better way to make this work.
and if so, can someone give me a example how to make this work.
This is my first project that I try to make after doing the MOOC course.

Regards,

Roelof

Reply | Threaded
Open this post in threaded view
|

Re: nested json problem

Sven Van Caekenberghe-2
Hi/Dag Roelof,

In a first approach I would not start by trying to map to actual domain objects (you can do that later), I would start by using NeoJSONObject, which is quite flexible and user friendly.

Consider the following example:

(NeoJSONObject fromString: '{
  "elapsedMilliseconds": 164,
  "count": 359,
  "artObjects": [
    {
      "links": {
        "self": "https://www.rijksmuseum.nl/api/nl/collection/SK-C-5",
        "web": "https://www.rijksmuseum.nl/nl/collection/SK-C-5"
      },
      "id": "nl-SK-C-5",
      "objectNumber": "SK-C-5",
      "title": "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ‘Nachtwacht’",
      "hasImage": true,
      "principalOrFirstMaker": "Rembrandt Harmensz. van Rijn",
      "longTitle": "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ‘Nachtwacht’, Rembrandt Harmensz. van Rijn, 1642",
      "showImage": true,
      "permitDownload": true,
      "webImage": {
        "guid": "92253da1-794d-49f4-9e3c-e4c160715f53",
        "offsetPercentageX": 50,
        "offsetPercentageY": 100,
        "width": 2500,
        "height": 2034,
        "url": "http://lh6.ggpht.com/wwx2vAS9DzFmmyeZefPjMtmCNOdjD80gvkXJcylloy40SiZOhdLHVddEZLBHtymHu53TcvqJLYZfZF7M-uvoMmG_wSI=s0"
      },
      "headerImage": {
        "guid": "29a2a516-f1d2-4713-9cbd-7a4458026057",
        "offsetPercentageX": 50,
        "offsetPercentageY": 50,
        "width": 1920,
        "height": 460,
        "url": "http://lh5.ggpht.com/SgH3Qo-vYI8GGm7-b-Qt6lXgsCAIoU2VDRwO5LYSBVNhhbZCetcvc88ZPi518MTy0MHDrna4X4ZC1ymxVJVpzps8gqw=s0"
      },
      "productionPlaces": []
    }
  ]
}') artObjects first atPath: #(webImage url)

First try to execute the expression inside the braces, and look at the result using the inspector.

Unknown accessor automatically get translated to at: message sends (in this case, at: #artObjects).

Using #atPath: you get the equivalent of webImage.url if you understand what I mean.

To use NeoJSONObject in an actual API call, you could do

ZnClient new
  contentReader: [ :entity | NeoJSONObject fromString: entity contents ];
  url: '...';
  get.

Sven

> On 5 Nov 2018, at 19:32, Roelof Wobben <[hidden email]> wrote:
>
> Hello,
>
> I try to use the rijksmuseum api.
> This gives json back for 10 paintings and the json looks like this :
>
> {
>
>  
> "elapsedMilliseconds": 164,
>
>  
> "count": 359,
>
>  
> "artObjects": [
>
>    
> {
>
>      
> "links": {
>
>        
> "self": "https://www.rijksmuseum.nl/api/nl/collection/SK-C-5",
>
>        
> "web": "https://www.rijksmuseum.nl/nl/collection/SK-C-5"
>
>      
> },
>
>      
> "id": "nl-SK-C-5",
>
>      
> "objectNumber": "SK-C-5",
>
>      
> "title": "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ‘Nachtwacht’",
>
>      
> "hasImage": true,
>
>      
> "principalOrFirstMaker": "Rembrandt Harmensz. van Rijn",
>
>      
> "longTitle": "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ‘Nachtwacht’, Rembrandt Harmensz. van Rijn, 1642",
>
>      
> "showImage": true,
>
>      
> "permitDownload": true,
>
>      
> "webImage": {
>
>        
> "guid": "92253da1-794d-49f4-9e3c-e4c160715f53",
>
>        
> "offsetPercentageX": 50,
>
>        
> "offsetPercentageY": 100,
>
>        
> "width": 2500,
>
>        
> "height": 2034,
>
>        
> "url": "http://lh6.ggpht.com/wwx2vAS9DzFmmyeZefPjMtmCNOdjD80gvkXJcylloy40SiZOhdLHVddEZLBHtymHu53TcvqJLYZfZF7M-uvoMmG_wSI=s0"
>
>      
> },
>
>      
> "headerImage": {
>
>        
> "guid": "29a2a516-f1d2-4713-9cbd-7a4458026057",
>
>        
> "offsetPercentageX": 50,
>
>        
> "offsetPercentageY": 50,
>
>        
> "width": 1920,
>
>        
> "height": 460,
>
>        
> "url": "http://lh5.ggpht.com/SgH3Qo-vYI8GGm7-b-Qt6lXgsCAIoU2VDRwO5LYSBVNhhbZCetcvc88ZPi518MTy0MHDrna4X4ZC1ymxVJVpzps8gqw=s0"
>
>      
> },
>
>      
> "productionPlaces": []
>
>    
> },
>
>    
> // more results...
>
>  
> ]
> }
>
>
> Artobjects is the part that I want to use because that is the part that contains data from 10 paintings.
>
> I have tried to parse it like this :  
>
>
> Painting class >> fromJSON: json [
> | instance |
> instance := self new.
> instance
> title: (json at: 'title');
> painter: (json at: 'principalOrFirstMaker');
> imageUrl: ((json at: 'webImage') at: 'url').
> ^ instance
> ]
> and
>
> PaintingCollection class >> fromJSON: json [
> | instance artObjects |
> instance := self new.
> artObjects := json at: #artObjects.
> artObjects
> do: [ :eachArtObject | instance addPainting: (Painting fromJSON: eachArtObject) ].
> ^ instance
> ]
>
> but that does not work.
>
> Is there a better way to make this work.
> and if so, can someone give me a example how to make this work.
> This is my first project that I try to make after doing the MOOC course.
>
> Regards,
>
> Roelof
>


Reply | Threaded
Open this post in threaded view
|

Re: nested json problem

Roelof Wobben
In reply to this post by Roelof Wobben
I use this code to try to read things:

 json paintingCollection |
json := (NeoJSONReader fromString: (ZnEasy get: 'https://www.rijksmuseum.nl/api/nl/collection?key=14OGzuak&format=json&type=schilderij&toppieces=True') contents).
paintingCollection := PaintingCollection fromJSON: json.
paintingCollection inspect

and now suddenly I see a message that #add: is sent to nill 

Roelof




Op 5-11-2018 om 22:33 schreef Erik Stel:
Roelof,

What does not work in your code? How do you call
PaintingCollection>>fromJSON: ?

>From what I see this code could work if used like (replace URL with actual
URL):







--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html



Reply | Threaded
Open this post in threaded view
|

Re: nested json problem

Sven Van Caekenberghe-2


> On 5 Nov 2018, at 22:41, Roelof Wobben <[hidden email]> wrote:
>
> I use this code to try to read things:
>
>  json paintingCollection |
> json := (NeoJSONReader fromString: (ZnEasy get: '
> https://www.rijksmuseum.nl/api/nl/collection?key=14OGzuak&format=json&type=schilderij&toppieces=True
> ') contents).
> paintingCollection := PaintingCollection fromJSON: json.
> paintingCollection inspect
>
> and now suddenly I see a message that #add: is sent to nill

I am guessing here: is the instance variable holding your collection inside PaintingCollection initialized to an actual collection before you #add: to it in #addPainting: ? You could initialize it lazily if you want.

> Roelof
>
>
>
>
>
> Op 5-11-2018 om 22:33 schreef Erik Stel:
>> Roelof,
>>
>> What does not work in your code? How do you call
>> PaintingCollection>>fromJSON: ?
>>
>> >From what I see this code could work if used like (replace URL with actual
>> URL):
>>
>>
>>
>>
>>
>>
>>
>> --
>> Sent from:
>> http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html
>>
>>
>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: nested json problem

Roelof Wobben
Problem has solved.

I had the instance variable to   instance := self new. instead of
instance := self basicNew.

Roelof



Op 5-11-2018 om 22:50 schreef Sven Van Caekenberghe:

>
>> On 5 Nov 2018, at 22:41, Roelof Wobben <[hidden email]> wrote:
>>
>> I use this code to try to read things:
>>
>>   json paintingCollection |
>> json := (NeoJSONReader fromString: (ZnEasy get: '
>> https://www.rijksmuseum.nl/api/nl/collection?key=14OGzuak&format=json&type=schilderij&toppieces=True
>> ') contents).
>> paintingCollection := PaintingCollection fromJSON: json.
>> paintingCollection inspect
>>
>> and now suddenly I see a message that #add: is sent to nill
> I am guessing here: is the instance variable holding your collection inside PaintingCollection initialized to an actual collection before you #add: to it in #addPainting: ? You could initialize it lazily if you want.
>
>> Roelof
>>
>>
>>
>>
>>
>> Op 5-11-2018 om 22:33 schreef Erik Stel:
>>> Roelof,
>>>
>>> What does not work in your code? How do you call
>>> PaintingCollection>>fromJSON: ?
>>>
>>> >From what I see this code could work if used like (replace URL with actual
>>> URL):
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> --
>>> Sent from:
>>> http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html
>>>
>>>
>>>
>>>
>
>