Unmarshal nested JSON into flat struct in Go [duplicate]











up vote
-1
down vote

favorite













This question already has an answer here:




  • Unmarshaling nested JSON objects in Golang

    8 answers




Suppose I define a struct as following:



type User struct {
ID string
Name string
Age uint
City string `json:"address.city"`
Province string `json:"address.province"`
}


I am able to take a User struct, and expand out the flattened fiends into a nested JSON structure, with an address object. I'm struggling however to go in the other direction.



How would I take the following JSON:



{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}


And unmarshal it into the given struct?



Is there something I'm missing, or will I just have to write it from scratch, probably using reflection?



Thanks










share|improve this question













marked as duplicate by Volker go
Users with the  go badge can single-handedly close go questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 20 at 5:55


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.



















    up vote
    -1
    down vote

    favorite













    This question already has an answer here:




    • Unmarshaling nested JSON objects in Golang

      8 answers




    Suppose I define a struct as following:



    type User struct {
    ID string
    Name string
    Age uint
    City string `json:"address.city"`
    Province string `json:"address.province"`
    }


    I am able to take a User struct, and expand out the flattened fiends into a nested JSON structure, with an address object. I'm struggling however to go in the other direction.



    How would I take the following JSON:



    {
    "ID": "1",
    "Name": "Keith Baldwin",
    "Age": 30,
    "address": {
    "city": "Saskatoon",
    "province": "Saskatchewan"
    }
    }


    And unmarshal it into the given struct?



    Is there something I'm missing, or will I just have to write it from scratch, probably using reflection?



    Thanks










    share|improve this question













    marked as duplicate by Volker go
    Users with the  go badge can single-handedly close go questions as duplicates and reopen them as needed.

    StackExchange.ready(function() {
    if (StackExchange.options.isMobile) return;

    $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
    var $hover = $(this).addClass('hover-bound'),
    $msg = $hover.siblings('.dupe-hammer-message');

    $hover.hover(
    function() {
    $hover.showInfoMessage('', {
    messageElement: $msg.clone().show(),
    transient: false,
    position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
    dismissable: false,
    relativeToBody: true
    });
    },
    function() {
    StackExchange.helpers.removeMessages();
    }
    );
    });
    });
    Nov 20 at 5:55


    This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

















      up vote
      -1
      down vote

      favorite









      up vote
      -1
      down vote

      favorite












      This question already has an answer here:




      • Unmarshaling nested JSON objects in Golang

        8 answers




      Suppose I define a struct as following:



      type User struct {
      ID string
      Name string
      Age uint
      City string `json:"address.city"`
      Province string `json:"address.province"`
      }


      I am able to take a User struct, and expand out the flattened fiends into a nested JSON structure, with an address object. I'm struggling however to go in the other direction.



      How would I take the following JSON:



      {
      "ID": "1",
      "Name": "Keith Baldwin",
      "Age": 30,
      "address": {
      "city": "Saskatoon",
      "province": "Saskatchewan"
      }
      }


      And unmarshal it into the given struct?



      Is there something I'm missing, or will I just have to write it from scratch, probably using reflection?



      Thanks










      share|improve this question














      This question already has an answer here:




      • Unmarshaling nested JSON objects in Golang

        8 answers




      Suppose I define a struct as following:



      type User struct {
      ID string
      Name string
      Age uint
      City string `json:"address.city"`
      Province string `json:"address.province"`
      }


      I am able to take a User struct, and expand out the flattened fiends into a nested JSON structure, with an address object. I'm struggling however to go in the other direction.



      How would I take the following JSON:



      {
      "ID": "1",
      "Name": "Keith Baldwin",
      "Age": 30,
      "address": {
      "city": "Saskatoon",
      "province": "Saskatchewan"
      }
      }


      And unmarshal it into the given struct?



      Is there something I'm missing, or will I just have to write it from scratch, probably using reflection?



      Thanks





      This question already has an answer here:




      • Unmarshaling nested JSON objects in Golang

        8 answers








      json go marshalling unmarshalling






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 20 at 1:10









      robbieperry22

      286




      286




      marked as duplicate by Volker go
      Users with the  go badge can single-handedly close go questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Nov 20 at 5:55


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






      marked as duplicate by Volker go
      Users with the  go badge can single-handedly close go questions as duplicates and reopen them as needed.

      StackExchange.ready(function() {
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function() {
      $hover.showInfoMessage('', {
      messageElement: $msg.clone().show(),
      transient: false,
      position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
      dismissable: false,
      relativeToBody: true
      });
      },
      function() {
      StackExchange.helpers.removeMessages();
      }
      );
      });
      });
      Nov 20 at 5:55


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


























          3 Answers
          3






          active

          oldest

          votes

















          up vote
          1
          down vote













          Create userInfo class



          type UserInfo struct {
          ID string `json:"ID"`
          Name string `json:"Name"`
          Age int `json:"Age"`
          Address struct {
          City string `json:"city"`
          Province string `json:"province"`
          } `json:"address"`
          }


          Then unmarshal your json data into a userinfo object



          var userInfo UserInfo
          jsonStr := `{
          "ID": "1",
          "Name": "Keith Baldwin",
          "Age": 30,
          "address": {
          "city": "Saskatoon",
          "province": "Saskatchewan"
          }
          }`
          json.Unmarshal(byte(jsonStr), &userInfo)





          share|improve this answer





















          • Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
            – Abhay Kumar
            Nov 20 at 5:28












          • Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct as json:"something.something".
            – robbieperry22
            Nov 20 at 17:34


















          up vote
          0
          down vote













          I think you need create an other Address struct.



          type Address struct {
          City string `json:"city"`
          Province string `json:"province"`
          }

          type User struct {
          ID string `json:"id"`
          Name string `json:"name"`
          Age uint `json:"age"`
          Address Address `json:"address"`
          }





          share|improve this answer




























            up vote
            0
            down vote













            You could make a temporary struct type to dump that data into that matches the format you expect. e.g.



            type userData struct {
            ID string
            Name string
            Age uint
            address map[string]string
            }


            Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.



            var allData map[string]json.RawMessage
            var user User{}
            //Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
            err := json.NewDecoder(r.Body).Decode(&allData)
            if err != nil {
            //handle
            }
            err = json.Unmarshal(allData["ID"], &c.ID)
            if err != nil {
            //handle
            }
            var addressMap map[string]string
            err = json.Unmarshal(allData["address"], addressMap)
            if err != nil {
            //handle
            }
            c.City = addressMap["city"]
            c.Province = addressMap["province"]


            I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.






            share|improve this answer




























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              1
              down vote













              Create userInfo class



              type UserInfo struct {
              ID string `json:"ID"`
              Name string `json:"Name"`
              Age int `json:"Age"`
              Address struct {
              City string `json:"city"`
              Province string `json:"province"`
              } `json:"address"`
              }


              Then unmarshal your json data into a userinfo object



              var userInfo UserInfo
              jsonStr := `{
              "ID": "1",
              "Name": "Keith Baldwin",
              "Age": 30,
              "address": {
              "city": "Saskatoon",
              "province": "Saskatchewan"
              }
              }`
              json.Unmarshal(byte(jsonStr), &userInfo)





              share|improve this answer





















              • Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
                – Abhay Kumar
                Nov 20 at 5:28












              • Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct as json:"something.something".
                – robbieperry22
                Nov 20 at 17:34















              up vote
              1
              down vote













              Create userInfo class



              type UserInfo struct {
              ID string `json:"ID"`
              Name string `json:"Name"`
              Age int `json:"Age"`
              Address struct {
              City string `json:"city"`
              Province string `json:"province"`
              } `json:"address"`
              }


              Then unmarshal your json data into a userinfo object



              var userInfo UserInfo
              jsonStr := `{
              "ID": "1",
              "Name": "Keith Baldwin",
              "Age": 30,
              "address": {
              "city": "Saskatoon",
              "province": "Saskatchewan"
              }
              }`
              json.Unmarshal(byte(jsonStr), &userInfo)





              share|improve this answer





















              • Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
                – Abhay Kumar
                Nov 20 at 5:28












              • Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct as json:"something.something".
                – robbieperry22
                Nov 20 at 17:34













              up vote
              1
              down vote










              up vote
              1
              down vote









              Create userInfo class



              type UserInfo struct {
              ID string `json:"ID"`
              Name string `json:"Name"`
              Age int `json:"Age"`
              Address struct {
              City string `json:"city"`
              Province string `json:"province"`
              } `json:"address"`
              }


              Then unmarshal your json data into a userinfo object



              var userInfo UserInfo
              jsonStr := `{
              "ID": "1",
              "Name": "Keith Baldwin",
              "Age": 30,
              "address": {
              "city": "Saskatoon",
              "province": "Saskatchewan"
              }
              }`
              json.Unmarshal(byte(jsonStr), &userInfo)





              share|improve this answer












              Create userInfo class



              type UserInfo struct {
              ID string `json:"ID"`
              Name string `json:"Name"`
              Age int `json:"Age"`
              Address struct {
              City string `json:"city"`
              Province string `json:"province"`
              } `json:"address"`
              }


              Then unmarshal your json data into a userinfo object



              var userInfo UserInfo
              jsonStr := `{
              "ID": "1",
              "Name": "Keith Baldwin",
              "Age": 30,
              "address": {
              "city": "Saskatoon",
              "province": "Saskatchewan"
              }
              }`
              json.Unmarshal(byte(jsonStr), &userInfo)






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 20 at 3:36









              Ehsan.Saradar

              45327




              45327












              • Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
                – Abhay Kumar
                Nov 20 at 5:28












              • Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct as json:"something.something".
                – robbieperry22
                Nov 20 at 17:34


















              • Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
                – Abhay Kumar
                Nov 20 at 5:28












              • Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct as json:"something.something".
                – robbieperry22
                Nov 20 at 17:34
















              Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
              – Abhay Kumar
              Nov 20 at 5:28






              Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
              – Abhay Kumar
              Nov 20 at 5:28














              Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct as json:"something.something".
              – robbieperry22
              Nov 20 at 17:34




              Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct as json:"something.something".
              – robbieperry22
              Nov 20 at 17:34












              up vote
              0
              down vote













              I think you need create an other Address struct.



              type Address struct {
              City string `json:"city"`
              Province string `json:"province"`
              }

              type User struct {
              ID string `json:"id"`
              Name string `json:"name"`
              Age uint `json:"age"`
              Address Address `json:"address"`
              }





              share|improve this answer

























                up vote
                0
                down vote













                I think you need create an other Address struct.



                type Address struct {
                City string `json:"city"`
                Province string `json:"province"`
                }

                type User struct {
                ID string `json:"id"`
                Name string `json:"name"`
                Age uint `json:"age"`
                Address Address `json:"address"`
                }





                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  I think you need create an other Address struct.



                  type Address struct {
                  City string `json:"city"`
                  Province string `json:"province"`
                  }

                  type User struct {
                  ID string `json:"id"`
                  Name string `json:"name"`
                  Age uint `json:"age"`
                  Address Address `json:"address"`
                  }





                  share|improve this answer












                  I think you need create an other Address struct.



                  type Address struct {
                  City string `json:"city"`
                  Province string `json:"province"`
                  }

                  type User struct {
                  ID string `json:"id"`
                  Name string `json:"name"`
                  Age uint `json:"age"`
                  Address Address `json:"address"`
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 20 at 1:38









                  KibGzr

                  1,102510




                  1,102510






















                      up vote
                      0
                      down vote













                      You could make a temporary struct type to dump that data into that matches the format you expect. e.g.



                      type userData struct {
                      ID string
                      Name string
                      Age uint
                      address map[string]string
                      }


                      Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.



                      var allData map[string]json.RawMessage
                      var user User{}
                      //Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
                      err := json.NewDecoder(r.Body).Decode(&allData)
                      if err != nil {
                      //handle
                      }
                      err = json.Unmarshal(allData["ID"], &c.ID)
                      if err != nil {
                      //handle
                      }
                      var addressMap map[string]string
                      err = json.Unmarshal(allData["address"], addressMap)
                      if err != nil {
                      //handle
                      }
                      c.City = addressMap["city"]
                      c.Province = addressMap["province"]


                      I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.






                      share|improve this answer

























                        up vote
                        0
                        down vote













                        You could make a temporary struct type to dump that data into that matches the format you expect. e.g.



                        type userData struct {
                        ID string
                        Name string
                        Age uint
                        address map[string]string
                        }


                        Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.



                        var allData map[string]json.RawMessage
                        var user User{}
                        //Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
                        err := json.NewDecoder(r.Body).Decode(&allData)
                        if err != nil {
                        //handle
                        }
                        err = json.Unmarshal(allData["ID"], &c.ID)
                        if err != nil {
                        //handle
                        }
                        var addressMap map[string]string
                        err = json.Unmarshal(allData["address"], addressMap)
                        if err != nil {
                        //handle
                        }
                        c.City = addressMap["city"]
                        c.Province = addressMap["province"]


                        I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.






                        share|improve this answer























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          You could make a temporary struct type to dump that data into that matches the format you expect. e.g.



                          type userData struct {
                          ID string
                          Name string
                          Age uint
                          address map[string]string
                          }


                          Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.



                          var allData map[string]json.RawMessage
                          var user User{}
                          //Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
                          err := json.NewDecoder(r.Body).Decode(&allData)
                          if err != nil {
                          //handle
                          }
                          err = json.Unmarshal(allData["ID"], &c.ID)
                          if err != nil {
                          //handle
                          }
                          var addressMap map[string]string
                          err = json.Unmarshal(allData["address"], addressMap)
                          if err != nil {
                          //handle
                          }
                          c.City = addressMap["city"]
                          c.Province = addressMap["province"]


                          I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.






                          share|improve this answer












                          You could make a temporary struct type to dump that data into that matches the format you expect. e.g.



                          type userData struct {
                          ID string
                          Name string
                          Age uint
                          address map[string]string
                          }


                          Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.



                          var allData map[string]json.RawMessage
                          var user User{}
                          //Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
                          err := json.NewDecoder(r.Body).Decode(&allData)
                          if err != nil {
                          //handle
                          }
                          err = json.Unmarshal(allData["ID"], &c.ID)
                          if err != nil {
                          //handle
                          }
                          var addressMap map[string]string
                          err = json.Unmarshal(allData["address"], addressMap)
                          if err != nil {
                          //handle
                          }
                          c.City = addressMap["city"]
                          c.Province = addressMap["province"]


                          I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 20 at 1:53









                          Slotheroo

                          33018




                          33018















                              Popular posts from this blog

                              Tonle Sap (See)

                              I get strange results when I access the Sqlitedatabase with Unity C# via XAMPP

                              Guatemaltekische Davis-Cup-Mannschaft