# Async

Scopes also work across asynchronous calls in that a method called asynchronously can call the \`use' method to access values from the Scope.

```dart
final keyAge = ScopeKey<int>('age');

final one = await (Scope()
    ..value<int>(keyAge, 18))
    .run<Future<int>>(() async {
        /// setup up a 1 second delay and call `use` within
        /// a future.
        final delayedvalue =
            Future<int>.delayed(const Duration(seconds: 1), () => use(keyAge));
        return delayedvalue;
    });

expect(one, equals(18));
```

The Future MUST also be created within the Scope.

{% hint style="info" %}
Just because a method runs concurrently to a Scope does not mean the method has access to the Scope.
{% endhint %}

Just because another async method runs during the scope's existence does not mean it has access to the Scope. It must be called from a method within the Scope's call stack.

e.g.

Scope -> run -> a -> b -> c

Where -> means calls; a, b and c have access to the the Scope.

main -> d -> f -> c

Even if these methods are run asynchronously whilst the Scope exists they will not have access to the Scope as they were not called from the Scope's `run` method.

## Calling async methods

You will often need the Scope's `run` method to make async calls and have the call wait until the run completes.

This is simple to do:

```dart
  /// May sync call
  Scope()
    ..value<bool>(tenatId, 10)
    ..value<bool>(bypassTenantKey, true)
    ..run(()  {
      action();
    });
    
  /// Make async call.
  await (Scope()
    ..value<bool>(tenatId, 10)
    ..value<bool>(bypassTenantKey, true)
     )
     .run(() async {
    await action();
  });
```

There are **five** key changes required to make the async call:

* add an await before the call to Scope()
* add async after the \`run(()\`&#x20;
* wrap the Scope and value builder calls in parenthesis
* change `..run` to `.run`
* ``add `await` before the call to action``

Its critical that you note step 3.&#x20;

The `..run` notation tells dart to call `run` but still return `Scope`.  It is the `run` method that is async so we need to ensure that the result of the expression is the result of run not a Scope.
