简体   繁体   中英

Handling Null JSON Array in Go using struct

we have struct and getting null after append struct in golang. Find below struct with my some part of code in golang.

type XmloutRoomRate struct {    
CancellationPolicy Policies `bson:"cancellationPolicy" json:"cancellationPolicy"`
}


type Policies struct {
    Policies []RoomPolicies `bson:"policies" json:"policies"`
}


type RoomPolicies struct {
    Amount            float64 `bson:"amount" json:"amount"`
    DaysBeforeCheckIn int     `bson:"daysBeforeCheckIn" json:"daysBeforeCheckIn"`
} 

cancelPolicyMain := Policies{}
cancelPolicy := RoomPolicies{}

if cancelAmount < 0 {
  cancelPolicy.Amount = cancelAmount
  cancelPolicy.DaysBeforeCheckIn = cancelDay
  cancelPolicyMain.Policies = append(cancelPolicyMain.Policies, cancelPolicy)
}else{
  cancelPolicyMain = agodaPolicies{}
  cancelPolicyMain.Policies = append(cancelPolicyMain.Policies)
}

when data present getting proper data structure.

"cancellationPolicy": {
   "policies": [
                {
                  "amount": 5141.58,
                  "daysBeforeCheckIn": 5
                }
              ]
}

But when data not available getting struct with null value.

"cancellationPolicy": {
            "policies": null
           }

We need my actual output with blank array [].

"cancellationPolicy": {
            "policies": []
           }

nil slice values are marshaled into JSON null values. This is documented at json.Marshal() :

Array and slice values encode as JSON arrays, except that []byte encodes as a base64-encoded string, and a nil slice encodes as the null JSON value .

Non- nil empty slices are marshaled into empty JSON arrays. So simply initialize Policies.Policies to an empty slice, and it will be [] in the output:

cancelPolicyMain = Policies{Policies: []RoomPolicies{}}

Test code:

const cancelDay = 1

for cancelAmount := -500.0; cancelAmount <= 501; cancelAmount += 1000 {
    cancelPolicyMain := Policies{}
    cancelPolicy := RoomPolicies{}

    if cancelAmount < 0 {
        cancelPolicy.Amount = cancelAmount
        cancelPolicy.DaysBeforeCheckIn = cancelDay
        cancelPolicyMain.Policies = append(cancelPolicyMain.Policies, cancelPolicy)
    } else {
        cancelPolicyMain = Policies{Policies: []RoomPolicies{}}
        cancelPolicyMain.Policies = append(cancelPolicyMain.Policies)
    }

    x := XmloutRoomRate{cancelPolicyMain}
    if err := json.NewEncoder(os.Stdout).Encode(x); err != nil {
        panic(err)
    }
}

Output (try it on the Go Playground ):

{"cancellationPolicy":{"policies":[{"amount":-500,"daysBeforeCheckIn":1}]}}
{"cancellationPolicy":{"policies":[]}}

In an array, the meaning of a "null" entry is clear: It means this array entry is missing.

In an object aka dictionary, there are different ways to indicate "no entry": The key might not be there. Or the key might not be there, but with an empty array as value. Or the key might be there, but with a "null" value.

You really need agreement between the provider of the data and the client processing it, what each of these mean. And since it's often hard to change what the data provider does, translate what you get into what you need.

So you have to decide what it means if "policies" does not exist as a key, or if it exists as a null value. I've seen software that wouldn't produce arrays with one element, but would provide the single element instead. So "policies": { "amount": ..., "daysBeforeCheckin": ... } would also be possible. You decide what you accept, what you treat as an array, and how you change from the form you got to the form you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM