I'm having a problem with unmarshaling some json data into go struct.
This an Update object I receive from the server :
{
"update_id":433935577,
"poll": {"id":"5899985794147287049","question":"How are you?","options":[{"text":"good","voter_count":0},{"text":"not bad","voter_count":0},{"text":"alright","voter_count":0},{"text":"bad","voter_count":1}],"total_voter_count":1,"is_closed":false,"is_anonymous":true,"type":"regular","allows_multiple_answers":false}
}
And this is the Update struct in my code :
type Update struct {
Update_id int `json:"update_id"`
Message Message `json:"message,omitempty"`
Edited_message Message `json:"edited_message,omitempty"`
ChannelPost Message `json:"channel_post,omitempty"`
EditedChannelPost Message `json:"edited_channel_post,omitempty"`
InlineQuery InlineQuery `json:"inline_query,omitempty"`
ChosenInlineResult ChosenInlineResult `json:"chosen_inline_result,omitempty"`
CallbackQuery CallbackQuery `json:"callback_query,omitempty"`
ShippingQuery ShippingQuery `json:"shipping_query,omitempty"`
PreCheckoutQuery PreCheckoutQuery `json:"pre_checkout_query,omitempty"`
Poll Poll `json:"poll,omitempty"`
PollAnswer PollAnswer `json:"poll_answer,omitempty"`
MyChatMember ChatMemberUpdated `json:"my_chat_member,omitempty"`
ChatMember ChatMemberUpdated `json:"chat_member,omitempty"`
ChatJoinRequest ChatJoinRequest `json:"chat_join_request,omitempty"`
}
Basically every time one of the update fields is returned by the server, i mean some times server returns the update object with message field and some times when a poll is updated it returns it with poll field. There's no problem when server returns message field and it's unmarshaled successfully.
So normally json.Unmarshal() should unmarshal the data into the Update struct and populate the Poll field but it's not working and the Poll field is blank and not populated and I have no idea why.
And this is the Poll struct :
type Poll struct {
Id string `json:"id"`
Question string `json:"quetion"`
Options []PollOption `json:"options"`
TotalVoterCount int `json:"total_voter_count"`
IsClosed bool `json:"is_closed"`
IsAnonymous bool `json:"is_anonymous"`
Type string `json:"type"`
AllowsMultipleAnswers bool `json:"allows_multiple_answers"`
CorrectOptionId int `json:"correct_option_id,omitempty"`
Explanation string `json:"explanation,omitempty"`
ExplanationEntities []MessageEntity `json:"explanation_entities,omitempty"`
OpenPeriod int `json:"open_period,omitempty"`
CloseDate int `json:"close_date,omitempty"`
}
I would appreciate it if you could help me how to fix it!
Some extra notes : The full data i receive from server is like this :
{"ok" : bool , "result" : array of update objects}
and this is the struct I have for this response :
type UpdateResult struct {
Ok bool `json:"ok"`
Result []Update `json:"result"`
}
And this is the code I use for unmarshaling :
ur := &UpdateResult{}
//body is a byte slice which contains the data received from server.
err := json.Unmarshal(body, ur)
When this code runs, err is nil but Poll is still not populated.
CodePudding user response:
The issue is that you're unmarshalling a single value to a slice
The Result
in this type will hold
type UpdateResult struct {
Ok bool `json:"ok"`
Result []Update `json:"result"`
}
This
{
"update_id":433935577,
"poll": {"id":"58"...}
}
Then it will never work, it should be
type UpdateResult struct {
Ok bool `json:"ok"`
Result Update `json:"result"`
}
Or you could Unmarshal to a single Result and then append
it.
CodePudding user response:
I tried single and array of object both are working fine and also getting Poll
data properly as expected.
Change the json tag quetion
to question
inside Poll
struct.
Question string `json:"quetion"`
You can run it here : https://go.dev/play/p/QKz98EXJkcc
Here is the code sample :
func main() {
// {"ok" : bool , "result" : array of update objects}
data := []byte(`{
"ok":true,
"result":[{
"update_id":433935577,
"poll": {"id":"5899985794147287049","question":"How are you?","options":[{"text":"good","voter_count":0},{"text":"not bad","voter_count":0},{"text":"alright","voter_count":0},{"text":"bad","voter_count":1}],"total_voter_count":1,"is_closed":false,"is_anonymous":true,"type":"regular","allows_multiple_answers":false}
},
{
"update_id":433935577,
"poll": {"id":"5899985794147287049","question":"How are you?","options":[{"text":"good","voter_count":0},{"text":"not bad","voter_count":0},{"text":"alright","voter_count":0},{"text":"bad","voter_count":1}],"total_voter_count":1,"is_closed":false,"is_anonymous":true,"type":"regular","allows_multiple_answers":false}
}]
}`)
type PollOption struct {
Text string `json:"text"`
VoterCount int `json:"voter_count"`
}
type Poll struct {
Id string `json:"id"`
Question string `json:"question"`
Options []PollOption `json:"options"`
TotalVoterCount int `json:"total_voter_count"`
IsClosed bool `json:"is_closed"`
IsAnonymous bool `json:"is_anonymous"`
Type string `json:"type"`
AllowsMultipleAnswers bool `json:"allows_multiple_answers"`
}
type Update struct {
UpdateId int `json:"update_id"`
Poll Poll `json:"poll,omitempty"`
}
type UpdateResult struct {
Ok bool `json:"ok"`
Result []Update `json:"result"`
}
ur := UpdateResult{}
err := json.Unmarshal(data, &ur)
if err != nil {
fmt.Println("Error :", err)
}
fmt.Println(ur)
}
Output :
{true [{433935577 {5899985794147287049 How are you? [{good 0} {not bad 0} {alright 0} {bad 1}] 1 false true regular false}} {433935577 {5899985794147287049 How are you? [{good 0} {not bad 0} {alright 0} {bad 1}] 1 false true regular false}}]}