Reputation: 422
I created two components one for listing all loans and another is for viewing each loan details on click of each card in the list. When I tried to console the data in subscribe, I can view the information, but I am not getting any data on the HTML page.
loan.ts
export class Loan
{
id :number;
title: string;
description: string;
amount: number;
}
list-loan-component.ts
import { Component, OnInit } from '@angular/core';
import * as EventEmitter from 'events';
import { Loan } from '../loan';
import { LoanService } from '../loan.service';
@Component({
selector: 'app-list-loans',
templateUrl: './list-loans.component.html',
styleUrls: ['./list-loans.component.css']
})
export class ListLoansComponent implements OnInit {
loans:Loan[];
constructor(private loanService: LoanService) { }
ngOnInit(): void {
this.loans = this.loanService.getLoans();
}
openLoan(loan: Loan)
{
this.loanService.loan.emit(loan);
}
}
list-loans-component.html
<div class="container">
<div class="card-deck">
<div *ngFor="let loan of loans">
<div class="card" routerLink="/loan/view" routerLinkActive="active"
(click)="openLoan(loan)">
<div class="card-header"> {{loan.title}} - {{loan.amount}}</div>
<div class="card-body">
<p class="card-text">{{loan.description}}</p>
</div>
</div>
</div>
</div>
</div>
view-loan.component.ts
import { ChangeDetectorRef, Component, Input, OnChanges, OnInit } from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot, Params } from '@angular/router';
import { Loan } from '../loan';
import { LoanService } from '../loan.service';
@Component({
selector: 'app-view-loan',
templateUrl: './view-loan.component.html',
styleUrls: ['./view-loan.component.css']
})
export class ViewLoanComponent implements OnInit {
selectedLoan: Loan ;
constructor(private loanService: LoanService, private router:ActivatedRoute) { }
ngOnInit() {
this.loanService.loan.subscribe(loan =>
{
this.selectedLoan = loan;
}
);
}
}
view-loan.component.html
<div class="card text-center">
<div class="card-header">
{{selectedLoan['title']}}
</div>
<div class="card-body">
<h5 class="card-title">Loan From : {{selectedLoan['title']}}</h5>
<h3 style="text-align: left; text-decoration: underline;">Details:</h3>
<p class="card-text">{{selectedLoan['description']}}</p>
<p class="card-text">{{selectedLoan['amount']}}</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
<div class="card-footer text-muted">
2 days ago
</div>
</div>
loan.service.ts
import { Injectable, Output, EventEmitter } from "@angular/core";
import { Loan } from "./loan";
@Injectable({
providedIn: 'root'
})
export class LoanService
{
loan = new EventEmitter<Loan>();
private loans:Loan[] = [
{
"id":1,
"title" : "HDFC Credit Loan",
"description" :"Loan to clear all credit card payments",
"amount" : 24958.23
},
{
"id":2,
"title" : "Aditya birla personal Loan",
"description" :"Loan to personal expenses",
"amount" : 12000.00
}
]
constructor(){}
getLoans(): Loan[]{
return this.loans.slice()
}
getLoan(id:number): Loan{
this.loans.forEach(loan =>
{
if(loan["id"] === id)
return loan;
}
);
return new Loan();
}
}
Note: I am using routing as well. Kindly let me know if routing can cause any of this issues.
Upvotes: 1
Views: 113
Reputation: 3588
Inside your list-loans-component.html
you are iterating over your loans like so:
<div *ngFor="let loan of loans | async">
but your loans
are not a async
value, as your loan
service directly returns an Loan[]
(not Observable<Loan[]>
).
Just remove the async
pipe and things will start to work.
p.s. Very well asked question.
Edit:
Here is a working stackblitz with your code line for line.
Upvotes: 0
Reputation: 2982
It seems you have EventEmitter value passed before your ViewLoanComponent is loaded. Just replace your EventEmitter
for ReplaySubject
, like this:
export class LoanService
{
$loan = new ReplaySubject<Loan>(1);
...
And next in code
openLoan(loan: Loan)
{
this.loanService.$loan.next(loan);
}
Also remove the async pipe, in your case:
<div *ngFor="let loan of loans">
Upvotes: 1
Reputation: 617
You just can using async
pipe on an observable but in your code you are using on loans[] witch is an array.
Remove the pipe.
But I recommend to use a BehaviorSubject
or an Observable
rather than an EventEmitter
.
https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service
Upvotes: 0