Viper: Can I get an array of tables using TOML?

Created on 26 Jul 2016  路  3Comments  路  Source: spf13/viper

Here is an example config file in TOML:

[[user]]
name = "John"
nicknames = ["Johnny","Jim"]

[[user]]
name = "Kim"
nicknames = ["Kimmy"]

How can I get these values properly, so that I can iterate over them using something like a for x := range y statement, where y is a slice of users?

Most helpful comment

@krak3n

presets, ok := viper.Get("lights.presets").([]map[string]interface{})
if !ok {
    return nil, errors.New("incorrectly configured light presents")
}

The type assert always be false.

presets, ok := viper.Get("lights.presets").([]interface{}) // type assert to '[]interface{}'
if !ok {
    return nil, errors.New("incorrectly configured light presents")
}else{
    for _, table := range presets {
        if m, ok := table.(map[string]interface{}); ok { // type assert here
            fmt.Println(cast.ToInt(m["relay"])) // need cast, "github.com/spf13/cast"
        }
    }
}

This could be ok.

Another example:

[[lights]]
relay = 1
name = "Night"
[[lights]]
relay = 2
name = "Day"
[[lights]]
relay = 3
name = "Low Intensity"
[[lights]]
relay = 8
name = "Blackout"

Get lights directly.

presets, ok := viper.Get("lights").([]interface{})
if !ok {
    return nil, errors.New("incorrectly configured light presents")
}else{
    for _, table := range presets {
        if m, ok := table.(map[string]interface{}); ok { // type assert here
            fmt.Println(cast.ToInt(m["relay"])) // need cast, "github.com/spf13/cast"
            // cast 'name' too
        }
    }
}

All 3 comments

This isn't a support forum. Please confer with the docs, or, maybe try the http://discuss.gohugo.io/ forum (Hugo uses viper).

@bep tad harsh. I came here looking for the same thing since I couldn't see anything in the docs, I wouldn't think of going to hugo's support discuss for questions relating to this library.

Anyway, incase anyone comes here for this, given this example:

[lights]
address = "127.0.0.1"
[[lights.presets]]
relay = 1
name = "Night"
[[lights.presets]]
relay = 2
name = "Day"
[[lights.presets]]
relay = 3
name = "Low Intensity"
[[lights.presets]]
relay = 8
name = "Blackout"

You can access it with a type assertion on viper.Get since this returns an interface{}:

    presets, ok := viper.Get("lights.presets").([]map[string]interface{})
    if !ok {
        return nil, errors.New("incorrectly configured light presents")
    }

This will give you a slice of maps. The value of the map key is an interface{} so you'll need to type assert that as well to what you are expecting, like a slice of strings or what not.

@krak3n

presets, ok := viper.Get("lights.presets").([]map[string]interface{})
if !ok {
    return nil, errors.New("incorrectly configured light presents")
}

The type assert always be false.

presets, ok := viper.Get("lights.presets").([]interface{}) // type assert to '[]interface{}'
if !ok {
    return nil, errors.New("incorrectly configured light presents")
}else{
    for _, table := range presets {
        if m, ok := table.(map[string]interface{}); ok { // type assert here
            fmt.Println(cast.ToInt(m["relay"])) // need cast, "github.com/spf13/cast"
        }
    }
}

This could be ok.

Another example:

[[lights]]
relay = 1
name = "Night"
[[lights]]
relay = 2
name = "Day"
[[lights]]
relay = 3
name = "Low Intensity"
[[lights]]
relay = 8
name = "Blackout"

Get lights directly.

presets, ok := viper.Get("lights").([]interface{})
if !ok {
    return nil, errors.New("incorrectly configured light presents")
}else{
    for _, table := range presets {
        if m, ok := table.(map[string]interface{}); ok { // type assert here
            fmt.Println(cast.ToInt(m["relay"])) // need cast, "github.com/spf13/cast"
            // cast 'name' too
        }
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

noandrea picture noandrea  路  4Comments

aarondl picture aarondl  路  6Comments

Giri4joyz picture Giri4joyz  路  3Comments

xh3b4sd picture xh3b4sd  路  6Comments

jeffwillette picture jeffwillette  路  5Comments