0

I have a doubt about Subject. I'm using an Observable in parent component and I'm passing it to child component through the decorator Input.

In child component, I get that stream and apply a next() for the parent component receives the data which is coming from child component.

Child Component:

@Input() test = new Subject<any>();

private sendDataToParent(data:any): void {
this.test.next(data);
}

Parent Component:

test = new Subject<any>();

ngOnInit() {

this.test.subscribe(console.log)

}

In that case, I'm using an Input Decorator as Outuput Decorator. There is a better way to connect to component through an Subject?

That way I applied Which problems I can find with it?

1 Answer 1

2

Angular is built to pass data to children components via properties (input) and send back to parents with events (output).

In your scenario I can't see nay reason to not pass data to the parent in an @Output property:

@Output() test = new EventEmitter<any>();
private sendDataToParent(data:any): void {
    this.test.emit(data);
}

<app-child (test)="parentMethod($event)></app-child>

If you need to expand your knowledge about this topic you should read this documentation: https://angular.io/guide/component-interaction

Anyway, sometimes you need the same data across multiple components, multiple parents or children, and you can use Observables to manage this, but you should create a service to be injected in all that components.

@Injectable()
export class MyDataService {
    private dataSubject$: BehaviorSubject<MyData> = new BehaviorSubject<MyData>(null);

    getData$(): Observable<MyData> {
        return this.dataSubject$;
    }

    changeData(data: MyData) {
        this.dataSubject$.next(data);
    }
}

And your components can subscribe to that service:

export class MyComponent implements OnInit {
    public data$: Observable<MyData>;

    constructor(private dataService: MyDataService) {
        this.data$ = this.dataService.getData$();
    }

    ngOnInit() {}

    changeData(data: MyData) {
        this.dataService.changeData(data);
    }
}

You can use data$ in your html with async pipe, or if you prefer you can subscribe manually in code, but don't forget to unsubscribe inside ngOnDestroy, this could be a way to do it:

export class MyComponent implements OnInit, OnDestroy {
    private destroy$ = new BehaviorSubject<boolean>(false);

    constructor(private dataService: MyDataService) {}

    ngOnInit() {
        this.dataService.getData$()
            .pipe(takeUntil(this.detroy$))
            .subscribe(data => {
                // do x
            });
    }

    ngOnDestroy() {
        this.destroy$.next(true);
        this.destroy$.unsubscribe();
    }

    changeData(data: MyData) {
        this.dataService.changeData(data);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

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.