MarshalJSON error , invalid character "g" after top-level
34gj
is not a valid JSON and hence not a valid string representation of your ID. You probably want to wrap this with double quotation mark to indicate this is a string, i.e. returning "34gj"
.
Try:
func (id ID) MarshalJSON() ([]byte, error) {
e, _ := HashIDs.Encode([]int{int(id)})
fmt.Println(e) /// 34gj
return []byte(`"` + e + `"`), nil
}
http://play.golang.org/p/0ESimzPbAx
Instead of doing it by hand you can also call marshaller for the string, by simply replacing your return with return json.Marshal(e)
.
My guess would be that invalid character 'g'
in your error is due to initial part of the value is being treated as a number and then unexpected character occurs.
Emad Ghasemi
Updated on June 05, 2022Comments
-
Emad Ghasemi almost 2 years
I made a custom type for my IDs:
type ID uint func (id ID) MarshalJSON() ([]byte, error) { e, _ := HashIDs.Encode([]int{int(id)}) fmt.Println(e) /// 34gj return []byte(e), nil } func (id *ID) Scan(value interface{}) error { *id = ID(value.(int64)) return nil }
I use the HashIDs package to encode my ids so that user wont be able to read them on client side. But I'm getting this error:
json: error calling MarshalJSON for type types.ID: invalid character 'g' after top-level value
-
Emad Ghasemi almost 9 yearsYes, it might... I had tought the marshaller wrap it it self in " " but don't know why this happend... anyway this solved it, thanks
-
Emad Ghasemi almost 9 yearsI hope there's a better explanation for this behavior
-
tomasz almost 9 yearsEmad, it can't wrap it for you with
"
automatically as by implementing marshaller you're supposed to provide a valid raw JSON. So you can, for example, return{"id": "abc"}
(not a string!). Obviously wrapping it with quotes would be wrong. You can always usereturn json.Marshal(e)
in your code to provide a valid string representation without worrying about quotes (added this comment to my answer).