Hi I want to access the property inside the interface from observable.
I have two properties inside this interface. loan-grade.ts
export interface LoanGrade{
grade:string
subgrade: string
}
I use subscribe to access Observable<LoanGrade[]>. edit.component.ts
grades: LoanGrade[];
ngOnInit():void{
this.termGradeServie.termGradeData$.subscribe(grades=>{
this.grades = grades;
})
}
Then in my html I want to print out all the grades that exist from observable I got. But I cannot do item.grade. How can I do this? edit.component.html
<ng-container *ngFor="let item of grades">
<tr>
<td><span>{{item.grade}}</span></td>
</tr>
</ng-container>
I think the problem is that when I subscribe termGradeData$ it returns observable(LoanGrade[]) so I can't help myself to set this.grades
as LoanGrade[]. But if I set it to LoanGrade[], I cannot access the property of grade or subgrade.
CodePudding user response:
In your service, make sure to write the observable with LoanGrade[]
type:
export interface LoanGrade {
grade: string;
subgrade: string;
}
@Injectable({ providedIn: 'root' })
export class TermGradeService {
public termGradeData$: Observable<LoanGrade[]>;
}
and that somewhere in the code it gets a value (for example, by connecting it to an http.get
method).
If you need to set a value for it by yourself, you can use 'BehaviorSubject` as follows:
export interface LoanGrade {
grade: string;
subgrade: string;
}
const initalLoanGradesValue: LoanGrade[] = [];
@Injectable({ providedIn: 'root' })
export class TermGradeService {
private _termGradeData$: BehaviorSubject<LoanGrade[]> = new BehaviorSubject<LoanGrade[]>(initalLoanGradesValue);
get termGradeData$() {
return this._termGradeData$.asObservable();
}
// ...
}
then somewhere in the code, make sure a value is emitted through the BehaviorSubject:
this._termGradeData$.next([
{ grade: 'x1', subgrade: 'y1' },
{ grade: 'x2', subgrade: 'y2' },
{ grade: 'x3', subgrade: 'y3' },
]);
Then in your component, you can do either A or B below:
A
private termsGradeSub: Subscription;
public grades: LoanGrade[];
ngOnInit(): void {
this.termsGradeSub = this.termGradeService.termGradeData$.subscribe((grades) => {
this.grades = grades; // "pull" the grades out of the observable, and save it to a local variable
});
}
// ...
ngOnDestroy() {
this.termsGradeSub?.unsubscribe();
}
and in your html:
<ng-container *ngFor="let item of grades">
<tr>
<td><span>{{ item.grade }}</span></td>
</tr>
</ng-container>
or
B (preferred way of reading observables): inside the component:
public termGradeData$: Observable<LoanGrade[]>;
ngOnInit() {
this.termGradeData$ = this.termGradeService.termGradeData$;
}
and use the async
pipe in your html:
<ng-container *ngFor="let item of grades | async">
<tr>
<td><span>{{ item.grade }}</span></td>
</tr>
</ng-container>