0

I'm trying a replace a current NGRX implmentation of binding data in template to reusable component due to change in dataStructure of @Input.

HTML:
//replace
"<child [summary]="summaryTitle$ | async" ></child >"

//with
"<child  [summary]="summaryTitles" ></child>"
parent.comp.ts
//replace
summaryTitle$ = this.store.select(Title)

//with
summaryTitles = [{title:summaryTitle$ , text: "someConstantValue"},...]

Here I need to resolve the summaryTitles array before passing it to the <child>, any easy method to do so like using async pipe for single result.

the Idea is to re-use the existing <child> without making much changes and I wont able to add any changes to the @store as well

1 Answer 1

1

Edit: If text is never an observable:

const result$ = combineLatest(
  summaryTitles.map(({ title, text }) => 
    title.pipe(map(title => ({ title, text })));
  )
);

A minimal reproducible example with something like stackblitz would be good, it's a pain to reproduce ngrx state and all, but something like this should work:

import { of, map, combineLatest } from 'rxjs';

const summaryTitles = [
  { title: of('1'), text: of('2') },
  { title: of('3'), text: of('4') }
];

const result$ = combineLatest(
  summaryTitles.map(({title, text}) =>
    combineLatest([title, text]).pipe(
      map(([title, text]) => ({ title, text }))
    )
  )
);

result$.subscribe(console.log);

You may want to change combineLatest for forkJoin or zip. The doc's operator decision tree and learnrxjs.io are great for that.

Stackblitz: https://stackblitz.com/edit/rxjs-9gah4b?file=index.ts

Edit: If the text field may be an observable or not, use isObservable, for example:

const result$ = combineLatest(
  summaryTitles.map(({ title, text }) => {
    const text$ = isObservable(text) ? text : of(text);
    return combineLatest([title, text$]).pipe(
      map(([title, text]) => ({ title, text }))
    );
  })
);

But it may be easier to insure it's an observable somewhere else before that.

Side note: I noticed now in my stackblitz the final result, which shouold be an array, is an "indexed object" ({ 0: 'foo', 1: 'bar' }). When I try to manually transform it to an array in ways that work in terminal it remains an object 🤷. I'm assuming this is a quirk in stackblitz. Check what you get live.

Sign up to request clarification or add additional context in comments.

6 Comments

thanks for the solution , im actually trying to replicate above with forkJOin as you have suggested but it acceptes only observable i believe cause some time the value could be constantsconst summaryTitles = [ { title: of('1'), text: 2 }, { title: of('3'), text: 4 } ];
@HARIPRASAD I updated the response, please update the question. I assume you meant text could be an observable but could also not be? If it's never an observable it could be simplified
thnx a lot for all your scenarios !
considering one of the objects is nested in that case I can replace eg. text as { id: of('1'), desc: 'hello'} as well in above implementation as ``` const result$ = combineLatest( summaryTitles.map(({ title, text:{id,desc}) => combineLatest([title,{id}]).pipe(map(title => ({ title, text:{id,desc}}))); ) ); ``` - can this work for nested object like ``` summaryTitle = [{ title : obs1$ , text : {id : obs2$ , desc: 'hello'} } ] ``` or do i have to nest a level deeper with combineLatest ?
The stackblitz link you shared isn't working for me, but if I understood correctly the a title is an observable and text is an abject that also has an observable id field. In that case you'll need to combine my first and last answers: use the map pipe for the text field, and combineLatest that observable with:title: combineLatest(summaryTitles.map(({ title, text }) => combineLatest([title, text.id]).pipe(map(([title, id]) => ({ title, text: {...text, id }})))));
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.