Reputation: 57
I have a struct that includes an array of another struct, eg
type Struct1 struct {
Value string
Items []Struct2
}
type Struct2 struct {
Value string
}
I am using gorilla schema to decode my Form values into Struct 1. The values for the embedded struct, Struct 2, are not coming through.
When I look at the logs for the FormValue("Struct2") it returns '[Object object], [Object object]'
Any help would be greatly appreciated
EDIT An example of the structure of the form,
Using AngularJS,
var data = $scope.struct1;
$http({
method: 'POST',
url:url,
data : data,
headers : {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
}
})
.then(function successCallback(response) {
console.log(response);
}, function errorCallback(response) {
});
Upvotes: 1
Views: 1934
Reputation: 4431
It's possible that you don't have the right struct design for your HTML form. You might want to post your input and/or your HTML form design.
gorilla/schema
's decode
expects the values input to be passed as a variable of type map[string][]string
, as you can see both from the example in the documentation and from the test files in the package. Here's a simple complete script that just wraps the example from the documentation and prints the result:
package main
import(
"fmt"
"github.com/gorilla/schema"
)
type Person struct {
Name string
Phone string
}
func main() {
values := map[string][]string{
"Name": {"John"},
"Phone": {"999-999-999"},
}
person := new(Person)
decoder := schema.NewDecoder()
decoder.Decode(person, values)
fmt.Printf("Person: %v\n", person)
}
That outputs Person: &{John 999-999-999}
.
That is the correct form for a map literal of type map[string][]string
, as you can demonstrate by performing a declaration followed by an assignment and running it without error:
var values map[string][]string
values = map[string][]string{
"Name": {"John"},
"Phone": {"999-999-999"},
}
Now map[string][]string
doesn't obviously support all the types that gorilla/schema supports, such as the type in your question: slices of structs. But the HTML form is processed such that a translation makes sense: it keeps appending indices and field names with dot separators to create the desired structure. So for the types you posted in your question, I wrote this script to decode values into the structs:
package main
import(
"fmt"
"github.com/gorilla/schema"
)
type Struct1 struct {
Value string
Items []Struct2
}
type Struct2 struct {
Value string
}
func main() {
values := map[string][]string{
"Value": {"the thing with the items"},
"Items.0.Value": {"a"},
"Items.1.Value": {"b"},
"Items.2.Value": {"c"},
}
s1 := new(Struct1)
decoder := schema.NewDecoder()
decoder.Decode(s1, values)
fmt.Printf("S1: %v\n", s1)
}
Running that outputs:
S1: &{the thing with the items [{a} {b} {c}]}
That demonstrates that decode can populate your struct design without error, if its input matches that design.
So you might try to verify that your input matches that scheme -- that it has those array-like indices and field names with the dot separator in a way that conforms to your struct design. And if it does not, that indicates that your struct design needs to be updated to fit the format of your input.
You can see examples of decode working on this type of structure in the decode_test.go file in the gorilla/schema package, such as these lines:
type Foo struct {
F01 int
F02 Bar
Bif []Baz
}
type Bar struct {
F01 string
F02 string
F03 string
F14 string
S05 string
Str string
}
type Baz struct {
F99 []string
}
func TestSimpleExample(t *testing.T) {
data := map[string][]string{
"F01": {"1"},
"F02.F01": {"S1"},
"F02.F02": {"S2"},
"F02.F03": {"S3"},
"F02.F14": {"S4"},
"F02.S05": {"S5"},
"F02.Str": {"Str"},
"Bif.0.F99": {"A", "B", "C"},
}
The Foo
struct has a field named Bif
of type []Baz
. Baz
is a struct -- so we have a slice of structs type, like in your question. Baz
has a field named F99
. You can see that the input is referenced with the string value "Bif.0.F99"
.
Use this and other examples in the test file as your guide.
Upvotes: 1