0

i cannot parse the json value i am sending a playground link Any idea about that? here is the link and codes

https://play.golang.org/p/qhZpS_-618s

package main

import (
    "encoding/json"
    "fmt"
    //mapstructure "github.com/mitchellh/mapstructure"

)

type presence struct{
    id string 
    m_type string 
    deny string 
}
type jsonHandler struct {
    name string 
    dat map[string]interface{}

}   

func main() {
    s := `["Presence",{"id":"905356870666@c.us","type":"unavailable","deny":true}]`
    data := jsonHandler{}
    json.Unmarshal([]byte(s), &data)
    fmt.Printf("Operation: %s", data.name)


}

Output : Operation: Program exited.

  • Does this answer your question? [json.Unmarshal returning blank structure](https://stackoverflow.com/questions/28228393/json-unmarshal-returning-blank-structure) – Peter Dec 24 '19 at 13:38
  • not worked @Peter https://play.golang.org/p/7d62N3BVan9 –  Dec 24 '19 at 13:58
  • solved i add solution –  Dec 24 '19 at 15:17

3 Answers3

1

Go Playground Link: https://play.golang.org/p/qe0jyFVNTH1

Few Problem are present in this:

1. Json Package can't refer the Unexported Structure Elements.So please use Deny instead of deny in the following snippet.This is applicable to all variables declared inside the structure

2. The json fields tag are incorrect. eg.mapstructure:"id" should be json:"id"

3. The json to be parsed contains two distinct elements i.e string "Presence" and nested json object.It can't be parsed as a single element.It is better to declare "Presence" as a key and nested json as the value.

4. The deny variable should be bool rather than string

  • 1
    Well,i want to parse ["Presence",{"id":"905356870666@c.us","type":"unavailable","deny":true}] not you provided to me {"Presence":{"id":"905356870666@c.us","type":"unavailable","deny":true}} so your comment doesn't mean anything to me because i receive this json from whatsapp socket please answer the question accourding to json array of : ["Presence",{"id":"905356870666@c.us","type":"unavailable","deny":true}] –  Dec 24 '19 at 11:50
  • @user3236289 your Json is not a valid Json. Also answer is true. To unmarshall Json, export your struct fields. So use capital letters. Also do not use "mapstructure". And why "jsonHandler" struct has name and dat fields. They are not related with Json data. Maybe you should explain deeply. – Tugrul Bayrak Dec 24 '19 at 11:56
  • my json is correct not wrong format.it comes from whatsapp socket okay? here parsed version of my json https://www.dropbox.com/s/0asnrkkinhfh2ke/Screenshot%202019-12-24%2015.43.44.png?dl=0 –  Dec 24 '19 at 12:44
  • @user3236289 Depending on your use case, Any direct method won't be applicable in this scenario.Either you have to parse data into json.RawMessage(as shown by @alessiosavi) or an interface{} and then implement a custom logic. Using custom unmarshaler is also a good option. kindly go through this article [link](https://engineering.bitnami.com/articles/dealing-with-json-with-non-homogeneous-types-in-go.html) by Marko Mikulicic. You will have some clarity about the possible solutions. – Shivang Goswami Dec 24 '19 at 14:26
1

Try with this one: https://play.golang.com/p/UICf_uNNFdC

I've commented a lot in order to enhance code readability. Be sure to handle error properly and remove debug print.

package main

import (
    "encoding/json"
    "log"
    "strings"
)

type Presence struct {
    Presence string
    ID       string `json:"id"`
    Type     string `json:"type"`
    Deny     bool   `json:"deny"`
}

type JsonHandler struct {
    Name string   `json:"name"`
    Dat  Presence `json:"dat"`
}

func main() {
    var (
        // Used for unmarshal a given json
        packedData []json.RawMessage
        err        error
        // Data that does not have a related json key
        name []byte
        // Used for extract the raw data that will be unmarshalled into the Presence struct
        temp []byte
        // Nested json
        jsonPresence Presence
        handler      JsonHandler
    )

    s := `["Presence",{"id":"905356870666@c.us","type":"unavailable","deny":true}]`

    log.Println("Dealing with -> " + s)

    // Unmarshall into a raw json message
    err = json.Unmarshal([]byte(s), &packedData)
    if err != nil {
        panic(err)
    }

    // Extract the presence
    log.Println("Presence: ", string(packedData[0]))
    // Extract the nested json
    log.Println("Packed: ", string(packedData[1]))

    // NOTE: 0 refers to the first value of the JSON
    name, err = packedData[0].MarshalJSON()
    if err != nil {
        panic(err)
    }
    log.Println("Value that does not have a key: " + string(name))
    handler.Name = strings.Replace(string(name), "\"", "", -1)

    // NOTE: 1 refers to the second value of the JSON, the entire JSON
    // Unmarshal the nested Json into byte
    temp, err = packedData[1].MarshalJSON()
    if err != nil {
        panic(err)
    }

    // Unmarshal the raw byte into the struct
    err = json.Unmarshal(temp, &jsonPresence)
    if err != nil {
        panic(err)
    }

    log.Println("ID:", jsonPresence.ID)
    log.Println("Type:", jsonPresence.Type)
    log.Println("Deny:", jsonPresence.Deny)

    handler.Dat = jsonPresence

    log.Println("Data unmarshalled: ", handler)
}
alessiosavi
  • 2,753
  • 2
  • 19
  • 38
  • we are simply parse `["Presence",{"id":"905356870666@c.us","type":"unavailable","deny":true}]` bro these codes too complicated and too much for this json... there must be a short way (2,3 lines codes) to do that by experiencing 7 years of software developer –  Dec 24 '19 at 13:53
1

Wow,solved problem by adding only these codes

Here Go Lang Link : https://play.golang.org/p/doHNWK58Cae

func (n *JsonHandler) UnmarshalJSON(buf []byte) error {
    tmp := []interface{}{&n.Name, &n.Dat}
    wantLen := len(tmp)
    if err := json.Unmarshal(buf, &tmp); err != nil {
        return err
    }
    if g, e := len(tmp), wantLen; g != e {
        return fmt.Errorf("wrong number of fields in Notification: %d != %d", g, e)
    }
    return nil
}
  • +1 very clean! Have you tested the performance of the two solution? I think that this one is more optimized than my solution in terms of speed. – alessiosavi Dec 25 '19 at 00:37