sibert
sibert

Reputation: 2208

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

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?

Upvotes: 6

Views: 28691

Answers (1)

Timothy Jones
Timothy Jones

Reputation: 22125

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
    }
}

Upvotes: 10

Related Questions