Home > Software engineering >  How to extract data from map[string]interface{}?
How to extract data from map[string]interface{}?

Time:11-15

I am sending the data to the API like following:

{"after": {"amount": 811,"id":123,"status":"Hi"}, "key": [70]}

and i am getting following while printing :

 map[after:map[amount:811 id:123 status:Hi ] key:[70]]

Is there any way to print individual field like this?? amount::800 id:123 status:Hi

The code:

package main

import (
    "encoding/json"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "net/http"
    "strings"
)

var (
    PORT       = ":8080"
)

func main() {
    fmt.Println("In Main")
    http.HandleFunc("/", changedData)
    http.ListenAndServe(PORT, nil)
}

type Data struct {
    Id               int64 `json:"id"`
    Amount           float64 `json:"amount"`
    Status           string  `json:"status"`
    
}


type mark map[string]interface{}

func changedData(w http.ResponseWriter, r *http.Request) {
    fmt.Println("Coming From API")
    
    reqBody, _ := ioutil.ReadAll(r.Body)
    fmt.Println("Data coming from API ", string(reqBody))

    digit := json.NewDecoder(strings.NewReader(string(reqBody)))

    for digit.More() {
        var result mark
        err := digit.Decode(&result)
        if err != nil {
            if err != io.EOF {
                log.Fatal(err)
            }
            break
        }
        fmt.Println("final_data ", result)
}
}

CodePudding user response:

Decode to a Go type that matches the structure of the JSON document. You declared a type for the "after" field. Wrap that type with a struct to match the document.

func changedData(w http.ResponseWriter, r *http.Request) {
    var v struct{ After Data }
    err := json.NewDecoder(r.Body).Decode(&v)
    if err != nil {
        http.Error(w, "bad request", 400)
        return
    }
    fmt.Printf("final_data: %#v", v.After)
}

Playground example.

CodePudding user response:

I think you can define a struct type if you know the JSON file format or if the JSON format is predefined. As far as I know that mostly using interface{} is a way when you don't know the JSON format or there is no predefined format of the JSON. If you define a struct type  and use it while unmarshaling the JSON to struct, you can access the variables by typing like data.Id or data.Status.

Here's an example code:

package main

import (
    "encoding/json"
    "fmt"
)

type Data struct {
    AfterData After `json:"after"`
    Key       []int `json:"key"`
}

type After struct {
    Id     int64   `json:"id"`
    Amount float64 `json:"amount"`
    Status string  `json:"status"`
}

func main() {
    j := []byte(`{"after": {"amount": 811,"id":123,"status":"Hi"}, "key": [70]}`)
    var data *Data
    err := json.Unmarshal(j, &data)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    fmt.Println(data.AfterData)
    fmt.Println(data.AfterData.Id)
    fmt.Println(data.AfterData.Amount)
    fmt.Println(data.AfterData.Status)

}

Output will be

{123 811 Hi}
123
811
Hi

Go Playground

  •  Tags:  
  • go
  • Related