harpal
harpal

Reputation: 476

Map behavioursubject and assign it to same variable after mapping rxjs

I have a scenario, my child component takes BehaviourSubject as Input and that(child) subscribes it internally. I need to filter/map on BehaviourSubject in the parent, so that when somewhere next() is called then child subscription receives map/filtered values.

export class ParentComponent {
    public myBSubject: BehaviorSubject<ListFilter[]> = new BehaviorSubject<ListFilter[]>(undefined);
    public ngOnInit(): void {
        this.myBSubject = this.myBSubject.pipe(
          map((filters): ListFilter[] => {
            // Do some manipulation with filters
          return filters;
        }));
    }
}

tempalate

<child [myBSubject]="myBSubject"> </child>

ChildComponent (I have no control on it.)

export class ChildComponent {
 @Input()
  public myBSubject: BehaviorSubject<ListFilter[]> = new BehaviorSubject<ListFilter[]>(undefined);
  
  // somewhere subscription of myBSubject

}

the problem is the .pipe(map) converting BehaviourSubject to Observable, which is not assignable. and without assigning map callback not called because immutable map.

by making .pipe(map..) as BehaviourSubject<ListFilter> working fine but i'm feeling its not a good solution. Please help me to achieve this in a better way, Thank you.

Upvotes: 1

Views: 1166

Answers (1)

Karel
Karel

Reputation: 119

Please have a look at this answer to a similar question.

Besides the 2 options described there (using an input property setter or implementing OnChanges), I believe there is a third one which might suit your needs, given that the data for your BehaviorSubject comes from another observable.

In your parent component, update the value of the BehaviorSubject in the subscription body of this first observable. Then in the template of the parent component, pass the BehaviorSubject through the async pipe and use that as input for the child component.

Parent component:

export class ParentComponent {
    public myBSubject: BehaviorSubject<ListFilter[]> = new BehaviorSubject<ListFilter[]>(undefined);
    public ngOnInit(): void {
        this.firstObservable.pipe(
          map(value => // map to ListFilter array here)
        ).subscribe(result => this.myBSubject.next(result));
    }
}

Template:

<child [myBSubject]="myBSubject | async"> </child>

Upvotes: 1

Related Questions