Reputation: 1096
I have some concerns on which is the best method for passing my observed data from the template into an external Modal. The data will be shown in the template with the help of the async pipe. The subscribed data is needed in the template and in the modal aswell.
<ng-container *ngIf="possibleTokens$ | async as possibleTokens">
<!-- do some other things with possibleTokens -->
<button type="button" (click)="openEditModal(possibleTokens)">edit</button>
<button type="button" (click)="duplicateRow(row, possibleTokens)">duplicate</button>
<button type="button" (click)="openCreateModal(possibleTokens)">create</button>
</ng-container>
export class BadgeOverviewExample {
possibleTokens$ = this.getPossibleTokensFromServer();
openCreateModal(possibleTokens: string[]): void {
console.log('open create modal with following tokens:');
console.log(possibleTokens);
// const modal = modal.open(...);
// modal.possibleTokens = possibleTokens;
}
}
Due to the async pipe, I cannot access the data in the component's class directly. My only idea for passing the data into the modal is by passing the data from the template into all of the needed methods, too.
What is the preferred way for handling such cases?
Should I get rid of the async pipe in such cases and subscribe() in the component's class directly? Personally I don't want to use the subscribe() for fetching data, because the async-pipe should be the preferred way. But maybe it isn't for such a use case?
Should I pipe the Observable result into a private variable? I think that would conflict with the reactive way as well?
private _possibleTokens = [];
possibleTokens$ = this.getPossibleTokensFromServer()
.pipe(
tap(tokens => this._possibleTokens = tokens)
);
);
// and now use this._possibleTokens in the component's class and get rid of the method parameters.
openCreateModal(): void {
console.log('open create modal with following tokens:');
console.log(this._possibleTokens);
// const modal = modal.open(...);
// modal.possibleTokens = this._possibleTokens;
}
Should I keep my solution? But with more actions coming into the page, I will have to pass the variable for every single method, which needs it.
Here is a Stackblitz for it: https://stackblitz.com/edit/angular-duc6if-66yyed?file=src%2Fapp%2Fbadge-overview-example.ts,src%2Fapp%2Fbadge-overview-example.html
Upvotes: 0
Views: 972
Reputation: 551
You can combine operator shareReplay (for caching result) and firstValueFrom (to read data asynchronously inside ts code). In this case only one http call will be triggered, due to usage of shareReplay operator. So your code will look like this:
possibleTokens$ = this.getPossibleTokensFromServer().pipe(shareReplay())
async openCreateModal(): Promise<void> {
const tokens = await firstValueFrom(this.possibleTokens$);
// do something with data
}
Upvotes: 0