# References to Nested Optional Resources

**URL:** <https://forum.flow.com/t/references-to-nested-optional-resources/2938>\
**Category:** 🏄🏻‍♀️ Cadence\
**Created:** [March 24, 2022, 12:23am UTC](https://forum.flow.com/t/references-to-nested-optional-resources/2938 "2022-03-24T00:23:29Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jacob](https://avatars.discourse-cdn.com/v4/letter/j/f1d935/32.png) [@jacob](https://forum.flow.com/u/jacob)\
**Post date:** [March 24, 2022, 12:23am UTC](https://forum.flow.com/t/references-to-nested-optional-resources/2938/1 "2022-03-24T00:23:30Z")

</div>

Nested optional resources are really tricky to get references to. For example:

```auto
pub resource Wrapper {
  pub var thing: @Thing?

  pub fun borrowThing(): &Thing {
    ...
  }
}

...

```

For some reason, Cadence doesn’t like you getting a reference to an optional nested resources. The weird part is that, in a normal NFT contract, `&self.ownedNFTs[id] as &NFT` isn’t a problem even though `self.ownedNFTs[id]` is in fact itself an optional type. Does anyone have any ideas of how to get a reference to a nested optional resource?

In terms of calling a function on the `@Thing?` resource, I know you can just do `self.thing?.method`, but getting a reference directly is more interesting to me.

---

<div class="post-metadata">

**Author:** ![bastian](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.flow.com/bastian/32/183_2.png) [@bastian](https://forum.flow.com/u/bastian)\
**Post date:** [March 24, 2022, 4:59am UTC](https://forum.flow.com/t/references-to-nested-optional-resources/2938/3 "2022-03-24T04:59:34Z")

</div>

That is a great question! There are two parts to the answer, one current/historic, and the upcoming improvement.

Indeed, currently there is special support for creating a reference to an element of a dictionary. Like you showed in your example, if `dict` is a dictionary, then `let ref = &dict[key] as &T` allows taking a reference to the element. If the element exists, uses of `ref` will succeed. If there is no element, i.e. the reference points to `nil`, then uses of `ref` will abort the program (!)

This turned out to be a bad design decision for multiple reasons:

- It only works for dictionary lookups specifically, not generally for any optional
- Uses of such a reference may be statically valid (i.e. they “type check”, there are no errors), but then fail at run-time

This is why [FLIP 722: Optional References to Indexed Accesses](https://github.com/onflow/flow/blob/master/flips/20211208-cadence-remove-optional-reference.md) improves the behavior:  
Now, when taking a reference to an optional, e.g. when indexing into a dictionary, or an optional field, the results is _an optional reference_. This change is already implemented in Cadence, but has not been released/deployed yet.

Independent of the current or future behavior, I would recommend handling the case where the field is nil, e.g. by returning an optional reference (`&Thing?`).

In an upcoming release the function thus would simply be:

```auto
fun borrowThing(): &Thing? {
    return &self.thing as &Thing?
}

```

If you want to keep failing the program when there is no thing / it is `nil`, you could force-unwrap or panic (which I don’t recommend, but up to you), e.g.

```auto
fun borrowThing(): &Thing {
    let ref = &self.thing as &Thing?
    return ref!
}

```

If you need to implement the function for current versions of Cadence (v0.21, v0.23), then there is still a way but it is more involved: You first have to move the thing out of the field, then take the reference to the non-optional thing, move the thing back to the field, and finally you can return the reference, like so:

```auto
fun borrowThing(): &Thing? {
    // Try to move the thing out of the field, and if there is any, 
    // set the field to nil and the variable `thing` to the thing
    if let thing <- self.thing <- nil {
        // `thing` has type `@Thing`, 
        // i.e. it is non-optional, so we can take a reference to it
        let ref = &thing as? &Thing
        // Move the thing back to the field. 
        // We know the field is empty (nil), so we can use force-move.
        self.thing <-! thing
        // Finally, return the ref, wrapped in an optional
        return ref
    }
    // There was no thing in the field, return nil
    return nil
}

```

Or again, if you do not want to return an optional you can also just panic, e.g:

```auto
fun borrowThing(): &Thing {
    // Try to move the thing out of the field, and if there is any, 
    // set the field to nil and the variable `thing` to the thing
    if let thing <- self.thing <- nil {
        // `thing` has type `@Thing`, 
        // i.e. it is non-optional, so we can take a reference to it
        let ref = &thing as? &Thing
        // Move the thing back to the field. 
        // We know the field is empty (nil), so we can use force-move.
        self.thing <-! thing
        // Finally, return the ref
        return ref
    }
    // There was no thing in the field
    panic("no thing!")
}

```
