I am wanting to build a JSON equivalent of the PurchaseOrder
struct below:
type PurchaseOrder struct {
State string
FsmName string
Supplier string
Receiver string
TradeItems map[string]PRTradeItem
}
type PRTradeItem struct {
Quantity float64 `json:"quantity"`
Supplier string `json:"supplier"`
Receiver string `json:"receiver"`
PricePerUnit float64 `json:"pricePerUnit"`
}
In order to do so, I did the following:
po := make(map[string]interface{})
po["Sender"] = "org2"
po["Receiver"] = "org1"
po["TradeItems"] = make(map[string]PRTradeItem)
po["TradeItems"]["sku1"] = PRTradeItem{Quantity: 100, Supplier: "org2", Receiver: "org1", PricePerUnit: 10.5}
poAsBytes, _ := JSON.Marshal(po)
The error that I get is:
invalid operation: po["TradeItems"]["sku1"] (type interface {} does not support indexing).
After looking around a bit, I added the following lines to the code and it worked.
internalMap, ok := po["TradeItems"].(map[string]PRTradeItem)
if !ok{
panic("why???")
}
if ok{
internalMap["sku1"] = PRTradeItem{Quantity:100,Supplier:"org2", Receiver:"org1", PricePerUnit:10.5}
}
I don't quite understand what this line means
internalMap, ok := po["TradeItems"].(map[string]PRTradeItem)
Can someone please explain?
I know the type of
po["TradeItems"]
. Please explain in-depth. Why should I assert?
You do, but the compiler doesn't. Your po
has type map[string]interface{}
. So po["TradeItems"]
in po["TradeItems"]["sku1"]
returns an object of type interface{}
, which you can't do anything useful with (not without reflection or type-assertions).
Hence the need to hint the compiler with that type assertion.
I am wanting to build a JSON equivalent of the PurchaseOrder struct below:
type PurchaseOrder struct { State string FsmName string Supplier string Receiver string TradeItems map[string]PRTradeItem }
The easiest way is:
po := PurchaseOrder{
State: "paid",
Supplier: "Acme, Inc.",
TradeItems: map[string]PRTradeItem{
"sku1": PRTradeItem{Quantity: 100, Supplier: "org2", ... },
},
}
poAsBytes, err := json.Marshal(po)
Forget about your po := make(map[string]interface{})
and manual manipulation of the map.
If you need to control the JSON keys in your PurchaseOrder
object, add the appropriate json
tags, as you did for the PRTradeItem
definition.