@ama-team/optional
TypeScript icon, indicating that this package has built-in type declarations

0.1.3 • Public • Published

@ama-team/optional

npm CircleCI/master Coveralls/master Code Climate

This module contains small class which is inspired by Java Optional and was created to provide earier ways to work with possibly nulled/undefined values.

This library is heavily inspired by Optional from standard java library, but doesn't follow it precisely. If you need exact port, there is typescript-optional implementation.

Please note that this project follows semantic versioning approach and may change API in between pre-1.0 minor releases.

Installation

npm i -S @ama-team/optional

or

yarn add @ama-team/optional

Usage

30-second start

Optional is just a class that wraps possibly-null/undefined value and apply operations to it if it is present. For example, you have a response from API that optionally has a metadata field with a flag deeply buried inside the response:

user:
  id: 1
  ...
  metadata:
    processors:
      fraud:
        fraudulent: true

Instead of checking presence of the fields, you can take a shortcut:

import {Optional} from '@ama-team/optional'

const fraudulent = Optional
  .of(user)
  .map(user => user.processors)
  .map(processors => processors.fraud)
  .map(metadata => metadata.fraudulent)
  .orElse(false);

Bingo, now you either have true or false without too much hassle. I'll show how to work with pipelines like the one above later.

API

You have three ways to create an optional:

Optional.empty();
Optional.of(value); // throws error if value is null / undefined
Optional.ofNullable(value);

Optional has two properties and several methods to interact with current state:

optional.present; // boolean
optional.empty; // also boolean

// following methods returns Optional itself, allowing to chain methods
optional.ifPresent(identity => {});
optional.ifEmpty(() => {});
optional.peek(identity => {}); // will substitute missing identity with null
optional.on(identity => {}, () => {}); // will trigger one of those depending on identity presence 

You can also suggest a value for optional, which will be used as identity if optional is empty:

optional.rescue(value);
optional.rescueWith(() => value);

There are also several ways to retrieve identity or substitute it with value:

optional.get(); // will throw TypeError on missing entity
optional.orElse(value); // return identity or value
optional.orElseGet(() => value); // return identity or producer result
optional.orElseThrow(() => new Error()); // throw error using producer

And, finally, there are transformation methods:

// all those methods aren't mutating optional itself - transformations 
// will be applied eagerly to construct new optional
optional.map(identity => transform(identity));
optional.flatMap(identity => Optional.of(identity)); // unwraps returned optional
optional.filter(identity => true); // substitutes identity with null if filter doesn't return true

Pipelines

Optionals help with checking for null/undefined, but generally the example above bloats code as well, and usually should be placed otherwise. To do so, pipelines were introduced: encapsulated set of lazy operations over optional:

import {Pipeline} from '@ama-team/optional';

const extractor = Pipeline.create()
  .map(user => user.processors)
  .map(processors => processors.fraud)
  .map(metadata => metadata.fraudulent);

// ...

const fraudulent = extractor.apply(user).orElse(false);

Pipelines are very simple, and currently they provide two methods to process value:

  • .apply(value), which will return an Optional and will let you to use .orElse() or similar methods
  • .transform(value), which will in fact just a shortcut for .apply(value).orElse(null).

Also pipelines can be concatenated - you can use .append(pipeline) method for that, which will return you a new pipeline.

Contributing

Feel free to send PR to dev branch.

dev (next release) branch state

CircleCI/dev Coveralls/dev

Licensing

MIT License / AMA Team / 2018

Readme

Keywords

none

Package Sidebar

Install

npm i @ama-team/optional

Weekly Downloads

0

Version

0.1.3

License

MIT

Unpacked Size

16.9 kB

Total Files

14

Last publish

Collaborators

  • ama-master
  • ama-bot
  • etki