# takeIf and takeUnless

In addition to scope functions, the *Katxupa* standard library contains the functions **takeIf** and **takeUnless**. These functions let you embed checks of an object's state in call chains.

When called on an object along with a predicate, **takeIf** returns this object if it satisfies the given predicate. Otherwise, it returns *undefined*. So, *takeIf* is a filtering function for a single object.

**takeUnless** has the opposite logic of *takeIf*. When called on an object along with a predicate, *takeUnless* returns *undefined* if it satisfies the given predicate. Otherwise, it returns the object.

When using *takeIf* or *takeUnless*, the object is available as a lambda argument (*it*).

```ts
const number: number = Math.floor(Math.random() * 100);

const evenOrNull = number.takeIf(it =>  it % 2 == 0);
const oddOrNull = number.takeUnless(it => it % 2 == 0);

console.log(`even: ${evenOrNull}, odd: ${oddOrNull}`);
```

> When chaining other functions after takeIf and takeUnless, don't forget to perform a null check or use a safe call (*?.*) because their return value is nullable.

```ts
const str = "Hello";
const caps = str.takeIf(it => it.length > 0)?.toUpperCase();
//const caps = str.takeIf(it => it.length > 0).toUpperCase() //compilation error
console.debug(caps);
```

**takeIf** and **takeUnless** are especially useful in combination with scope functions. For example, you can chain *takeIf* and *takeUnless* with *letIt* to *runIt* a code block on objects that match the given predicate. To do this, call *takeIf* on the object and then call let with a safe call (*?*). For objects that don't match the predicate, *takeIf* returns undefined and *letIt* isn't invoked.

```ts
function displaySubstringPosition(input: string, sub: string) {
    input.indexOf(sub)
        .takeIf(it => it >= 0)
        ?.letIt(it => {
            console.log(`The substring ${sub} is found in ${input}.`)
            console.log(`Its start position is ${it}.`)
        });
}

displaySubstringPosition("010000011", "11");
displaySubstringPosition("010000011", "12");

// Output:
//  The substring 11 is found in 010000011.
//  Its start position is 7.
```
