A do notation syntax allows writing code in a more declarative style, similar to the do notation in other programming languages. It provides a way to define variables and perform operations on them using functions like bind and let, piping the returned values into a context object.
Initiates a Do-notation with the current OptionAsync, binding it to a context object with the provided key.
bind
Binds an OptionAsync to the context object in a Do-notation.
If the OptionAsync resolves to Some, the value is assigned to the key in the context object. If the OptionAsync resolves to None, the parent OptionAsync running the Do simulation becomes a None.
let
Ensure you know what you're doing when binding a promise using let, otherwise a thrown exception will not be caught and break your app
Binds a non-rejecting promise to the context object in a do notation.
If the promise resolves to a non-nullable value, the value is assigned to the key in the context object. If the promise resolves to null or undefined, the parent OptionAsync running the Do simulation becomes a None.
Understanding the do notation
Do notation provides a clean way to handle sequences of operations that might fail, where each step depends on the success of all previous steps. Think of it as a chain of dominoes - if any domino falls incorrectly (resolves to Option.None), the entire sequence stops.
import { OptionAsync } from 'funkcia';
declare function findUser(id: string): OptionAsync<User>;
declare function getUserPermissions(user: User): OptionAsync<Permissions>;
declare function checkAccess(permissions: Permissions, resource: string): OptionAsync<Access>;
const access = OptionAsync.Do
// First, try to find the user
.bind('user', () => findUser('user_123'))
// If user is found, get their permissions
.bind('permissions', (ctx) => getUserPermissions(ctx.user))
// If all steps succeed, we can use the accumulated context to check access to specific resource
.andThen((ctx) => checkAccess(ctx.permissions, 'api-key'));
import { OptionAsync } from 'funkcia';
declare function findUser(id: string): OptionAsync<User>;
declare function getUserPermissions(user: User): OptionAsync<Permissions>;
declare function checkAccess(permissions: Permissions, resource: string): OptionAsync<Access>;
const access = findUser('user_123')
.andThen(user =>
getUserPermissions(user)
.andThen(permissions =>
checkAccess(permissions, 'api-key')
)
);
import { OptionAsync } from 'funkcia';
declare function findUser(id: string): OptionAsync<User>;
declare function getUserPermissions(user: User): OptionAsync<Permissions>;
declare function checkAccess(permissions: Permissions, resource: string): OptionAsync<Access>;
const user = findUser('user_123');
const permissions = user.andThen(getUserPermissions);
const access = permissions.andThen(permissions => {
return checkAccess(permissions, 'admin-panel');
});