TheRealFakeNews
TheRealFakeNews

Reputation: 8173

How to use ImmutableJS's reduce function with an Immutable accumulator?

I'm trying to use ImmutableJS's reduce function like so:

const myChanges = data
  .getIn(['a', 'b']) // Immutable.List
  .reduce((accum, data) => {
    // console.log('accum', accum);
    // console.log('data', data); <--- an Immutable.Map
    accum.push(List([ data.get('id'), data.get('time') ]));
    return accum;
  }, List());

However, accum always console logs as an empty Immutable.List. My guess is that it's because List() can't be mutated, so each time accum is returning a new empty Immutable.List().

What I would like to get is a list of lists, where each of the inner lists (essentially a tuple) consists of id and time.

How can I get this to work? Do I need to use withMutations?

Upvotes: 3

Views: 9391

Answers (2)

Thiniel P. Foti
Thiniel P. Foti

Reputation: 91

In immutable all data are 'readonly'. When you call the push method it returns a new object with the changes. For this code to work you need to return directly:

const myChanges = data.getIn(['a', 'b'])
    .reduce((accum, data) => {
        return accum.push(List([ data.get('id'), data.get('time') ]));
    }, List());

or you can store the result in a variable and return it

const myChanges = data.getIn(['a', 'b'])
    .reduce((accum, data) => {
        let result = accum.push(List([ data.get('id'), data.get('time') ]));
        return result;
    }, List());

Upvotes: 5

Bergi
Bergi

Reputation: 665090

Your problem is that you return the original accum, not the new value that includes the data. Remember that push returns a new list, unlike a mutable JS Array!

const myChanges = data
  .getIn(['a', 'b'])
  .reduce((accum, d) => {
    return accum.push(List([ d.get('id'), d.get('time') ]));
  }, List());

Upvotes: 0

Related Questions