How can I print out a map[string]interface{} as json?

go
10,870

If you want to format your output as JSON, it's better to use the json package. There's a well-written introduction to json handling in this blog post, but generally the Marshal function is happy to take a map of map[string]interface{} where interface{} is any other type that it is able to marshal:

b, err := json.Marshal(m)

This returns a byte array, so you'll need to convert it to a string:

m := map[string]string{
    "USER_ID":"JD", 
    "USER_NAME":"John Doe",
}
b, err := json.Marshal(m)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(b))

https://play.golang.org/p/rffsuI4BL35

However, since you know that you're just going to print out the encoded result, it's probably better to use a streamed encoder:

m := map[string]string{
    "USER_ID":"JD", 
    "USER_NAME":"John Doe",
}
enc := json.NewEncoder(os.Stdout)

if err := enc.Encode(m); err != nil {
        log.Fatal(err)
}

https://play.golang.org/p/l2-BOUK3yn9

For your code, it looks like this:

enc := json.NewEncoder(w)
rows, err = db.Queryx(query)
// Note: you should check err here

for rows.Next() {
    results := make(map[string]interface{})
    err = rows.MapScan(results)
    // Note: You should check err here       

    if err := enc.Encode(results); err != nil {
         // Whatever you want to do in an encoding error
    }
}
Share:
10,870

Related videos on Youtube

sibert
Author by

sibert

I have used an unknown RAD tool for several years connecting a datafile. Replaced the local datafile with Postgresql on Debian and I am today familiar with basic SQL. Very stable and rather simple to learn, but still learning. Now trying to learn Golang. Not as simple as I expected... Using Golang for our website. Built by HTML, CSS and Javascript and Golang as engine. In order to learn Go, I have created a test site https://go4webdev.org

Updated on June 04, 2022

Comments

  • sibert
    sibert almost 2 years

    I have a problem with formatting when using sqlx

    rows, err = db.Queryx(query)
    for rows.Next() {
        results := make(map[string]interface{})
        err = rows.MapScan(results)
        fmt.Fprintf(w,"%#v \n", results)
    }
    

    The output when using %#v

    fmt.Fprintf(w,"%#v \n", results)
    

    map[string]interface {}{"USER_ID”:”JD”, "USER_NAME”:”John Doe”}

    map[string]interface {}{"USER_ID”:”JAD”, "USER_NAME”:”Jane Doe”}

    map[string]interface {}{"USER_ID”:”DD”, "USER_NAME”:”Donald Duck”}

    Using only %v

    fmt.Fprintf(w,"%v \n", results)
    

    map[USER_ID:JD USER_NAME:John Doe]

    map[USER_ID:JAD USER_NAME:Jane Doe]

    map[USER_ID:DD USER_NAME:Donald Duck]

    The desired output is to get rid of map[string]interface {}

    {"USER_ID”:”JD”, "USER_NAME”:”John Doe”}

    {"USER_ID”:”JAD”, "USER_NAME”:”Jane Doe”}

    {"USER_ID”:”DD”, "USER_NAME”:”Donald Duck”}

    Is this possible?

    EDIT USING JSON

    According to @Timothy Jones I have updated the main code and it work as expected. Except that the result is printed to the TERMINAL and not browser.

    rows, err = db.Queryx(query)
      for rows.Next() {
        results := make(map[string]interface{})
        err = rows.MapScan(results)
        if err := enc.Encode(results); err != nil {
          fmt.Fprintf(w,"%s\n", results)
        }
      }
    

    {"USER_ID”:”JD”,”USER_NAME”:”John Doe”}

    {"USER_ID”:”JAD”,”USER_NAME”:”Jane Doe”}

    {"USER_ID”:”DD”,”USER_NAME”:”Donald Duck”}

    Removing the error handling just to test. It shows wrong results, but are printed to the BROWSER as it should.

    rows, err = db.Queryx(query)
    for rows.Next() {
      results := make(map[string]interface{})
      err = rows.MapScan(results)
      enc.Encode(results)
      fmt.Fprintf(w,"%s\n", results)
    }
    

    map[USER_ID:JD USER_NAME:John Doe]

    map[USER_ID:JAD USER_NAME:Jane Doe]

    map[USER_ID:DD USER_NAME:Donald Duck]

    One question remains. How do I print the correct result to the BROWSER?

    • Flimzy
      Flimzy almost 6 years
      You'll have to do it yourself, instead of depending on a printf verb
    • sibert
      sibert almost 6 years
      @Flimzy Can you give an example?
    • Peter
      Peter almost 6 years
      Looks like what you want happens to be JSON encoding, so use the encoding/json package.
    • sibert
      sibert almost 6 years
      @Peter Any link or hint how to use encoding/json together with sqlx?
    • Peter
      Peter almost 6 years
      This has nothing to do with sqlx. You want to format a map[string]interface{}. The fact that you fill it with MapScan is irrelevant. encoding/json is documented on golang.org, like every other package in the standard library.
    • sibert
      sibert almost 6 years
      I am stuck being a total newbie. Something like json.Unmarshal([]byte(results]), &results). Or can you be more specific?
  • sibert
    sibert almost 6 years
    Thank you for this exhaustive answer! It sure points me in the right direction, but there still are some minor issues. Look at my updated question.
  • Timothy Jones
    Timothy Jones almost 6 years
    Your updated question is unrelated to your initial question, I recommend you ask a new question.
  • Timothy Jones
    Timothy Jones almost 6 years
    Oh, I didn't see that you were writing to a specific Writer in your original question. I've edited my answer.
  • sibert
    sibert almost 6 years
    Yes! it works better. Thank you! But numeric values does not encode correct: "QTY":"MS4wMA==". How come?
  • sibert
    sibert almost 6 years
    Though this not solved my entire problem, it was an exact answer to my question. Thank you!