55

Begining to study golang. Task: Get Json and Unmarshall it. But I get mistake:

Json tag but not exported

How to make unexported fields become exported and then implement it using methods?

Here is the code:

package main

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

type Time struct {
    time
}
type time struct {
    id                    string  `json:"$id"`
    currentDateTime       string  `json:"currentDateTime,string"`
    utcOffset             float64 `json:"utcOffset,string"`
    isDayLightSavingsTime bool    `json:"isDayLightSavingsTime,string"`
    dayOfTheWeek          string  `json:"dayOfTheWeek,string"`
    timeZoneName          string  `json:"timeZoneName,string"`
    currentFileTime       float64 `json:"currentFileTime,string"`
    ordinalDate           string  `json:"ordinalDate,string"`
    serviceResponse       string  `json:"serviceResponse,string"`
}

func (t *Time) GetTime() (Time, error) {
    result := Time{}

    return result, t.Timenow(result)
}
func (t *Time) Timenow(result interface{}) error {

    res, err := http.Get("http://worldclockapi.com/api/json/utc/now")
    if err != nil {
        fmt.Println("Cannot get Json", err)
    }

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println("Cannot create Body", err)
    }

    defer res.Body.Close()

    var resultJson interface{}
    return json.Unmarshal(body, &resultJson)

}

func main() {

    var a Time
    t, err := a.GetTime()
    if err != nil {
        fmt.Println("Error ", err)
    }
    fmt.Println("Time:", t)
}

Please explain in details whats wrong with struct and how to get right response?

frostrock
  • 789
  • 1
  • 5
  • 11
  • 12
    Your struct values need to be exported by having capitalized field names. For example you need to use `CurrentDateTime` instead of `currentDateTime`. – squiguy May 13 '18 at 18:47
  • 1
    https://golang.org/ref/spec#Exported_identifiers – mkopriva May 13 '18 at 18:54
  • 1
    The [encoding/json](https://godoc.org/encoding/json) documentation explains that fields must be exported. The specification [describes exported identifiers](https://golang.org/ref/spec#Exported_identifiers). – Charlie Tumahai May 13 '18 at 18:54

1 Answers1

136

You're adding a JSON tag to a field that isn't exported.

Struct fields must start with upper case letter (exported) for the JSON package to see their value.

struct A struct {
    // Unexported struct fields are invisible to the JSON package.
    // Export a field by starting it with an uppercase letter.
    unexported string

    // {"Exported": ""}
    Exported string

    // {"custom_name": ""}
    CustomName string `json:"custom_name"`
}

The underlying reason for this requirement is that the JSON package uses reflect to inspect struct fields. Since reflect doesn't allow access to unexported struct fields, the JSON package can't see their value.

Thiru
  • 1,380
  • 13
  • 21
Zippo
  • 15,850
  • 10
  • 60
  • 58
  • 1
    I'm learning golang and i was going crazy over the fact that everytime i returned a JSON response it would return empty Objects. Thanks a ton – HaMAD Oct 08 '21 at 11:04