Reputation: 603
I'm having issues with writing a golang library for an api. The json aspect of booleans is causing issues.
Let's say the default value of a boolean is true for an api call.
If I do
SomeValue bool `json:some_value,omitempty`
and I don't set the value through the library, the value will be set to true. If I set the value to false in the library, omitempty says that a false value is an empty value so the value will stay true through the api call.
Let's take out the omitempty and have it look like this
SomeValue bool `json:some_value`
Now I have the opposite issue, I can set the value to false but if I don't set the value then the value will be false even though I expect it to be true.
Edit: How do I maintain the behavior of not having to set the value to true while also being able to set the value to false?
Upvotes: 60
Views: 42538
Reputation: 681
As a continuation to gaav's answer. I had the same problem with unmarshalling instead. If you want to check that the value is provided or not, simply check if the pointer is nil or not
type SomeStruct struct {
SomeValue *bool `json:"some_value,omitempty"`
}
func HandleApiRequest(w http.ResponseWriter, r *http.Request) {
body := new(SomeStruct)
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
err := json.Unmarshal(reqBody, body)
if err != nil {
panic(err)
}
if body.SomeValue != nil {
// SomeValue is provided in the body and is a valid boolean
// Do something with *body.SomeValue
log.Println("Some Value is:", *body.SomeValue)
} else {
// SomeValue was NOT sent in json body
// Will panic with a fault if you tried accessing *body.SomeValue
}
}
Upvotes: 1
Reputation: 4893
package main
import (
"encoding/json"
"fmt"
)
type SomeStruct struct {
SomeValue *bool `json:"some_value,omitempty"`
}
func main() {
t := new(bool)
f := new(bool)
*t = true
*f = false
s1, _ := json.Marshal(SomeStruct{nil})
s2, _ := json.Marshal(SomeStruct{t})
s3, _ := json.Marshal(SomeStruct{f})
fmt.Println(string(s1))
fmt.Println(string(s2))
fmt.Println(string(s3))
}
Output:
{}
{"some_value":true}
{"some_value":false}
Upvotes: 91