looping over struct and accessing array in golang

Issue

My issue is

  1. I want to be able to loop over each server and within that loop, loop over UsageData
  2. My current loop gives me an error about ranging over assets not sure why
  3. I cant access assets.Server.UsageData

Here is my code : https://go.dev/play/p/ttNVW5_Q4Ys

package main

import (
    "encoding/json"
    "fmt"
)

type Asset struct {
    Server struct {
        Host string `json:"host"`
        Port string `json:"port"`
    } `json:"server"`
    Postgres struct {
        Host      string `json:"host"`
        User      string `json:"user"`
        Password  string `json:"password"`
        DB        string `json:"db"`
        UsageData []struct {
            Region string `json:"Region"`
            Mbps   int    `json:"Mpbs"`
        } `json:"UsageData"`
    } `json:"database"`
}

func main() {
    jsonConfig := []byte(`[
    {
        "server":{
            "host":"serverA",
            "port":"8080"},
        "database":{
            "host":"serverA",
            "user":"db_user",
            "password":"supersecret",
            "db":"A_db",
            "UsageData":[{"Region":"US","Mbps":100}, {"Region":"EU","Mbps":140}]
        }
    },
    {
        "server":{
            "host":"serverB",
            "port":"8383"},
        "database":{
            "host":"serverB",
            "user":"db_user2",
            "password":"acbd123",
            "db":"B_db",
            "UsageData":[{"Region":"US","Mbps":58}, {"Region":"EU","Mbps":250}]
        }   
    }
]`)
    var assets []Asset
    err := json.Unmarshal(jsonConfig, &assets)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Assets: %+v\n", assets)
    //fmt.Printf("Config: %+v\n", assets.Server.Host)
    //fmt.Printf("Config: %+v\n", assets.database.UsageData)
    //fmt.Printf("Config: %+v\n", assets.Server.UsageData)

    for _, asset := range assets {
        fmt.Printf("%v\n", asset)
        //for _, Usage := range assets.UsageData {
        //  fmt.Printf("%v\n",Usage)
        //}
    }
}

** Code with the correct answer, I was calling the nested struct incorrectly**

https://go.dev/play/p/tEbA405WWbC

Solution

Provided jsonConfig is not technically incorrect but keys SHOULD be unique (see question).
It seems that encoding/json will override value with last occurrence.

So you have 2 options:

  1. change jsonConfig to [{asset1}, {asset2}] (see fixed playground)
  2. implement custom unmarshaler

I definitely recommend first option.

Answered By – medasx

Answer Checked By – Katrina (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.