ddhille
ddhille

Reputation: 137

Dynamic JSON struct in Golang doesn't behave as expected

I'm trying to create a struct with some basic fields which are always present and some optional fields which are structs by themselves.

I'm wondering why the following code:

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

type DataManagement struct {
    DataManagement struct {
        Type              string
        Asset struct {
            LocalAssetUID string
            Type          string
        }
        *ContentProductionOrder
        *ContentItem
        TimeStamp         time.Time
        Hash              string
    }
}

type ContentProductionOrder struct {
    ProductionOrderNo int
    ItemNo            int
    StartDate         time.Time
    FinishDate        time.Time
    StatusID          int
    StatusDate        time.Time
    SourceTypeID      int
    TrackingID        int
}

type ContentItem struct {
    ItemNo     int
    ItemText   string
    Quantity   int
}

func main() {
    var contentItem ContentItem
    contentItem.ItemNo = 123
    contentItem.ItemText = "aaaaaaaa"
    contentItem.Quantity = 3

    var dataManagement DataManagement
    dataManagement.DataManagement.Type = "asd"
    dataManagement.DataManagement.Asset.LocalAssetUID = "asd"
    dataManagement.DataManagement.Asset.Type = "asd"
    dataManagement.DataManagement.ContentItem = &contentItem
    dataManagement.DataManagement.TimeStamp = time.Now().UTC()
    dataManagement.DataManagement.Hash = "123"

    xy, _ := json.MarshalIndent(dataManagement, "", "  ")
    fmt.Println(string(xy))
    xy, _ = json.MarshalIndent(contentItem, "", "  ")
    fmt.Println(string(xy))
}

outputs to the following:

{
  "DataManagement": {
    "Type": "asd",
    "Asset": {
      "LocalAssetUID": "asd",
      "Type": "asd"
    },
    "ItemText": "aaaaaaaa",
    "Quantity": 3,
    "TimeStamp": "2009-11-10T23:00:00Z",
    "Hash": "123"
  }
}
{
  "ItemNo": 123,
  "ItemText": "aaaaaaaa",
  "Quantity": 3
}

and not to:

{
  "DataManagement": {
    "Type": "asd",
    "Asset": {
      "LocalAssetUID": "asd",
      "Type": "asd"
    },
    "ContentItem": {
      "ItemNo": 123,
      "ItemText": "aaaaaaaa",
      "Quantity": 3
    },
    "TimeStamp": "2009-11-10T23:00:00Z",
    "Hash": "123"
  }
}
{
  "ItemNo": 123,
  "ItemText": "aaaaaaaa",
  "Quantity": 3
}

Any ideas? It's probably pretty easy to explain; I'm not that experienced in Golang.

Here's a Playground link: https://play.golang.org/p/iRDcaRIZ_ZU

Upvotes: 0

Views: 109

Answers (1)

Himanshu
Himanshu

Reputation: 12675

The output you are not getting which you want is because you have used embedded struct for ContentItem in DataManagement rather than field name to add to the struct.

A field declared with a type but no explicit field name is called an embedded field. An embedded field must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.

A field declaration will sove your issue. You should change the struct DataManagement to:

type DataManagement struct {
    DataManagement struct {
        Type  string
        Asset struct {
            LocalAssetUID string
            Type          string
        }
        *ContentProductionOrder // this is embedded struct
        ContentItem *ContentItem
        TimeStamp time.Time
        Hash      string
    }
}

Working Code on Go Playground

For more information, Have a look at Golang Spec for Struct Types

Upvotes: 2

Related Questions