json.Marshal(struct) returns "{}"
Asked Answered
G

3

181
type TestObject struct {
    kind string `json:"kind"`
    id   string `json:"id, omitempty"`
    name  string `json:"name"`
    email string `json:"email"`
}

func TestCreateSingleItemResponse(t *testing.T) {
    testObject := new(TestObject)
    testObject.kind = "TestObject"
    testObject.id = "f73h5jf8"
    testObject.name = "Yuri Gagarin"
    testObject.email = "[email protected]"

    fmt.Println(testObject)

    b, err := json.Marshal(testObject)

    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(string(b[:]))
}

Here is the output:

[ `go test -test.run="^TestCreateSingleItemResponse$"` | done: 2.195666095s ]
    {TestObject f73h5jf8 Yuri Gagarin [email protected]}
    {}
    PASS

Why is the JSON essentially empty?

Gupton answered 12/10, 2014 at 16:34 Comment(0)
K
347

You need to export the fields in TestObject by capitalizing the first letter in the field name. Change kind to Kind and so on.

type TestObject struct {
 Kind string `json:"kind"`
 Id   string `json:"id,omitempty"`
 Name  string `json:"name"`
 Email string `json:"email"`
}

The encoding/json package and similar packages ignore unexported fields.

The `json:"..."` strings that follow the field declarations are struct tags. The tags in this struct set the names of the struct's fields when marshaling to and from JSON.

Ru it on the playground.

Kew answered 12/10, 2014 at 16:38 Comment(4)
there is supposed to be no "space" before "omitempty"Titmouse
Can I make with small letter ?Milne
If you want small letter tag the fields #21825822Milne
@Milne Set the JSON field name to a lowercase name using the json field tag (as described in last paragraph of this answer).Hen
D
35
  • When the first letter is capitalised, the identifier is public to any piece of code that you want to use.
  • When the first letter is lowercase, the identifier is private and could only be accessed within the package it was declared.

Examples

 var aName // private

 var BigBro // public (exported)

 var 123abc // illegal

 func (p *Person) SetEmail(email string) {  // public because SetEmail() function starts with upper case
    p.email = email
 }

 func (p Person) email() string { // private because email() function starts with lower case
    return p.email
 }
Digital answered 19/7, 2016 at 9:40 Comment(2)
awesome man, work perfect only change first letter to UPPER CASE, thank you so muchUlcer
Exactly, In Go, a name is exported if it begins with a capital letter. To put it in context, visit this Go Basics TourQuit
M
7

In golang

in struct first letter must uppercase ex. phonenumber -> PhoneNumber

======= Add detail

First, I'm try coding like this

type Questions struct {
    id           string
    questionDesc string
    questionID   string
    ans          string
    choices      struct {
        choice1 string
        choice2 string
        choice3 string
        choice4 string
    }
}

golang compile is not error and not show warning. But response is empty because something

After that, I search google found this article

Struct Types and Struct Type Literals Article then... I try edit code.

//Questions map field name like database
type Questions struct {
    ID           string
    QuestionDesc string
    QuestionID   string
    Ans          string
    Choices      struct {
        Choice1 string
        Choice2 string
        Choice3 string
        Choice4 string
    }
}

Is work.

Hope for help.

Moriah answered 30/1, 2020 at 4:46 Comment(2)
add more detailsTaxable
Yapp, I add more details.Moriah

© 2022 - 2024 — McMap. All rights reserved.