1

I am really new to Golang and I am trying to parse values to my ErrorMessage struct when an error occurs.

I have this struct:

type ErrorMessage struct {
    Errors []struct {
        Code    string `json:"code"`
        Message string `json:"message"`
        Field   string `json:"field,omitempty"`
    } `json:"errors"`
    Meta struct {
        Status string `json:"status"`
    } `json:"meta"`
}

Which is mapped to display JSON like this:

{
    "errors": [
        {
            "code": "short-code", 
            "message": "Wow, such bad!"
        },
        {
            "code": "other-code",
            "message": "OMG, very error!",
            "field": "This is the field"
        }
    ],
    "meta": {
        "status": "error"
    }
}

However I cannot work out how to parse the values from my controller into this Struct. For a basic Struct I understand and had something like this: e := models.ErrorMessage{"Error", "404", "Field Missing"}

How would use a line similar to the above but for the more complicated Struct?

icza
  • 389,944
  • 63
  • 907
  • 827
Elliot Reeve
  • 901
  • 4
  • 21
  • 39
  • 1
    You want to create a value of `ErrorMessage` in Go, or you want to parse a JSON text into a variable of type `ErrorMessage`? – icza May 14 '15 at 10:37
  • I want to create a value of ErrorMessage in Go which will basically then be rendered. `return c.RenderJson(e)` – Elliot Reeve May 14 '15 at 10:45

2 Answers2

0

If you separate the Error and Meta from inline structs into pre-defined struct types, it becomes pretty straightforward:

type Error struct {
     Code    string `json:"code"`
     Message string `json:"message"`
     Field   string `json:"field,omitempty"`
}

type Meta struct {
    Status string `json:"status"`
}

type ErrorMessage struct {
    Errors []Error `json:"errors"`
    Meta Meta `json:"meta"`
}

msg := ErrorMessage {
    Errors: []Error{
        {Code: "f00", Message: "bar", Field: "wat"},
    },
    Meta: Meta{"WAT"},
}
Not_a_Golfer
  • 47,012
  • 14
  • 126
  • 92
0

The problem here is that you use anonymous structs as types of the fields of ErrorMessage. E.g. the element type of ErrorMessage.Errors is an anonymous struct. The type of ErrorMessage.Meta is also an anonymous struct.

Unfortunately initializing variables with anonymous struct types requires you to duplicate the anonymous struct declaration, see this answer for examples and more details.

What I would suggest is to name your anonymous struct types like this:

type MyErr struct {
    Code    string `json:"code"`
    Message string `json:"message"`
    Field   string `json:"field,omitempty"`
}

type MyMeta struct {
    Status string `json:"status"`
}

type ErrorMessage struct {
    Errors []MyErr `json:"errors"`
    Meta   MyMeta  `json:"meta"`
}

And then your tasks becomes dead simple:

res := ErrorMessage{
    Errors: []MyErr{
        MyErr{
            Code:    "short-code",
            Message: "Wow, such bad!",
        },
        MyErr{
            Code:    "other-code",
            Message: "OMG, very error!",
            Field:   "This is the field",
        },
    },
    Meta: MyMeta{"error"},
}
data, err := json.MarshalIndent(&res, "", "  ")
if err != nil {
    panic(err)
}
fmt.Println(string(data))

This will produce exactly your desired output. Try it on the Go Playground.

Community
  • 1
  • 1
icza
  • 389,944
  • 63
  • 907
  • 827