[Pharo-users] NeoJSON extension - easier list handling with NeoJSONPropertyMapping

Sven Van Caekenberghe sven at stfx.eu
Sat Jun 16 14:47:52 EDT 2018


Hmm, Ben,

Did you see NeoJSONCustomMapping's mapping method category ?

There you can already find #listOfElementSchema: #listOfType: #listOfType:andElementSchema: as well as #mapWithValueSchema:

I am guessing they do what you want, no ? Or am I missing something as well ?

Sven

> On 16 Jun 2018, at 20:27, Ben Coman <btc at openinworld.com> wrote:
> 
> hi Sven,
> 
> With NeoJSON I have found several times in handling lists that
> I need to indirect through  #for:customDo:  like this......
> 
> 	reader 
> 		for: ExercismProblems 
> 		do: [ :mapping |
> 			self halt.
> 			(mapper mapInstVar: #problems) valueSchema: #ArrayOfProblems ].
> 	reader
> 		for: #ArrayOfProblems
> 		customDo: [  :mapping |
> 			mapper listOfElementSchema: ExercismProblem ].
> 
> 
> when I'd really like to be simpler and more concise like this...
> 
> 	reader 
> 		for: ExercismProblems 
> 		do: [ :mapping |
> 			(mapping mapInstVar: #problems) listOfType: Array withElementSchema: ExercismProblem ].	
> 
> so I'm seeking your feedback on the following hack which facilitates that.
> (and if I missed something that already makes it simpler)
> 
> ---------------------------- 
>    Object subclass: #NeoJSONPropertyMapping
> 	instanceVariableNames: 'propertyName valueSchema getter setter collectionClass' "Added collectionClass"
> 
> 
> NeoJSONPropertyMapping >> listOfType: aCollectionClass withElementSchema: elementSchema
> 	collectionClass := aCollectionClass.
> 	valueSchema := elementSchema
> 
> 
>    NeoJSONPropertyMapping >> readObject: anObject from: jsonReader
> 	| value |
> 	value := collectionClass 
> 		ifNil: [jsonReader nextAs: valueSchema]  "nil by default retains the original behaviour"
> 		ifNotNil: [jsonReader nextList: collectionClass of: valueSchema ].
> 	setter value: anObject value: value
> 
>    
>    NeoJSONReader >> nextList: nextListClass of: schema   "copied from #nextAs"
> 	"Secondary interface to parse JSON.
> 	Return a list of objects, each element according to schema."
> 	
> 	^ nextListClass streamContents: [ :stream |
> 			self parseListDo: [ 
> 				stream nextPut: (self nextAs: schema) ] ]
> ----------------------------
> 
> Sample data is shown at: https://github.com/bencoman/pharogui-exercism/blob/master/README.md
> with the following code to access it.
> 
> Object subclass: #ExercismAPI
> 	instanceVariableNames: 'client rawResponse jsonResponse success message result'
> 	classVariableNames: 'ApiKey'
> 	package: 'Exercism'
> 
> 
> ExercismAPI  class >> configureApiKey: key
> 	ApiKey := key. 
> 
> 
> ExercismAPI >> track: trackIdString
> 	self path: 'v2/exercises/' , trackIdString.
> 
> 
> ExercismAPI >> fetchTrack: trackIdString
> 	|znclient response|
> 	ApiKey ifNil: [ self error: 'ApiKey not configured. See class-side ExcercismAPI' ].
> 	znclient := ZnClient new
> 		https;
> 		enforceHttpSuccess: true;
> 		accept: ZnMimeType applicationJson;
> 		host: 'x.exercism.io' .
> 	znclient 	path: 'v2/exercises/' , trackIdString.
> 	znclient queryAt: 'key' put: ApiKey.
> 	^ [ response := znclient get ] 
> 		on: ZnHttpUnsuccessful
> 		do: [ :exception | Transcript crShow: exception ]
> 
> 
> fetchJsonTrack: trackIdString
> 	| reader |
> 	reader := NeoJSONReader on: (self fetchTrack: trackIdString) readStream.
> 	reader 
> 		for: ExercismProblems 
> 		do: [ :mapper |
> 			(mapper mapInstVar: #problems) listOfType: Array andElementSchema: ExercismProblem ].	 
> 	^ reader nextAs: ExercismProblems 
> 
> 
> In Playground...
> 
> ExercismAPI configureApiKey: 'ec60c50cb50d4ffaa97903d5ebb3d5ff'.
> 
> (ExercismAPI new fetchJsonTrack: 'go') inspect
> 
> 
> I'll reset the apikey shortly.  You can get a new one from http://exercism.io/account/key.
> 
> cheers -ben




More information about the Pharo-users mailing list