Reputation:
I am developing a small Angular application that aims to list bank accounts, and to be able to manipulate them with CRUD (there are also transactions). But here’s a problem for me, and I really don’t understand why. When I click on one of the listed accounts, it sends me to another page containing the account details (Balance, Name,...), I have however well set up (at least I assume) the Get(id), with it I get an object that then allows me to manipulate the data. But it doesn’t work and I always get the same mistake as here:
There is my Account Service (the Get(id) i use HttpClient) :
public getCompte(id: number): Observable<Compte> {
return this.http.get<Compte>('http://localhost:33713/api/Compte/' + id);
}
There is my Account class :
export class Compte {
private _Id: number;
private _Nom: string;
private _Solde: number;
private _AllowsDecouvert: boolean;
constructor(Nom?: string, Montant?: number, Decouvert?: boolean) {
this._Nom = Nom;
this._Solde = Montant;
this._AllowsDecouvert = Decouvert;
}
get Id(): number {
return this._Id;
}
set Id(value: number) {
this._Id = value;
}
get Nom(): string {
return this._Nom;
}
set Nom(value: string) {
this._Nom = value;
}
get Solde(): number {
return this._Solde;
}
set Solde(value: number) {
this._Solde = value;
}
get AllowsDecouvert(): boolean {
return this._AllowsDecouvert;
}
set AllowsDecouvert(value: boolean) {
this._AllowsDecouvert = value;
}
public static fromJSON(rawCompte: any) : Compte {
const tmpCompte = new Compte(rawCompte['Nom'], rawCompte['Montant'], rawCompte['Decouvert']);
tmpCompte.Id = rawCompte['Id'];
return tmpCompte;
}
public static fromArrayJSON(rawComptes: any[]) : Compte[] {
return rawComptes.map(Compte.fromJSON);
}
public getCleanDataForSending() {
return {
"Id": this.Id,
"Nom": this.Nom,
"Montant": this.Solde,
"Decouvert": this.AllowsDecouvert
};
}
}
And there is my component code :
export class DetailsComponent implements OnInit {
public detail$: Compte ;
private id;
constructor(private route: ActivatedRoute, private _cmptService: CompteService) {
this.route.params.subscribe( params => this.id = params.id );
}
ngOnInit() {
this._cmptService.getCompte(this.id).subscribe(
res => { this.detail$ = Compte.fromJSON(res); }
);
Thank in advance ;)
Upvotes: 0
Views: 69
Reputation: 691913
getCompte()
returns an Observable<Compte>
.
Why doesn't it simply return a Compte
directly?
Because it can't: AJAX requests, as their name indicates, are asynchronous: you send a request, get back an observable immediately, and much later, when the response has finally come back, the observable notifies its subscriber that the compte is finally available.
During all this time, the component is displayed, and its detail$
variable has still not been initialized, and thus has the value undefined
. So, since the template tries to display its name, you get an exception.
In the template, only display the detail if it's there:
<div *ngIf="detail">...</div>
Also, rename it to detail
, or better: compte
, or even better: account
. The $
suffix is conventionally used for variables of type Observable, and detail$
is not an observable.
It seems that you're coming from a Java background where you use getters and setters for everything. It's not necessary in TypeScript: you can just use public fields, and switch to getters and setters if they're really necessary without changing how clients access these properties. The name fromJSON
is also a bad choice: the method doesn't take a JSON sring as argument.
Finally, just as in Java, properties typically start by a lowercase letter in TypeScript/JavaScript.
Upvotes: 2