For example, I have an account information that contains balance field (I fetch it from the server):
export class Account {
constructor(
// ...
public balance: number
) {
}
}
I also have two components in which I need this field. Actually, the question is: how can I retrieve this account in my components?
I have a few assumptions:
#1
Fetch an account information in each component:
// First Component
this.accountService.get().subscribe(...);
// Second Component
this.accountService.get().subscribe(...);
This is the worst solution since I send two requests to the server.
#2
Fetch an account information in the AppComponent and then pass it to the children as inputs.
This is closer to the truth, but how can I pass this data to the router outlet?
<!-- Is this even possible? -->
<router-outlet [account]="account"></router-outlet>
#3
Use NgRx. Perhaps the best solution. The problem is that I don't need NgRx for other manipulations (In my case, it creates more problems than it solves), so I don't want to download such a big library and store it in my bundle.
So, should I consider using NgRx or you can advise me better approach for this problem?
P.S. I also have WebSockets that send me a new balance. I have to manage this as well. This looks like this:
this.socket.fromEvent('new_balance').subscribe(...);
Please don't go for NgRx just for this. It's one of the most common mistakes people do. There are 'Angular' ways on how to deal with it.
#1
If you have a child - parent connection between your components. You can communicate in between them using @Input / @Output decorators.
export class AccountChild {
@Input() balance: number;
}
And then in parent component (component where you are calling AccountChild) you pass the balance like this:
<acconut-child [balance]="balance"></account-child>
#2
Another option would be to create a Subject out of your API response, and then you can subscribe to it from any other component.
export class AccountService {
public accounts: Subject<any> = new Subject();
constructor(
private http: HttpClient
) { }
fetchAccounts() {
return this.http.get(...).pipe(
map((result) => {
this.accounts.next(result);
}));
}
}
In order to call the API and load the subject with data you do this:
this.accountService.fetchAccounts().subscribe();
And now subscribe to that subject from component where you need that info.
this.accountService.accounts.subscribe((res) => console.log(res));
If you go for a way with subject and subscription it is important to unsubscribe manually from it when you are no longer using that component.
ngOnDestroy() {
this.accountService.accounts.unsubscribe();
}