Amio.io
Amio.io

Reputation: 21595

Update several properties

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}

Upvotes: 3

Views: 439

Answers (2)

Scott Sauyet
Scott Sauyet

Reputation: 50807

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)

Upvotes: 1

davidchambers
davidchambers

Reputation: 24856

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.

Upvotes: 2

Related Questions