# ifElse

```erlang
ifElse :: (Function predicate, Function ifTrue, Function, ifFalse)
    => (a, b, ..., z) => Any | Promise<Any> output
```

## description

Accepts a predicate function, an ifTrue & an ifFalse branch functions, and returns a function which will pass all the arguments it receives to the `ifTrue` branch function if the predicate evaluates to a truthy value, or to the `ifFalse` branch function.

If the predicate is an *asynchronous* function, the returned function will return a `Promise` , allowing to use `Promise.prototype.then` or the `await` keyword to wait until it's resolved.

## examples

### basic example

```javascript
import { ifElse } from 'conductor'

const isEven = x => x % 2 === 0
const double = x => 2 * x
const add1 = x => 1 + x

ifElse(isEven, double, add1)(2) // 4
ifElse(isEven, double, add1)(1) // 2
```

Here, we want wrote a function that doubles an input value if it's even, or simply add one if it's odd.

### passing more than one argument

```javascript
import { ifElse } from 'conductor'

const hasProp = (key, object) =>
  Object.prototype.hasOwnProperty.call(object, key)
const returnAsIs = (_, object) => object
const addProp = (key, object, value) => {
  object[key] = value
  return object
}
const insertOnce = ifElse(hasProp, returnAsIs, addProp)

insertOnce('role', {}, 'drummer') // { role: 'drummer' }
insertOnce('role', { role: 'drummer' }, 'guitarist') // { role: 'drummer' }
```

We want to build an `insertOnce` function which adds a property (a key & a value) to an object, but only if the property does not already exist on the object.

* The `hasProp` function is our predicate, and will check if a property exists on an object.
* The `returnAsIs` is our `ifTrue` branch and will simply return the object as is.
* `addProp` is our `ifFalse` branch function and will add a property to the object

These functions do not need the same arguments but remember that `ifElse`'s resulting function will pass *all* the arguments it receives to the `predicate`, `ifTrue` & `ifFalse` functions, so as long as these functions expect their arguments in the same order, it won't be a problem.

In the first call to `insertOnce`, the object is empty, so the `role` property is added.

In the second call, the object already has a `role` property, so its value is **not** overridden.

### using an asynchronous predicate function

```javascript
import { ifElse } from 'conductor'

const isEven = async x => x % 2 === 0
const double = x => 2 * x
const add1 = x => 1 + x

ifElse(isEven, double, add1)(3) // Promise<pending>
await ifElse(isEven, double, add1)(3) // 4
```

Here our `isEven` predicate is an asynchronous function. If we call `ifElse` without waiting for the returned `Promise` to be resolved, we simply get the pending `Promise`. So we need to use the `await` keyword (or `Promise.prototype.then`) to wait for the `Promise` to be resolved.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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://conductor.js.org/api-reference/ifelse.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.
