Reputation: 69
I am trying to display a single object from an array based on a property value.
My list of transactionitems has an accountId property, but I would like to display the account name instead. All accounts are loaded in the accounts$ array. I just can't figure out how to properly use my getAccountById function
Here is the component class
export class NewtransactionComponent implements OnInit {
transaction$: Transaction;
tempItem$: TransactionItem;
accounts$: Array<Account>;
constructor(private data: DataService) { }
ngOnInit() {
this.transaction$ = new Transaction();
this.data.getAccounts().subscribe(data => this.accounts$ = Object.assign(new Array<Account>(), data));
this.tempItem$ = new TransactionItem();
this.transaction$.TransactionDate = new Date();
}
addItem(){
this.transaction$.TransactionItems.push(this.tempItem$);
this.tempItem$ = new TransactionItem();
}
getAccountById(id):Account{
return this.accounts$.find(x => x.id === id);
};
and here is the html view that gives the error "Cannot read property 'name' of undefined"
<div class="items-container">
<mat-form-field>
<input matInput placeholder="Amount" [(ngModel)]="tempItem$.Amount">
</mat-form-field>
<mat-form-field *ngIf="accounts$">
<mat-select placeholder="Account" [(ngModel)]="tempItem$.AccountId">
<mat-option *ngFor="let account of accounts$" [value]="account.id">{{account.name}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="Credit/Debit" [(ngModel)]="tempItem$.CreditDebit">
<mat-option value="Credit">Credit</mat-option>
<mat-option value="Debit">Debit</mat-option>
</mat-select>
</mat-form-field>
<button mat-mini-fab color="primary" (click)="addItem()">Add</button>
</div>
<table *ngIf="transaction$.TransactionItems.length">
<tr>
<th>Amount</th>
<th>Account</th>
<th>Credit/Debit</th>
</tr>
<tr *ngFor="let item of transaction$.TransactionItems">
<th>{{item.Amount | currency}}</th>
<th>{{getAccountById(item.AccoundId).name}}</th>
<th>{{item.CreditDebit}}</th>
</tr>
</table>
these are the account and transactionitem data models for reference
export class Account {
Id: string;
Name: string;
Category: string;
SubCategory: string;
}
export class TransactionItem{
Id: number;
TransactionId:number;
Accountid: string;
Amount: number;
CreditDebit: string;
}
Upvotes: 2
Views: 7487
Reputation: 60626
I assume that the error is here: {{account.name}}
?
This is most likely a timing issue. The page will attempt to display before the data is retrieved from the subscription.
One way to resolve the issue is to use an *ngIf
<div class="items-container" *ngIf="account">
That way the page won't try to display until the data is retrieved.
Another option is to use the safe navigation operator:
{{account?.name}}
The question mark tells Angular not to attempt to read the name property if the account is null or undefined.
EDIT:
If there error is here: {{getAccountById(item.AccountId).name}}
, then it is telling you that getAccountById(item.AccountId)
is undefined or null. Is it possible that one of your transactions has no account?
And looking at your code more closely, JavaScript/TypeScript is case sensitive. So if you declare the id using:
Id: string;
(Upper case I)
You can't then access it using:
return this.accounts$.find(x => x.id === id);
(Lower case)
Upvotes: 5