Simon Baars
Simon Baars

Reputation: 2319

Transform JavaScript object in RxJS pipe

I currently have the following piece of logic in typescript:

something.pipe(
  take(1),
  withLatestFrom(
    this.a$,
    this.b$
  ),
  tap(([, a, b]) => {
    const obj = {};
    a.forEach(
      x =>
        (obj[x.myKey.a] = x.myValue.map(record -> {
                      ...record,
                      quantity: 0,
                    }))
    );
    doSomething(object, b);
  })
);

This code works, but is quite verbose considering what it tries to achieve. I've been looking for a way to simplify the logic by better using RxJS operators, but can't figure out how. The main thing I'd like to improve is the part where I first create an empty JavaScript object (called obj) and then assign its values in a forEach. I've been looking into simplifying this logic using something that merges several JavaScript objects (mergeMap?):

const obj = a.mergeMap(x => {x.myKey.a: x.myValue.map(record -> {
                      ...record,
                      quantity: 0,
                    })});

Of course, the code in above snippet is not valid, since mergeMap must be used in the surrounding pipe, but I can't figure out how to. Can someone point me in the right direction?

Upvotes: 0

Views: 511

Answers (2)

Mrk Sef
Mrk Sef

Reputation: 8062

As mentioned already, reduce is generally a good way of turning an array into a single value (be that a number, boolean, or object).

This should do it.

You'll notice some extra brackets. They're necessary, since curly braces denote both object literals as well as a block of code. Wrapping an object literal in braces removes that ambiguity.

const obj = a.reduce(
  (acc, curr) => ({
    ...acc,
    [curr.myKey.a]: curr.myValue.map(record => ({
      ...record,
      quantity: 0,
    }))
  }), 
  {}
);

Upvotes: 1

Simon Baars
Simon Baars

Reputation: 2319

According to T. van den Berg's hint to use reduce, I simplified it to the following:

const obj = a.reduce((acc, x) => {acc[x.myKey.a] = x.myValue.map(record -> {
                      ...record,
                      quantity: 0,
                    };
                    return acc;
                  }), {});

Upvotes: 0

Related Questions