Reputation: 123
Please give me some ideas of workaround for my app! I am trying to switch dynamicly template in my component but have odd behavior. Thanks! Here is stackblitz
What I want basically: I want to recieve async data (node) from service in my alert component, and show this data (node) in my #initTemplate, then I want to take id of this data (node), send request with this id and get another data (styles) which I want to display in my #stylesTemplate. Both templates are in my alert component.
What's my problem? I realized desired behavior of my component, but this is not exactly what I need... What I am doing: 1. Click on "pushData" button 2. Look at my alert component 3. Click on change template button (!! component disappears !!) 4. Click on "pushData" again 5. Look at my component with changed template
I need to switch component's template without it's disappearing.
Here is my simplified alert component (see also at stackblitz working sample)
class AlertComponent implements OnInit, OnDestroy {
private subscription: Subscription;
message: any;
node$: Observable<{}>;
styles$: Observable<{}>;
constructor(private dataService: DataService) { }
activeInit: boolean = true;
ngOnInit() {
this.node$ = this.dataService.getAsyncData().pipe(share());
this.styles$ = this.node$.pipe(
mergeMap(node => {
if(!!node) {
// I need node here, because getSecondAsyncData send request with this data
return this.dataService.getSecondAsyncData(node);
}
else return of(null);
}));
}
ngOnDestroy() {
}
openSecond() {
this.activeInit = false;
}
openFirst() {
this.activeInit = true;
}
close() {
this.dataService.sendNodeToSubscribe(null);
}
And here is my html with both templates:
<ng-container *ngTemplateOutlet="activeInit ? initTemplate : stylesTemplate"></ng-container>
<ng-template #initTemplate>
<div class="card left-settings position-fixed" *ngIf="(node$ | async) as node;">
<div class="row justify-content-end mx-0">
<div class="col-0">
<button type="button" class="btn btn-block btn-ghost-light p-1 px-2" (click)="close()">Close</button>
</div>
</div>
<div class="row custom-width">
<div class="col-lg-12">
<button (click)="openSecond()">switch second template</button>
</div>
</div>
</div>
</ng-template>
<ng-template #stylesTemplate>
<div class="card left-settings position-fixed" *ngIf="(styles$ | async) as styles;">
<div class="row justify-content-end mx-0">
<div class="col-0">
<button type="button" class="btn btn-block btn-ghost-light p-1 px-2" (click)="close()">
Close
</button>
</div>
</div>
<div class="row custom-width">
<label>{{styles.isIcon}}</label>
<label>{{styles.radius}}</label>
<button (click)="openFirst()">switch first template</button>
</div>
</div>
</ng-template>
Thank you !!
Upvotes: 6
Views: 854
Reputation: 4145
You just have to replace below code,
use BehaviorSubject : A BehaviorSubject holds one value. When it is subscribed it emits the value immediately. A Subject doesn't hold a value.
private subject = new Subject<any>();
with
private subject = new BehaviorSubject(new String());
here's is updated Stackblitz
Updated!!
Thank you!! Nice advice, that's work fine, but I need my component to be hidden before recieved real data. To do that, I modified your solution, now I use this:
private subject = new BehaviorSubject(null);
Upvotes: 7