Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print out a JSON in Go

Tags:

json

go

I'm new to Go, and having trouble figuring out how to print out a JSON I've created. I'm using "encoding/json" and am getting a []byte returned. However when I go to print this out I get:

cannot use json_msg (type []byte) as type string in function argument

After receiving this I've tried to convert the []byte array to a string or an empty interface. However I can't seem to get it to work. Any ideas? Relevant code below:

type Message struct {
    Id int
    Name string
}



for _, row := range rows {
    m := Message{row.Int(0), row.Str(1)}

    json_msg, err := json.Marshal(m)

    if err == nil {
        panic(err)
    }//if

            //tried below to print out a interface, didn't work either
    //var f interface{}
    //err = json.Unmarshal(json_msg, &f)

    fmt.Fprintf(c.ResponseWriter, json_msg)
}//for
like image 669
user387049 Avatar asked Dec 01 '22 20:12

user387049


2 Answers

there's a handful of ways to get what you're looking for.

First, to answer your question directly, fmt.Fprintf if of type func(io.Writer, string, ...interface{}). Since you're passing c.ResponseWriter into it, I assume that's something that satisfies io.Writer. The second argument to fmt.Fprintf is a format string. If you want to print something as a string, you use the %s format string, so what you would want is this:

fmt.Fprintf(c.ResponseWriter, "%s", json_msg)

that answers your question directly, but let's go a little further: is that the right way to solve the problem you're solving? No, not really; it's a little weird to do it that way.

First off, because we know that fmt.Fprintf accepts io.Writer, we're talking about something with a method of the form Write([]byte) (int, error). You could just write that []byte data to the ResponseWriter by calling the Write() method on the ResponseWriter directly:

_, err := c.ResponseWriter.Write(json_msg)

that's slightly less awkward. It turns out, there's an even better way to do this: use a json.Encoder. A json.Encoder is a struct that embeds an io.Writer, effectively adding to any io.Writer struct an Encode method, which will encode structs to json and write them to the writer. The difference is that what you're doing encodes the data to a byte slice in memory, and then copies that into an io.Writer, when you could just write it directly, like this:

err := json.NewEncoder(c.ResponseWriter).Encode(m)

and now you don't even have that intermediate []byte format.

like image 59
jorelli Avatar answered Dec 16 '22 02:12

jorelli


You are using json_msg as the format string in a Printf type function, which only excepts string as the format string ([]byte and string are distinct types. Although you can cast them to each other). The proper way of writing a byte slice would be to specify the format string:

fmt.Fprintf(WRITER_OBJ, "%s", json_msg)

This will print the []byte as it's Unicode contents. You shouldn't use varibles as the format string in Fprintf/Printf. I don't think it's a problematic as it would be in C. But it might cause issues if a "%" got in your JSON.

like image 30
Triss Healy Avatar answered Dec 16 '22 02:12

Triss Healy