This question already has an answer here:
Why struct fields are showing empty?
(1 answer)
Closed 2 years ago.
I have a simple struct with string and int.
When I unmarshal a json the struct members are not getting parsed if beginning with lowercase string .Even if I am using in the same package
package main
import (
"encoding/json"
"fmt"
)
type Bird struct {
Species string
Description string
lifespan int
}
func main() {
birdJson := `{"species": "pigeon","description": "likes to perch on rocks","lifespan": 9}`
var bird Bird
json.Unmarshal([]byte(birdJson), &bird)
fmt.Printf("Species: %s, Description: %s,lifespan: %d", bird.Species, bird.Description,bird.lifespan)
//Cant read the lifespan ??
}
lifespan int
needs to be
Lifespan int
you can't unmarshal into an unexported field
Related
This question already has answers here:
json.Marshal(struct) returns "{}"
(3 answers)
(un)marshalling json golang not working
(3 answers)
Printing Empty Json as a result [duplicate]
(1 answer)
json.Unmarshal json string to object is empty result [duplicate]
(1 answer)
json.Unmarshal not returning decoded data [duplicate]
(1 answer)
Closed 11 months ago.
I runned the bellow code to retrieve a json from api and parse the values to a struct to use the values, but the print appears in blank.
The json format is:
"user":{
"id":13,
"name":"xpto",
"email":"bla#blum.com.br",
"role":"partner"
},
"token":"hjhfsdhfjkhskfjhsjkfhjksdhfjkshfkjsoiwwsnskcnksjcjkscksjcksbsdsdjsdj"
}
and the code that i am running is:
package main
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
)
type resposta struct {
usuario usuario `json:"user"`
token string `json:"token"`
}
type usuario struct {
id string `json:"id"`
name string `json:"name"`
email string `json:"email"`
role string `json:"role"`
}
func main() {
values := map[string]string{"email": "blablum#xpto.com.br", "password": "senhaaaaa"}
jsonValue, _ := json.Marshal(values)
response, _ := http.Post("https://api.endereco.com.br/sessions", "application/json", bytes.NewBuffer(jsonValue))
defer response.Body.Close()
body, _ := ioutil.ReadAll(response.Body)
println(body)
println(string(body))
var result resposta
json.Unmarshal(body, &result)
println("Resposta")
println(result.token)
println(result.token)
}
Any suggestion?
All your struct fields are unexported (they begin with a lowercase letter) and thus are considered "private." This is preventing the json package from seeing them with reflection. Export your fields by naming them with a Capital letter and it'll work.
Here's an example with some test data: https://go.dev/play/p/0lWdLtNuOr3
This question already has an answer here:
Can't unmarshall JSON with key names having spaces
(1 answer)
Closed 4 years ago.
I am trying to use json.Marshal but it refuses to accept my struct tags.
What am I doing wrong?
Here is the source code for "marshal.go"
https://play.golang.org/p/eFe03_89Ly9
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json: "name"`
Age int `json: "age"`
}
func main() {
p := Person{Name: "Alice", Age: 29}
bytes, _ := json.Marshal(p)
fmt.Println("JSON = ", string(bytes))
}
I get these error messages from "go vet marshal.go"
./marshal.go:9: struct field tag `json: "name"` not compatible with reflect.StructTag.Get: bad syntax for struct tag value
./marshal.go:10: struct field tag `json: "age"` not compatible with reflect.StructTag.Get: bad syntax for struct tag value
I get this output when I run the program.
% ./marshal
JSON = {"Name":"Alice","Age":29}
Notice the field names match the Go structure and ignore the json tags.
What am I missing?
Oh my goodness! I just figured it out. There is no space allowed between json: and the field name "name".
The "go vet" error message ("bad syntax") is remarkably unhelpful.
The following code works. Can you see the difference?
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
p := Person{Name: "Alice", Age: 29}
bytes, _ := json.Marshal(p)
fmt.Println("JSON = ", string(bytes))
}
This question already has answers here:
json.Marshal(struct) returns "{}"
(3 answers)
Closed 5 years ago.
I wonder why the following didn't marshall to json successfully? I am trying to use a very simple example to learn json package.
package main
import (
"encoding/json"
"fmt"
)
type Message struct {
username string `json:"name"`
message string `json:"message"`
}
func main() {
var m = Message{
username: "hello",
message: "world",
}
js, _ := json.Marshal(m)
fmt.Println(m)
fmt.Println(string(js))
}
username
message
start with a lowercase letter, meaning they are unexported (think private), and so are not visible to the encoding/json package. You need to export your fields, or implement the MarshalJSON() ([]byte, error) method and do it yourself.
This question already has answers here:
My structures are not marshalling into json [duplicate]
(3 answers)
Closed 7 years ago.
I have the following code:
package main
import "encoding/json"
import "fmt"
type SuperNum struct {
num string
}
func main() {
byt := []byte(`{"num":"6.13"}`)
var dat SuperNum
if err := json.Unmarshal(byt, &dat); err != nil {
panic(err)
}
fmt.Printf("%+v", dat) // I expect this to have a `num` attribute
}
Output:
{num:}
Program exited.
You can run this code in the golang playground.
Because I'm setting a num property in the struct and in the JSON and they're both strings, I would have expected the dat struct to have a num property, with 'hello', but it doesn't.
What am I doing wrong? What in my mental model of how this should work is incorrect?
EDIT
I tried adding the json signature to the struct, but it makes no difference (no idea what that actually does).
type SuperNum struct {
num string `json:"num"`
}
num is by convention not exported as it is lower case. Change it to Num and you are able to inspect the result.
type SuperNum struct {
Num string
}
Just change num to Num. The lowercase properties of the structures are not visible.
Go playground
When unmarhalling JSON structures, the properties that you're mapping on must be public (remember that in Go, public and private visibility of struct and module members is denoted by the member's name being upper or lower camel case.
So, first of all, your struct must be defined like this:
type SuperNum struct {
Num string // <- note the capital "N"
}
With this struct, the JSON marshaller will expect the JSON property to be also named Num. In order to configure a different property name (like the lowercased num in your example), use the json annotation for that struct member:
type SuperNum struct {
Num string `json:"num"`
}
This question already has answers here:
My structures are not marshalling into json [duplicate]
(3 answers)
Closed 7 years ago.
I'm trying to marshal a struct in Go to JSON but it won't marshal and I can't understand why.
My struct definitions
type PodsCondensed struct {
pods []PodCondensed `json:"pods"`
}
func (p *PodsCondensed) AddPod(pod PodCondensed) {
p.pods = append(p.pods, pod)
}
type PodCondensed struct {
name string `json:"name"`
colors []string `json:"colors"`
}
Creating and marshaling a test struct
fake_pods := PodsCondensed{}
fake_pod := PodCondensed {
name: "tier2",
colors: []string{"blue", "green"},
}
fake_pods.AddPod(fake_pod)
fmt.Println(fake_pods.pods)
jPods, _ := json.Marshal(fake_pods)
fmt.Println(string(jPods))
Output
[{tier2 [blue green]}]
{}
I'm not sure what the issue is here, I export json data for all my structs, the data is being stored correctly and is available to print. It just wont marshal which is odd because everything contained in the struct can be marshaled to JSON on its own.
This is a common mistake: you did not export values in the PodsCondensed and PodCondensed structures, so the json package was not able to use it. Use a capital letter in the variable name to do so:
type PodsCondensed struct {
Pods []PodCondensed `json:"pods"`
}
type PodCondensed struct {
Name string `json:"name"`
Colors []string `json:"colors"`
}
Working example: http://play.golang.org/p/Lg3cTO7DVk
Documentation: http://golang.org/pkg/encoding/json/#Marshal