Reputation: 29
I want to display the text 'Subscribed' if the user is subscribed and 'Subscribe' if he is not. To do that, I call from the back-end a service that provides me the object if he is subscribed and throws an error not found if he is not. Now how can I change the text on display whether he is subscribed or whether he is not.
I am working on Angular 7.
import { Component, OnInit } from '@angular/core';
import { CategoryService } from '@ikubinfo/core/services/category.service';
import { Router } from '@angular/router';
@Component({
selector: 'ikubinfo-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
categories: Object;
text: string;
constructor(private categoryService: CategoryService, private router: Router) {
this.categories=[];
this.text='';
}
ngOnInit() {
this.categoryService.getAllCategories().subscribe(res=>{
this.categories=res;
console.log(this.categories);
});
}
subscribe(id: number){
this.categoryService.subscribe(id).subscribe(res=>{
});
}
isSubscribed(id:number){
return this.categoryService.isSubscribed(id).subscribe(res=>{
this.text='Subscribed';
},err=>{
this.text='Subscribe';
});
}
}
And the html
<div class="row">
<div class="col col-xl-6 col-lg-12" *ngFor="let category of categories">
<ikubinfo-panel header="Category">
<div panel-content ng-onload="isSubscribed(category.categoryId)">
<h1>{{ category.categoryName }}</h1>
<p>{{ category.categoryDescription }}</p>
<button class="btn btn-success" (click)="subscribe(category.categoryId)">{{ text }}</button>
</div>
</ikubinfo-panel>
</div>
</div>
Upvotes: 0
Views: 41
Reputation: 5602
You should change your isSubscribed() method like this:
isSubscribed(id:number) {
return this.categoryService.isSubscribed(id)
.pipe(
//this will map your response to 'Subscribed' text
map(res => 'Subscribed'),
//this map error to 'NotSubscribed
catchError(error => 'Not Subscribed')
);
}
Now let's change the template like this:
<div class="row">
<div class="col col-xl-6 col-lg-12" *ngFor="let category of categories">
<ikubinfo-panel header="Category">
<div panel-content>
<h1>{{ category.categoryName }}</h1>
<p>{{ category.categoryDescription }}</p>
<button class="btn btn-success" (click)="subscribe(category.categoryId)">{{ isSubscribed(category.categoryId) | async}}</button>
</div>
</ikubinfo-panel>
</div>
</div>
Although I have provided the solution as per your current code. There is plenty of scope of the code improvement. You should avoid using function calls in the template in bindings [except user action i.e. button click]. Also you can avoid .subscribe() in your component class by using async
pipe [https://blog.angularindepth.com/tiny-angular-pipe-to-make-any-function-memoizable-f6c8fa917f2f]
Upvotes: 0
Reputation: 1654
Have an additional property isSubscribed in the Category model,
export interface Category {
... // other existing properties
isSubscribed: boolean = false; // initializing to false by default for error case
}
In the *.ts file,
ngOnInit() {
this.categoryService.getAllCategories().subscribe(res=>{
this.categories=res;
this.categories.forEach((category) => {
this.categoryService.isSubscribed(id).subscribe(res=>{
category.isSubscribed = true;
});
});
});
}
In the *.html file, display the text based on this property.
<!-- It is better to disable the button if it is subscribed-->
<button class="btn btn-success" (click)="subscribe(category.categoryId)">{{ category.isSubscribed?'Subscribed':'Subscribe'}}</button>
Also, I would recommend getting the subscription flag on the initial request of getting all categories.
Upvotes: 1