2

I am marshaling values into a struct from JSON. This is my struct:

type AutoGenerated struct {
    ID int64 `json:"id"`
    SuccessHTTPResponseCode int `json:"success_http_response_code"`
    MaxRetries int `json:"max_retries"`
    CallbackWebhookURL string `json:"callback_webhook_url"`
    Request struct {
        URL string `json:"url"`   (error occurs here)
        Method string `json:"method"`
        HTTPHeaders struct {
            ContentType string `json:"content-Type"`
            Accept string `json:"accept"`
        } `json:"http_headers"`
        Body struct {
            Foo string `json:"foo"`
        } `json:"body"`
    } `json:"request"`
}

Below is the function where I marshal it:

func createBSON() []byte {
      data1:= AutoGenerated{
      ID: 1462406556741,
      SuccessHTTPResponseCode: 200,
      MaxRetries: 3,
      CallbackWebhookURL: "http://requestb.in/vh61ztvh",
      Request: {
          URL: "http://requestb.in/vh61ztvh",
          Method: "POST",
          HTTPHeaders: {
              ContentType: "Application/json",
            Accept: "Application/json",
          },
          Body : {
              Foo: "bar",
          },
      },

}
    sample,err:=json.Marshal(data1)
    check(err)
    fmt.Print(sample)
    return sample
}

I made a couple of changes and the above is my updated function. I am getting the following error:

  missing type in composite literal

I am kind of new to Golang. I can't figure out what this error is. Any help would be appreciated.

RJP
  • 385
  • 5
  • 19
  • 1
    If a newbie to go, do [some reading](https://golang.org/doc/effective_go.html) and take the [Go Tour to learn how to code in Go](https://tour.golang.org/). – eduncan911 May 14 '16 at 05:34
  • I made some changes and updated the same. – RJP May 14 '16 at 05:47
  • Please see my edited answer. – Pandemonium May 14 '16 at 05:51
  • 3
    If you narrowed the problem down (by removing struct fields one at a time until you have a minimal problem), you'll find it's a dupe of this: http://stackoverflow.com/questions/26866879/initialize-nested-struct-definition-in-golang – Paul Hankin May 14 '16 at 05:58
  • This is a minimal repro for this problem: https://play.golang.org/p/tybBTTp5Vj – Paul Hankin May 14 '16 at 06:00

2 Answers2

3

When you use an anonymous struct like this:

type AutoGenerate struct {
        Request: struct {
                URL    string
                Method string
        }
}

This whole chunk is the type name

struct {
        URL string
        Method string
}

In another word, you'll have to initiate this way

data := AutoGenerate{
        Request: struct {
                URL    string
                Method string
        }{
                URL: "http://somedomain.com/",
                Method: "GET",
        },
}

Thus, in your case, it is better to separate each struct into a named one:

type Request struct {
         URL    string
         Method string
}

type AutoGenerate struct {
        Request Request
}

Please see https://play.golang.org/p/kZDN2yhlkz of the chaos it will become with anonymous structs.

Pandemonium
  • 7,724
  • 3
  • 32
  • 51
  • I did that. And i am still getting the exact same errors. – RJP May 14 '16 at 05:37
  • I already did this and updated my original post. It now shows a "missing type in composite literal" error. – RJP May 14 '16 at 05:53
  • Please be more specific with the error. Does it tells the line with problem? – Pandemonium May 14 '16 at 05:55
  • It occurs in the line in which i give the value for URL. – RJP May 14 '16 at 05:58
  • You code runs fine on my end without error. Are you sure in your code your `URL` type is string? "missing type in composite literal" error occurs when one does not specify the type in the literal construction which normally happens with slices, map, structs. – Pandemonium May 14 '16 at 06:01
  • @RJP Older versions of go required you to name the subtypes in literals. I'm guessing you are using go 1.4.something from your linux distro? – David Budworth May 14 '16 at 17:19
0

Okay, after referring to the links posted by Paul and PieOhPah this is how i created my struct :

type AutoGenerated struct {
    ID int64 `json:"id"`
    SuccessHTTPResponseCode int `json:"success_http_response_code"`
    MaxRetries int `json:"max_retries"`
    CallbackWebhookURL string `json:"callback_webhook_url"`
    Request `json:"request"`
}
type Request struct{
  URL string `json:"url"`
  Method string `json:"method"`
  HTTPHeaders `json:"http_headers"`
  Body `json:"body"`
}
type HTTPHeaders struct{
  ContentType string `json:"content-Type"`
  Accept string `json:"accept"`
}
type Body struct{
    Foo string `json:"foo"`
}

Here is the function in which I initialize and Marshal it:

func createBSON() []byte {
data1:= AutoGenerated{
    ID: 1462406556741,
    SuccessHTTPResponseCode: 200,
    MaxRetries: 3,
    CallbackWebhookURL: "http://requestb.in/vh61ztvh",
    Request: Request{
        URL: "http://requestb.in/vh61ztvh",
        Method: "POST",
        HTTPHeaders: HTTPHeaders {
            ContentType: "Application/json",
          Accept: "Application/json",
        },
        Body : Body {
            Foo: "bar",
        },
    },

}
    fmt.Print(data1)
    sample,err:=json.Marshal(data1)
    s := string(sample)
    fmt.Println(s)
    return sample
}

I posted this hoping this it will be useful for others who encounter deeply nested structs in Go.

RJP
  • 385
  • 5
  • 19