6

I have started using https://mholt.github.io/json-to-go/ to turn API JSON into go structs and I really like it, however I am stuck on how to initialize the Filters array struct in the Report Definition struct shown below.

type ReportDefinition struct {
    ReportName string `json:"reportName"`
    ReportType string `json:"reportType"`
    Product    string `json:"product"`
    Email      string `json:"email"`
    CreatedBy  string `json:"createdBy"`
    Duration   struct {
        Duration  string      `json:"duration"`
        StartDate interface{} `json:"startDate"`
        EndDate   interface{} `json:"endDate"`
    } `json:"duration"`
    Filters []struct {
        Column struct {
            ColumnName string `json:"columnName"`
            Value      string `json:"value"`
        } `json:"column"`
        Operator string `json:"operator"`
    } `json:"filters"`
    SortBy            interface{}   `json:"sortBy"`
    ReportGroup       interface{}   `json:"reportGroup"`
    ReportOnHierarchy bool          `json:"reportOnHierarchy"`
    IsReportPreview   string        `json:"isReportPreview"`
    OutputRecordCount interface{}   `json:"outputRecordCount"`
    Schedule          interface{}   `json:"schedule"`
    Columns           []interface{} `json:"columns"`
}

I cannot seem to reference the items declared within the Filters struct or even the Filters struct in order to create a new Filter item and append it to Filters.

Is it possible to reference the Column struct with the ReportDefinition written as is? Or am I am doing something silly and I should just declare Filters outside of the ReportDefinition structure?

2
  • 3
    You should define the anonymous structs as separate types outside of ReportDefinition. Commented Mar 25, 2018 at 18:54
  • 1
    As Andy Schweig said, you should define your types like this: play.golang.org/p/RKOnM6QcaS5. In your version you cannot reference the "Column" struct because it's anonymous, you have there a Column field whose type is an anonymous struct, there is not Column type in your code. Commented Mar 25, 2018 at 19:30

1 Answer 1

5

Since the sliced type in the Filters field doesn't have a name, you have to repeat the definition when you want to initialize it:

package main

import "fmt"

type ReportDefinition struct {
    Filters []struct {
            Column struct {
                    ColumnName string `json:"columnName"`
                    Value      string `json:"value"`
            } `json:"column"`
            Operator string `json:"operator"`
    } `json:"filters"`
}

func main() {
    var rd ReportDefinition
    rd.Filters = append(rd.Filters, struct {
            Column struct {
                    ColumnName string `json:"columnName"`
                    Value      string `json:"value"`
            } `json:"column"`
            Operator string `json:"operator"`
    }{
            Column: struct {
                    ColumnName string `json:"columnName"`
                    Value      string `json:"value"`
            }{
                    ColumnName: "foo",
                    Value:      "bar",
            },
            Operator: "==",
    })

    fmt.Printf("+%v\n", rd)
}

It should be clear that this is very unconvenient, so you should just give your types names (at least those that you want to initialize):

package main

import "fmt"

type ReportDefinition struct {
    Filters []Filter `json:"filters"`
}

type Filter struct {
    Column   Column `json:"column"`
    Operator string `json:"operator"`
}

func NewFilter(col, op, val string) Filter {
    return Filter{
            Column: Column{
                    ColumnName: col,
                    Value:      val,
            },
            Operator: op,
    }
}

type Column struct {
    ColumnName string `json:"columnName"`
    Value      string `json:"value"`
}

func main() {
    var rd ReportDefinition
    rd.Filters = append(rd.Filters, NewFilter("foo", "==", "bar"))

    fmt.Printf("+%v\n", rd)
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.