On Mon, 11 Mar 2019 at 01:09, Roelof Wobben <r.wob...@home.nl> wrote:

> Op 10-3-2019 om 17:45 schreef Ben Coman:
>
>
>
> On Sun, 10 Mar 2019 at 23:40, Roelof Wobben <r.wob...@home.nl> wrote:
>
>> Op 10-3-2019 om 16:19 schreef Ben Coman:
>>
>>
>>
>> On Sun, 10 Mar 2019 at 17:55, Roelof Wobben <r.wob...@home.nl> wrote:
>>
>>> I could do something like this :
>>>
>>> getImages
>>>     | json numbers json2  |
>>>     json := NeoJSONReader
>>>         fromString:
>>>             (ZnEasy
>>>                 get:
>>>                     '
>>> https://www.rijksmuseum.nl/api/nl/collection?key=14OGzuak&format=json&type=schilderij&toppieces=True
>>> ')
>>>                 contents.
>>>     numbers := self class fromJSON: json
>>>     numbers do: [each |  json :=  .........
>>>                                            imageData = self class ???
>>>
>>
>> I'm not sure what "numbers" refers to. It seems a quite non-domain
>> related identifier.
>> To understand the domain, pasting the json contents of your link above
>> into https://jsonformatter.curiousconcept.com/
>> and collapsing objects I see the structure is...
>>
>> <snip>
>
> Did you work through this example I provided?   Please do so.
> In a clean image...
>
>> Start with only your original code (which was good btw)...
>>
>>     Paintings class >>  fromJSON: json
>>         | instance artObjects |
>>         instance := self new.
>>         artObjects := json at: #artObjects.
>>         artObjects
>>             do:
>>                 [ :eachArtObject | instance addPainting: (Painting
>> fromJSON: eachArtObject) ].
>>         ^ instance
>>
>>
> except objectNumber(s) seem associated with each painting, so should be
> stored within the painting object, as ADDED here...
>
>
>  Painting class >> fromJSON: json
>
>         | instance |
>         instance := self new.
>         instance
>             objectNumber: (json at: #objectNumber);     "<<<<<<<<ADDED"
>             title: (json at: #title);
>             painter: (json at: #principalOrFirstMaker);
>             imageUrl: ((json at: #webImage) at: #url).
>         ^ instance
>
> Evaluate the following in Playground...
>     collectionUrl :=  '
> https://www.rijksmuseum.nl/api/nl/collection?key=14OGzuak&format=json&type=schilderij&toppieces=True
> '.
>     collectionJson := NeoJSONReader fromString: (ZnEasy get:
> collectionUrl) contents.
>     paintings := Paintings fromJSON: collectionJson.
>     paintings inspect.
>
> then clean the DNU errors as they occur (i.e. click the <Create> button
> shown by the debugger, and fill in as follows...)
> when you save the methods, choose <Declare new instance variable>"
>
>     Painting >> objectNumber: aString
> objectNumber := aString
>
>>     Painting >> title: aString
>> title := aString
>>
>>     Painting >> painter: aString
>> painter := aString
>>
>>     Painting >> imageUrl: aString
>> imageUrl := aString
>>
>>     Paintings >> addPainting: aPainting
>> paintings := paintings ifNil: [ OrderedCollection new ].
>> paintings add: aPainting.
>>
>> and an inspector will appear showing a list of paintings, which you can
>> drill down to a painting and see each has the expected data.
>> Now just to round things off...
>>
>>     Painting >> title
>> ^ title
>>
>>     Painting >> printOn: aStream
>> super printOn: aStream.
>> aStream << ' (' << self title << ')'
>>
>> to help distinguish each item in the Inspector.
>>
>>
>> To extend the Playground code to download and display a painting, in
>> Playground evaluate...
>>
>>     painting := paintings first.
>>     imageResponse := ZnEasy get: painting imageUrl.
>>     image := ImageReadWriter formFromStream: imageResponse entity
>> readStream.
>>     image inspect.
>>
>>     Paintings >> first
>> ^ paintings first
>>
>>     Painting >> imageUrl
>> ^ imageUrl
>>
>> and an inspector on the `image` variable displays the painting on the
>> Morph tab.
>>
>>
>> Now to mold the IDE to your domain...
>> using Spotter to browser gtInspector* methods, a promising find is...
>> AbstractFileReference>>gitInspectorJpegIn:
>> from which I produced...
>>
>>     Painting  >>  gtInspectorJpegIn: composite
>> <gtInspectorPresentationOrder: 0>
>> composite morph
>> title: 'Painting';
>> display: [ ImageReadWriter formFromStream: self imageEntity readStream ]
>>
>> Then inspecting the `paintings` variable and drilling down to a painting
>> pops up a DNU #imageEntity, which can be resolved by...
>>
>>     Painting >> imageEntity
>> ^ imageEntity ifNil: [ imageEntity := (ZnEasy get: self imageUrl) entity
>> ].
>>
>> and you get to see the painting shown in the Inspector.
>>
>>
>> Now if I understand your question... "Do I need to make some more object
>> to get this working..."
>> I'd say... No. You only want one object for each painting. Once you have
>> a painting object, it should handle all getting all further data it needs
>> for itself.
>> You don't want duplicate objects each having half of the data.
>>
>>
>> can I for example name the function fromJson2 or fromJSONFromLink2  ?
>>>
>>
>> By naming convention #fromJson: implies it sits on the class side.
>> To get further data for an existing object you want an instance-side
>> method, maybe named #getLink2Json.
>>
>> HTH,
>> cheers -ben
>>
>>
>>
>> oke
>>
>> numbers should be the objectNumbers because for the rest I need them
>>
>
>
>
>
>>
>>
>> I use a instance variable called painting to hold the data.
>>
>>
>> so I can change the call to get data for the painting to :
>>
>> Painting class >> fromJSON: json
>>         | instance |
>>         instance := self new.
>>         instance
>>             objectNumber: ((json at: #objectNumber).
>>         ^ instance
>>
>>
>> so numbers should be a collection of 10 ObjectNumbers
>>
>
> I'm presuming that 10 objectNumbers relate to 10 different paintings,
> in which case, No, you should never need to deal with a collection of 10
> objectNumbers.
> What you should have is a collection of painting-objects which know their
> own objectNumber
> and then iterate that collection sending each painting-object the message
> "getLink2Json".
>
>
>
>> so I should use a loop to make a call to the second api call
>>
>
> In Pharo OO approach, you don't "loop" on the "calls",
> you "iterate" on the "objects" asking them to use their own data to do the
> stuff they know how to do.
> i.e. Let each object take care of itself.
>
> Which class is getImages defined on?  That is really important to
> understand your proposed solution.
> I'm just presuming its defined on the class side of Paintings since your
> are referring to the same URL as before.
>
>>
>>  getImages
>>     | json numbers  |
>>     json := NeoJSONReader
>>         fromString:
>>             (ZnEasy
>>                 get:
>>                     '
>> https://www.rijksmuseum.nl/api/nl/collection?key=14OGzuak&format=json&type=schilderij&toppieces=True
>> ')
>>                 contents.
>>     numbers painting := self class fromJSON: json
>>
>
> btw, it won't work with two identifiers "numbers painting" to the left of
> the assignment symbol.  Space here bad.
>
>
>     numbers  do: [each |  json :=  call to the second url.here I used
>> each
>>                                            imageData = self class
>> getLink2Json
>>
>                                            json2 := call to the 3th url
>>                                            otherData := self class
>> getLink3Json
>>
>>
>
> no :)    the "self class" seems wrong.
> getting extra data about a painting should be handled by the instance side
> of its painting-object.
>
>
>
>> Then  I can  I hope on every json method fill in the data I need
>>
>> Do I understand you well
>>
>
> I think not so well yet :)   (or else I am missing something)
> Keep trying.  It will change the way you think about programming.
>
> Please work though the example I provided.
> cheers -ben
>
>
>
>
> I did and it worked the same as my code
> Still I do not see how to use then the objectNumber in a second call to
> the api
> for example
>
> lets say we have only 1 objectNumber now
> for example
>
> SK-C-5
>
> then I need that one here :   
> https://www.rijksmuseum.nl/api/nl/collection/SK-C-5?key=[API_KEY]&format=json
> so I see a json response of this :
>
> <snip>

> where I at this moment need only artObjects -> makers -> name and artobject 
> -> title
>
> And I need to do that for all 10
>
> But as far as I know I can only have one fromJson
>
> You can have as many Painting-class>>fromJsonXxxx methods as you like,
but you only call one of them once per painting.  This has nothing to do
with Json
and everything to do with your Painting-class>>fromJson method creating a
new Painting-object,
and you only want *one* Painting-object per Json-painting, so you can only
call one.

But actually, you don't need any Painting>>fromJSON:.
Please delete it !!!!

Then modify the other one as follows...
    Paintings class >> fromJSON: json
    | instance |
    instance := self new.
    (json at: #artObjects)
        do:
            [ :artObjectJson |
    |painting|
painting := Painting new.
    painting
        objectNumber: (artObjectJson  at: #objectNumber);
          title: (artObjectJson  at: #title);
        painter: (artObjectJson  at: #principalOrFirstMaker);
        imageUrl: ((artObjectJson  at: #webImage) at: #url).
instance addPainting: painting ].
    ^ instance

Does...
    collectionUrl :=  '
https://www.rijksmuseum.nl/api/nl/collection?key=14OGzuak&format=json&type=schilderij&toppieces=True
'.
    json := NeoJSONReader fromString: (ZnEasy get: collectionUrl) contents.
    paintings := Paintings fromJSON: json.

give you the same result as before?

so how do I take care that the second one is called and parsed
> and the right info is on the Painting object
>
> That is my question all the time
>
>
As I said before...
> What you should have is a collection of painting-objects which know their
own objectNumber
> and then iterate that collection sending each painting-object the message
"getLink2Json".

So more generically, add something like...
    Painting >> getMoreData  "or a better name of your own"
            | url json artObjectJson |
            url := 'https://www.rijksmuseum.nl/api/nl/collection/' ,
objectNumber , '?key=[API_KEY]&format=json'
Transcript crShow: 'Getting description from ', url.
json  := (NeoJSONReader fromString: (ZnEasy get: url) contents).
artObjectJson := json at: 'artObject.
             description := artObjectJson at: 'description'.
             title := artObjectJson at: 'title'.

Now in playground, variable paintings holds a collection 10 ten paintings.
So lets ask each of them to get more data.

paintings do: [ :painting | painting getMoreData ].


cheers -ben

Reply via email to