Gin: *gin.Context.JSON turning empty array into null

Created on 25 Sep 2014  ·  5Comments  ·  Source: gin-gonic/gin

*gin.Context.JSON should be able to return an empty array as that is valid json.

Most helpful comment

Maybe you can use make method to create a slice.

func main() {
    router := gin.Default()

    router.GET("/", func(c *gin.Context) {

        var user1 []string
        user2 := make([]string, 0)

        user3 := append(user1, "one item")
        user4 := append(user2, "one item")

        c.JSON(http.StatusOK, gin.H{
            "null_array":   user1,
            "empty_arrary": user2,
            "one_item":     user3,
            "other_one_item": user4,
        })

    })
    router.Run(":8808")
}

☁  ~  curl  http://127.0.0.1:8808/ | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    92  100    92    0     0  99891      0 --:--:-- --:--:-- --:--:-- 92000
{
    "empty_arrary": [],
    "null_array": null,
    "one_item": [
        "one item"
    ],
    "other_one_item": [
        "one item"
    ]
}

All 5 comments

It is encoding/json specific bug(feature)

Do you have a link to bug because I think I may have missed it skimming though them

@apriendeau

Array and slice values encode as JSON arrays, except that []byte encodes as a base64-encoded string, and a nil slice encodes as the null JSON object.

From http://golang.org/pkg/encoding/json/
So

type Struct struct {
    Data []string `json:"data"`
}

func main() {
    value := Struct{}
    b, _ := json.Marshal(value)
    fmt.Println(string(b)) // { "data": null }
    value.Data = []string{}
    b, _ = json.Marshal(value)
    fmt.Println(string(b)) // { "data": [] }
}

http://play.golang.org/p/cmSdTuQtmD

*gin.Context.JSON just wraps json.Marshal and no additional logic done.
Empty array != nil slice

Another example, that shows the difference:
http://play.golang.org/p/MlKFLeqgny

I have a fix that I am doing, I just thought it would be good to have a way to return an empty array when you are returning an array of objects.

Maybe you can use make method to create a slice.

func main() {
    router := gin.Default()

    router.GET("/", func(c *gin.Context) {

        var user1 []string
        user2 := make([]string, 0)

        user3 := append(user1, "one item")
        user4 := append(user2, "one item")

        c.JSON(http.StatusOK, gin.H{
            "null_array":   user1,
            "empty_arrary": user2,
            "one_item":     user3,
            "other_one_item": user4,
        })

    })
    router.Run(":8808")
}

☁  ~  curl  http://127.0.0.1:8808/ | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    92  100    92    0     0  99891      0 --:--:-- --:--:-- --:--:-- 92000
{
    "empty_arrary": [],
    "null_array": null,
    "one_item": [
        "one item"
    ],
    "other_one_item": [
        "one item"
    ]
}
Was this page helpful?
0 / 5 - 0 ratings