yssachan
yssachan

Reputation: 109

How to create custom unmarshal for 2 types map[string]interface{} and []interface{}

Here's my sample go playground https://go.dev/play/p/MosQs62YPvI

My curl API return 2 kind of return, can any of the ff:

{
  "code": 200,
  "message": "Success",
  "data": {
    "list": {
      "1": {
        "user": "user A",
        "status": "normal"
      },
      "2": {
        "user": "user A",
        "status": "normal"
      }
    },
    "page": 1,
    "total_pages": 2000
  }
}

or

 {
  "code": 200,
  "message": "Success",
  "data": {
    "list": [
      {
        "user": "user A",
        "status": "normal"
      },
      {
        "user": "user B",
        "status": "normal"
      }
    ],
    "page": 1,
    "total_pages": 5000
  }
}

How to unmarshal it properly?

Here's my struct

    type User struct {
    Code    int    `json:"code"`
    Message string `json:"message"`
    Data    struct {
        List []struct {
            User   string `json:"user"`
            Status string `json:"status"`
        } `json:"list"`
        Page       int `json:"page"`
        TotalPages int `json:"total_pages"`
    } `json:"data"`
}

Here's how I unmarshal it

err = json.Unmarshal([]byte(io_response), &returnData)
    if err != nil {
        log.Println(err)
    }

I have tried creating my own unmarshal but I have issues converting it to map[string]interface{}

Can you please help me? Or is there any better way?

Upvotes: 1

Views: 2015

Answers (1)

mkopriva
mkopriva

Reputation: 38233

type UserItem struct {
    User   string `json:"user"`
    Status string `json:"status"`
}

type UserList []UserItem

func (ul *UserList) UnmarshalJSON(data []byte) error {
    switch {
    case len(data) == 0 || string(data) == `null`:
        return nil
    case data[0] == '[': // assume it's a JSON array
        return json.Unmarshal(data, (*[]UserItem)(ul))
    case data[0] == '{': // assume it's a JSON object
        obj := make(map[string]UserItem)
        if err := json.Unmarshal(data, &obj); err != nil {
            return err
        }
        for _, v := range obj {
            *ul = append(*ul, v)
        }
        return nil
    default:
        return fmt.Errorf("unsupported json type")
    }
    return nil
}

https://go.dev/play/p/Y5PAjrmPhy2

Upvotes: 1

Related Questions