Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update several properties

Tags:

ramda.js

In ramda how can I update several properties at once? The closest I could get was using R.evolve(). evolve wants me to modify a property using a transformation function. I would like to do it directly. However, R.assoc() lets me modify only one property at a time and I have to specify the property using a string.

This is how I do it now with evolve:

const STATE_INITIAL = {
    isDisabled: true,
    isLoading: false
};

R.evolve({
    isDisabled: R.not, 
    isLoading: () => true // I don't want to set a value using a function
    }, state)

In JS I would the object-spread operator and I would receive a new object:

{ ...state, isDisabled: !state.isDisabled, isLoading: true}
like image 606
Amio.io Avatar asked Sep 29 '26 05:09

Amio.io


2 Answers

One option is to use lenses:

const isDisabled = R.lensProp('isDisabled');
const isLoading = R.lensProp('isLoading');

//    toggle :: State -> State
const toggle = R.pipe(
  R.over(isDisabled, R.not),
  R.set(isLoading, true)
);

toggle({isDisabled: true, isLoading: false});
// => {isDisabled: false, isLoading: true}

See R.lensProp, R.over, and R.set.

like image 145
davidchambers Avatar answered Oct 01 '26 19:10

davidchambers


Ramda tries to keep things simple, so there's not likely a good technique that would allow you to use a function for one property and a value for another, except by piping them through as David Chambers suggests. His, version, which can also be written like this:

const toggle = R.pipe(
  R.over(R.lensProp('isDisabled'), R.not),
  R.set(R.lensProp('isLoading'), true)
)

is certainly somewhat more verbose than

const toggle = state => {
  ...state,
  isDisabled: !state.isDisabled, 
  isLoading: true    
}

But it doesn't seem that bad. However, if your objection to using functions for both properties is not too strong, there's a variant of your original version with evolve that's pretty simple:

const toggle = R.evolve({
  isDisabled: R.not, 
  isLoading: R.T
})

R.T is simply shorthand for R.always(true)

like image 45
Scott Sauyet Avatar answered Oct 01 '26 18:10

Scott Sauyet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!