# Conditions and Promises

Sometimes your asynchronous function calls another asynchronous function conditionally. Writing such code in an elegant way may take a bit of effort. Case in point: let's consider application logic, in which we cache response from an API call and therefore only make an API call if the information is stale or missing. An `if` statement where part of it is calling asynchronous logic and part is not can get messy. Let's see an example code where we try to untangle the complexity.

Note: this is an example code for demonstration purposes-only, it is missing trivial parts for brevity and is therefore not runnable as-is:

```javascript
const Promise     = require('bluebird');
const rp          = require('request-promise');
const fakepromise = require('fakepromise');

class SomeModel {

  constructor() {
    this.cachedEntity = {};
  }

  lookupValue() {
    let waitForRefresh;
    if (!this.isFresh()) {
      console.log("Rereshing entity...")
      waitForRefresh = this.refreshEntity();
    } else {
      console.log("Entity from cache...")
      // Fake wait, creates a fulfilled promise:
      waitForRefresh = Promise.resolve(this.cachedEntity);
    }

    return new Promise((resolve, reject) => {
      waitForRefresh.then((response) => {
        response = this.processResponse(response);
        this.cachedEntity = response; // refresh cache
        resolve(response);
      }).catch((err) => {
        reject(err);
      });
    })
  }

  isFresh() {
    if (!this.cachedEntity.lastFresh) {
      return false;
    }

    // or if older than 5 secs - consider not-fresh
    if ((Date.now() - this.cachedEntity.lastFresh) > 5000) {
      return false;
    }

    return true;
  }

  processResponse(response) {
    response.processed = true;
    return response;
  }

  refreshEntity() {
    const retValue = {};
    retValue.lastFresh = Date.now();
    retValue.value = Math.random() * 700; // 0 - 700
    return fakepromise.promise(200, retValue);
  }
}

let model = new SomeModel();
model.lookupValue().then(response1 => {
  console.log(response1);
  return model.lookupValue();
}).then(response2 => {
  console.log(response2)
});
```

> Side note: source files of all examples and instructions for how to execute, are located at: <https://github.com/inadarei/promises123-code>

In summary, by introducing a variable that is assigned to the sub-call invoking a promise and turning non-async part of the `if` logic into a fake promise, we can make code look uniform and clean. Which is what you see in the implementation of lookupValue() function. The refreshEntity() function implementation is not directly related to the trick we are explaining, but is included here to bring more clarity to the context of the discussion.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.promises123.com/conditions-and-promises.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
