# Async & Await

This document is a quick introduction to using the `async` and `await` syntactic sugar in CloudCode tasks and in TypeScript apps.

{% hint style="info" %}
`async` and `await` works in CloudCode tasks (both JS and TS) and TypeScript apps. It does not work in the app logic for JavaScript apps.
{% endhint %}

{% hint style="success" %}
Start with [this interactive introduction to `async` & `await`](https://runkit.com/rkistner/short-introduction-to-async-await-with-fetch) if you are not familiar with the syntax at all.
{% endhint %}

#### Introduction to async and await usage

In JourneyApps many operations are asynchronous. We use `async` & `await` to handle this.

In CloudCode, your main `run` function should always be `async`:

```javascript
export async function run() {
// Code here
}
```

Generally, database operations that query the backend are asynchronous, and needs `await`:

```javascript
export async function run() {
    var user = await DB.user.first();
    console.log('name:', user.name);
    // This doesn't hit the database yet, so does not need `await`
    var assignment = DB.assignment.create();
    assignment.user(user);
    await assignment.save();
}
```

Fetch calls are also asynchronous and therefore require an `await`:

```javascript
export async function run() {
    var response = await fetch("http://api.open-notify.org/iss-now.json");
    if(!response.ok) {
        throw new Error('Request failed: ' + response.statusText);
    }
    var body = await response.json();
    return body.iss_position;
}
```

If you define an `async` function, you also need to `await` on its response:

```javascript
async function getLocation() {
    var response = await fetch("http://api.open-notify.org/iss-now.json");
    if(!response.ok) {
        throw new Error('Request failed: ' + response.statusText);
    }
    var body = await response.json();
        return body.iss_position;
    }
    
    export async function run() {
    var location = await getLocation();
    return {location: location};
}
```

Notable `async` operations:

```
someModel.first()

someQuery.toArray()
someQuery.first()
someQuery.destroyAll()
someQuery.count()

someDbObject.save()
someDbObject.destroy()
someDbObject.reload()
```

Getting `belongs-to` relationships are also `async`. If a chain of `belongs-to` lookups are performed, each one requires an `await`. For readable code, it is recommended to do each `belongs-to` lookup on a separate line. For example:

```javascript
// Works, but not readable
let clientName = (await (await user.assignment()).client()).name;

// More readable
let assignment = await user.assignment();
let client = await assignment.client();
let clientName = client.name;
```

`for` loops require specific attention: `someArray.forEach` does not wait for `async` functions to complete, so it is recommend to use a `for...of` loop instead:

```javascript
var objects = await DB.myobject.all().toArray();
for(let object of objects) {
    // ...
}
```

For example:

```javascript
export async function run() {
// Task to recalculate the totals for all invoices
  var invoices = await DB.invoices.all().toArray();
  for(let invoice of invoices) {
    var line_items = await invoice.line_items.toArray();
    var total = 0;
    for(let line_item of line_items) {
      var product = await line_item.product();
      var price = product.price * line_item.quantity;
      total += price;
    }
    invoice.total = total;
    await invoice.save();
  }
}
```
