Op 10-3-2019 om 17:45 schreef Ben Coman:


On Sun, 10 Mar 2019 at 23:40, Roelof Wobben <r.wobben@home.nl> wrote:
Op 10-3-2019 om 16:19 schreef Ben Coman:


On Sun, 10 Mar 2019 at 17:55, Roelof Wobben <r.wobben@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...��
�� �� 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 : 

{
  "elapsedMilliseconds": 27,
  "artObject": {
    "links": {
      "search": "https://www.rijksmuseum.nl/api/nl/collection"
    },
    "id": "nl-SK-C-5",
    "priref": "5216",
    "objectNumber": "SK-C-5",
    "language": "nl",
    "title": "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ���Nachtwacht���",
    "tags": [
      {
        "userId": 3530,
        "name": "margaret barrett my first collection",
        "lang": "en",
        "objectNumber": "SK-C-5"
      },
      // more results...
    ],
    "copyrightHolder": null,
    "webImage": {
      "guid": "92253da1-794d-49f4-9e3c-e4c160715f53",
      "offsetPercentageX": 50,
      "offsetPercentageY": 100,
      "width": 2500,
      "height": 2034,
      "url": "http://lh6.ggpht.com/wwx2vAS9DzFmmyeZefPjMtmCNOdjD80gvkXJcylloy40SiZOhdLHVddEZLBHtymHu53TcvqJLYZfZF7M-uvoMmG_wSI=s0"
    },
    "colors": [
      "#261808",
      // more results...
    ],
    "colorsWithNormalization": [
      {
        "originalHex": "#261808",
        "normalizedHex": "#000000"
      },
      // more results...
    ],
    "normalizedColors": [
      "#000000",
      // more results...
    ],
    "normalized32Colors": [
      "#000000",
      // more results...
    ],
    "titles": [
      "Officieren en andere schutters van wijk II in Amsterdam onder leiding van kapitein Frans Banninck Cocq en luitenant Willem van Ruytenburch, bekend als de ���Nachtwacht���",
      "Het korporaalschap van kapitein Frans Banninck Cocq en luitenant Willem van Ruytenburch, bekend als de 'Nachtwacht'"
    ],
    "description": "Het korporaalschap van kapitein Frans Banninck Cocq en luitenant Willem van Ruytenburch, bekend als de 'Nachtwacht'. Schutters van de kloveniersdoelen uit een poort naar buiten tredend. Op een schild aangebracht naast de poort staan de namen van de afgebeelde personen: Frans Banninck Cocq, heer van purmerlant en Ilpendam, Capiteijn Willem van Ruijtenburch van Vlaerdingen, heer van Vlaerdingen, Lu[ij]tenant, Jan Visscher Cornelisen Vaendrich, Rombout Kemp Sergeant, Reijnier Engelen Sergeant, Barent Harmansen, Jan Adriaensen Keyser, Elbert Willemsen, Jan Clasen Leydeckers, Jan Ockersen, Jan Pietersen bronchorst, Harman Iacobsen wormskerck, Jacob Dircksen de Roy, Jan vander heede, Walich Schellingwou, Jan brugman, Claes van Cruysbergen, Paulus Schoonhoven. De schutters zijn gewapend met lansen, musketten en hellebaarden. Rechts de tamboer met een grote trommel. Tussen de soldaten links staat een meisje met een dode kip om haar middel, rechts een blaffende hond. Linksboven de vaandrig met de uitgestoken vaandel.",
    "labelText": null,
    "objectTypes": [
      "schilderij"
    ],
    "objectCollection": [
      "schilderijen"
    ],
    "makers": [
      {
        "name": "Rembrandt Harmensz. van Rijn",
        "unFixedName": "Rembrandt Harmensz. van Rijn",
        "placeOfBirth": "Leiden",
        "dateOfBirth": "1606-07-15",
        "dateOfBirthPrecision": null,
        "dateOfDeath": "1669-10-08",
        "dateOfDeathPrecision": null,
        "placeOfDeath": "Amsterdam",
        "occupation": [
          "prentmaker",
          "tekenaar",
          "schilder"
        ],
        "roles": [
          "schilder"
        ],
        "nationality": "Noord-Nederlands",
        "biography": null,
        "productionPlaces": [],
        "schoolStyles": [],
        "qualification": null
      }
    ],
    "principalMakers": [
      {
        "name": "Rembrandt Harmensz. van Rijn",
        "unFixedName": "Rembrandt Harmensz. van Rijn",
        "placeOfBirth": "Leiden",
        "dateOfBirth": "1606-07-15",
        "dateOfBirthPrecision": null,
        "dateOfDeath": "1669-10-08",
        "dateOfDeathPrecision": null,
        "placeOfDeath": "Amsterdam",
        "occupation": [
          "prentmaker",
          "tekenaar",
          "schilder"
        ],
        "roles": [
          "schilder"
        ],
        "nationality": "Noord-Nederlands",
        "biography": null,
        "productionPlaces": [],
        "schoolStyles": [],
        "qualification": null
      }
    ],
    "plaqueDescriptionDutch": "Rembrandts beroemdste en grootste doek werd gemaakt voor de Kloveniersdoelen. Dit was een van de verenigingsgebouwen van de Amsterdamse schutterij, de burgerwacht van de stad. \r\nRembrandt was de eerste die op een groepsportret de figuren in actie weergaf. De kapitein, in het zwart, geeft zijn luitenant opdracht dat de compagnie moet gaan marcheren. De schutters stellen zich op. Met behulp van licht vestigde Rembrandt de aandacht op belangrijke details, zoals het handgebaar van de kapitein en het kleine meisje op de achtergrond. Zij is de mascotte van de schutters.",
    "plaqueDescriptionEnglish": null,
    "principalMaker": "Rembrandt Harmensz. van Rijn",
    "artistRole": null,
    "associations": [],
    "acquisition": {
      "method": "bruikleen",
      "date": "1808-01-01T00:00:00Z",
      "creditLine": "Bruikleen van de gemeente Amsterdam"
    },
    "exhibitions": [],
    "materials": [
      "doek",
      "olieverf"
    ],
    "techniques": [],
    "productionPlaces": [],
    "dating": {
      "presentingDate": "ca. 1642",
      "sortingDate": 1642,
      "period": 17
    },
    "classification": {
      "iconClassIdentifier": [
        "45(+26)",
        "45C1",
        "48C7341",
        "31D11222",
        "45D12",
        "34B11"
      ],
      "motifs": [],
      "events": [],
      "periods": [],
      "places": [
        "Amsterdam"
      ],
      "people": []
    },
    "hasImage": true,
    "historicalPersons": [],
    "inscriptions": [
      "Rembrandt f 1642",
      "signatuur en datum",
      "Frans Banning Cocq, heer van purmerlant en Ilpendam, Capiteijn Willem van Ruijtenburch van Vlaerdingen, heer van Vlaerdingen, Lu[ij]tenant, Jan Visscher Cornelisen Vaendrich, Rombout Kemp Sergeant, Reijnier Engelen Sergeant, Barent Harmansen, Jan Adriaensen Keyser, Elbert Willemsen, Jan Clasen Leydeckers, Jan Ockersen, Jan Pietersen bronchorst, Harman Iacobsen wormskerck, Jacob Dircksen de Roy, Jan vander heede, Walich Schellingwou, Jan brugman, Claes van Cruysbergen, Paulus Schoonhoven",
      "inscriptie"
    ],
    "documentation": [
      "Inzoomer object op zaal, 2013 (Nederlands/English).",
      "A. Jensen Adams, Public Faces and Private Identities in Seventeenth-Century Holland, Portraiture and the Production of Community, New York 2009, p. 211-217, fig. 60.",
      "M. Rayssac, 'l'Exode des Mus��es, Histoire des oeuvres d'art sous l'Occupation', Parijs 2007.",
      // more results...
    ],
    "catRefRPK": [],
    "principalOrFirstMaker": "Rembrandt Harmensz. van Rijn",
    "dimensions": [
      {
        "unit": "cm",
        "type": "hoogte",
        "part": null,
        "value": "379,5"
      },
      {
        "unit": "cm",
        "type": "breedte",
        "part": null,
        "value": "453,5"
      },
      {
        "unit": "kg",
        "type": "gewicht",
        "part": null,
        "value": "337"
      },
      {
        "unit": "kg",
        "type": "gewicht",
        "part": null,
        "value": "170"
      }
    ],
    "physicalProperties": [],
    "physicalMedium": "olieverf op doek",
    "longTitle": "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ���Nachtwacht���, Rembrandt Harmensz. van Rijn, 1642",
    "subTitle": "h 379,5cm �� b 453,5cm �� g 337kg",
    "scLabelLine": "Rembrandt Harmensz. van Rijn (15-jul-1606 - 08-okt-1669), 1642, olieverf op doek",
    "label": {
      "title": "Schutters van wijk II onder leiding van kapitein Frans Banninck Cocq, bekend als de ���Nachtwacht���",
      "makerLine": "Rembrandt Harmensz van Rijn (1606���1669), olieverf op doek, 1642",
      "description": null,
      "notes": null,
      "date": "2013-05-22"
    },
    "showImage": true
  },
  "artObjectPage": {
    "id": "nl-sk-c-5",
    "similarPages": [],
    "lang": "nl",
    "objectNumber": "sk-c-5",
    "tags": [],
    "plaqueDescription": null,
    "audioFile1": null,
    "audioFileLabel1": null,
    "audioFileLabel2": null,
    "createdOn": "0001-01-01T00:00:00Z",
    "updatedOn": "0001-01-01T00:00:00Z",
    "adlibOverrides": {
      "titel": null,
      "maker": null,
      "etiketText": null
    }
  }
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 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 

Roelof