Skip to content

Instantly share code, notes, and snippets.

@hrldcpr
Last active August 31, 2017 19:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hrldcpr/c17dcf39451d5a8867efbcdb804fefaf to your computer and use it in GitHub Desktop.
Save hrldcpr/c17dcf39451d5a8867efbcdb804fefaf to your computer and use it in GitHub Desktop.
exampda
// We have some state like:
const state1 = {
data: { some: 'stuff' },
people: ['blah', 'blah', 'blah'],
memberships: [
{ id: 1, roles: [], other: 'stuff' },
{ id: 2, roles: ['client'], more: 'junk' }
]
};
// We want to be able to add a role to a particular membership (without mutation):
import { append, evolve, map, propEq, when } from 'ramda';
const addRole = (id, role) => evolve({
memberships: map(when(propEq('id', id), evolve({ roles: append(role) })))
});
// For example:
addRole(2, 'admin')(state1)
// …returns a new object, in which `data`, `people`, and membership id 1 are all the exact same objects as before (not copies):
{
data: { some: 'stuff' },
people: ['blah', 'blah', 'blah'],
memberships: [
{ id: 1, roles: [], other: 'stuff' },
{ id: 2, roles: ['client', 'admin'], more: 'junk' }
]
}
@mrcoles
Copy link

mrcoles commented Aug 31, 2017

I was curious how to prevent adding 'admin' multiple times and came up with the following:

import { allPass, compose, not, contains, prop } from 'rambda'; // extra imports

const addRole = (id, role) => evolve({
  memberships: map(when(
    allPass([
      propEq('id', id),
      compose(not, contains(role), prop('roles'))
    ]),
    evolve({ roles: append(role) })
  ))
});

it gets a bit more funky with that… but still works!

also what about full-on currying addRole and maybe switching the role and id params?

import { curry } from 'rambda'; // extra imports

const addRole = curry((role, id, state) => evolve({
  memberships: map(when(
    allPass([
      propEq('id', id),
      compose(not, contains(role), prop('roles'))
    ]),
    evolve({ roles: append(role) })
  ))
}, state));

const addAdmin = addRole('admin');
addAdmin(2, state1);

I messed around with it in a codepen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment