FAQ: Can we use nested dictionaries in Cadence?

I was trying to use something like this:

pub contract Test {
    pub let retired: {UInt32: {UInt32: Bool}}

    init() {
        self.retired = {}
    }

    pub fun retire(playerID: UInt32, series: UInt32) {
        self.retired[playerID][series] = true
    }
}

but I’m getting this error; “cannot index into value which have type {UInt32: Bool}?”.
Am I missing something?

Nested dictionaries are supported in Cadence.

The error message here points to the fact that the lookup of key playerID in dictionary retired might fail, i.e. there might be a case where there is no value for a given key. In that case, the lookup results in nil. Dictionary lookups in Cadence return an optional, the “not existing” case must be handled explicitly.

For this particular example, it is probably a good idea to create an empty nested dictionary when it does not exists:

pub fun retire(playerID: UInt32, series: UInt32) {
    let nested = self.retired[playerID] ?? {}
    nested[series] = true
    self.retired[playerID] = nested
}

Basically, first get the nested dictionary – if it does not exist, create an empty one.
Second, set the value in the nested dictionary.
Finally, insert the updated nested dictionary in the outer dictionary.