A label and a table with multiple rows on the same page. Label keeps sum of values from table.
Component 1
Sum total = 45
Component 2 (a table)
filterBy: [none]
- Value 2
- Value 42
- Value 1
You see component 1 depends on 2. Problem is the table in Component 2 has a filter input field. When you filter and press Enter it does an API call. The list returned might be different because from another part of our app a new Value was added.
Component 1
Sum total = 45 (Problem: same value after filter)
Component 2 (a table)
filterBy: smth
- Value 2
- Value 42
- Value 1
- Value 5
- Value 1
And the sum total is not up-to-date.
(!!) In my app, you cannot compute or deduce the Sum total from the table of Values. Its just an example.
I have thought to use one Get() call for label and for table. One get fetching Value and Sum total at the same time. But they act as one component with one API call and the HTMLs cannot be reused. Final thoughts were to have: Parent X-> Component 1, Component 2
Where Parent X does the one call for Sum and Values and sends through Input() to each component data for label and for table.This way the htmls are reusables and that one call solves the filter update problem.
Question I had a big brainstorm thinking also about using SignalR and any other solution. This looks like a very common scenario, so I want to ask. What solution would you use?
CodePudding user response:
Assuming you have your components set up in a parent child fashion with app-selectors, you can use an output event from component 2 to tell component 1 about the new total.
EG:
<component1>
<component2 (totalChange)="totalChanged($event)"></component2>
</component1>
In the child component you need to declare an output event emitter:
@Output()
totalChanged: EventEmitter<number> = new EventEmitter<number>();
Then after your api call in component 2, when you get new data, emit the new total value:
// make API call and get new data
// emit event with new total of data
this.totalChanged.emit(newTotal);
Then in component1 you can add a function called 'totalChanged':
public totalChanged(total: number){
this.total = total;
}
CodePudding user response:
There're two cases:
parent-child relationship
if component-1
is parent and component-2
is its child, then you can use Outupt
decorator to define an EventEmitter
which will be emitted once filter function is called, results are fetched and sum is calculated.
@Output() filterUsed = new EventEmitter<number>();
filter(input) {
....
this.sum = ....;
this.filterUsed.emit(this.sum);
}
then in the parent component-1
use an Event-Binding
in the tag of the component-2
<app-component-2 (filterUsed)="getNewSum($event)"></app-component-2>
and inside getNewSum(sum)
function, update the value of the sum in the parent component;
not-related components
if component-1
and component-2
are not related, then you can add a middleware service that will be injected in both components.
this service must contain an observable that will be used by component-2
(next) to carry a new value of sum for the component-1
(subscribe).