fukamachi / caveman

Lightweight web application framework for Common Lisp.
http://8arrow.org/caveman/
775 stars 63 forks source link

The result of render-json is error, when the list has only one member #60

Closed ly5156 closed 9 years ago

ly5156 commented 9 years ago

My case is

(render-json  '((COMMENT-ID 4 COMMENT-AUTHOR liuyan COMMENT-TEXT testcomment)))

the result is error:

"{\"commentid\":[4,\"commentauthor\",\"liuyan\",\"commenttext\",\"testcomment\"]}"
and the right result should be
"[{\"commentid\":4,\"commentauthor\":\"liuyan\",\"commenttext\":\"testcomment\"}]"
```lisp
hijarian commented 9 years ago
  1. Please, use ```lisp fenced code blocks, this way you'll get source code highlighting, which will help read your examples. :)
  2. render-json uses internal function encode-json, I'm not sure what package it is from, but apparently when you pass a list to it, it treats it as an alist, which means, it should be an array of pairs, first element of a pair is a key, second one is a value.

What I mean is this.

Prepare:

(ql:quickload "caveman2")
(caveman2:make-project #P"~/systems/quicklisp/local-projects/caveman")
(ql:quickload "demo-caveman")
(in-package :demo-caveman.view)

Now look:

;;;; Passing an ordinary list
(encode-json '(1 2 3))
>> "[1,2,3]"

;;;; Passing a list of pairs
(encode-json '((1 . 2) (3 . 5)))
>> "{\"1\":2,\"3\":5}"

;;;; Passing a list of lists --- each sublist is treated as pair of first element and tail
(encode-json '((1 2 3))) ; same as '((1 . (2 3)))
"{\"1\":[2,3]}"

So what you get is not an error, but expected (badly documented maybe) behavior. If you want to get

"[{"commentid":4,"commentauthor":"liuyan","commenttext":"testcomment"}]"

you want to use

(render-json '(("commentid" . 4) ("commentauthor" . "liuyan") ("commenttext" . "testcomment"))
ly5156 commented 9 years ago

Thank you for your answer. It's very helpful to me.