Reputation: 1185
I'm trying to use tidwall/sjson to modify properties in a json object, but getting the following error:
./prog.go:34:77: syntax error: unexpected {, expecting expression
Here's my code:
package main
import (
"fmt"
"github.com/tidwall/sjson"
)
func main() {
config := `{
"root": {
"obj1Arr": [
{
"obj2": {
"obj3Arr": [
{
"key1": "val1",
"key2": {
"val2": ["a", "b"]
}
},
{
"key3": "val3",
"key4": "val4"
}
]
}
}
]
},
"strExample": "bar",
"boolExample": true,
"floatExample": 12.54
}`
value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}[{"hello":"world"}])
fmt.Println(value)
}
You can reproduce the error with this go playground link. I'm trying to modify the object root.obj1Arr[0].obj2.obj3Arr
to simply have a single object inside of it. I'm also trying to work with an unstructured object. How can I fix this error?
Upvotes: 1
Views: 411
Reputation: 4515
A slice composite literal is created using {}
instead of []
e.g.
value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}{map[string]string{"hello":"world"}})
https://play.golang.org/p/1h07L5KNVTR
Note that you cannot create an anonymous object using composite literal syntax. I chose to use a map[string]string
in the example. If your types aren't that simple, or simply aren't known, you can use map[string]interface{}
e.g. map[string]interface{}{"my": map[string]interface{}{"nested": []string{"values", "are", "here"}}}
Upvotes: 2
Reputation: 7431
Your []interface{}[{"hello":"world"}]
is not valid Go expression as
[]type{...}
and not []type[...]
map[string]string{"hello": "world"}
So to modify obj3Arr
to be an array of map[string]string
the code should be something like:
value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []map[string]string{map[string]string{"hello":"world"}})
To work with objects where you don't know structure and types at compile time (as per "I'm also trying to work with an unstructured object" in your question) you will need empty interface{}
as type in map instead of string
: map[string]interface{}
. So that you can store various types in that map values:
value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}{
map[string]interface{}{
"hello": "world",
"key2": true,
"listkey": []int{1,2,3,4},
"mapkey": map[int][]bool{1: []bool{true, true, false}}},
})
will produce:
"obj3Arr": [{"hello":"world","key2":true,"listkey":[1,2,3,4],"mapkey":{"1":[true,true,false]}}]
Upvotes: 1
Reputation: 751
Based on the suggestions changing replacing []interface{}[{"hello":"world"}]
with []interface{}{map[string]string{"hello": "world"}}
package main
import (
"fmt"
"github.com/tidwall/sjson"
)
func main() {
config := `{
"root": {
"obj1Arr": [
{
"obj2": {
"obj3Arr": [
{
"key1": "val1",
"key2": {
"val2": ["a", "b"]
}
},
{
"key3": "val3",
"key4": "val4"
}
]
}
}
]
},
"strExample": "bar",
"boolExample": true,
"floatExample": 12.54
}`
value, _ := sjson.Set(config, "root.obj1Arr.0.obj2.obj3Arr", []interface{}{map[string]string{"hello": "world"}})
fmt.Println(value)
}
Output:
{
"root": {
"obj1Arr": [
{
"obj2": {
"obj3Arr": [{"hello":"world"}]
}
}
]
},
"strExample": "bar",
"boolExample": true,
"floatExample": 12.54
}
Upvotes: 1