Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example for consuming a list of objects #3

Open
justjoheinz opened this issue Feb 4, 2021 · 5 comments
Open

Example for consuming a list of objects #3

justjoheinz opened this issue Feb 4, 2021 · 5 comments

Comments

@justjoheinz
Copy link

I can succesfully consume a class person from the according json format, but how do I invoke json-to-clos if my json endpoint returns a list of person. Being fairly new to Common Lisp I do not grokk yet how to provide the according class information.

@gschjetne
Copy link
Owner

gschjetne commented Mar 8, 2021

There's no API for it in json-mop. You'll have to parse your JSON response with Yason into a list of hash tables, iterate over it and calling json-to-clos with your person class on each element.

Maybe there should be an API for it. I feel bad for not maintaining this library all these years, I really need to do something about that.

@mooseyboots
Copy link

i had the same issue, and managed to implement it with a loop.

then i was reading up a little more on initializing, and discovered the initialize-instance method, which can be called with :after, and specialized on a given class. i tried to use it to iterate over a list of hash-tables in the slot of an initialized object, and call json-to-clos on each one, as suggested above.

but it doesn't work, even though the initialize-instance method is being called, and it does work when called using make-instance instead of json-to-clos.

is there some way that my initialize-instance perhaps needs to come after a similar method from this library? i see that json-mop:json-serializable-class has such a method (:around), and the yason library also does. i'm new to CLOS and so don't immediately understand the order of all the many initialize-instance methods.

or could there be something else in json-to-clos that prevents this from working?

seems like initialize-instance is a good way to go about handling a list of objects in a slot.

@kilianmh
Copy link
Contributor

Consuming list / vectors can be implemented by adding these two additional json-to-clos methods

(defmethod json-to-clos ((input list) class &rest initargs)
  (declare (ignore initargs))
  (mapcar (lambda (element)
            (json-to-clos element class))
          input))

(defmethod json-to-clos ((input vector) class &rest initargs)
  (declare (ignore initargs))
  (coerce (json-to-clos (coerce input 'list) class)
          'vector))

Then we can parse an list object with json-to-clos the same way as one object.

What do you think @gschjetne ?

@gschjetne
Copy link
Owner

My CL is a bit rusty, but could we specialize on sequence instead, and kill two birds with one stone?

@kilianmh
Copy link
Contributor

kilianmh commented Aug 27, 2023

Sure we can also do it with a method specialized on sequence, such as:

(defmethod json-to-clos ((input sequence) class &rest initargs)
  (declare (ignore initargs))
  (etypecase input
    (list
     (mapcar (lambda (element)
               (json-to-clos element class))
             input))
    (vector
     (map 'vector
          (lambda (element)
            (json-to-clos element class))
          input))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants