0

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:

Error

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 ;)

0

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

In my service i change my getCompte() into : public getCompte(id: number): Compte { return this.http.get('localhost:33713/api/Compte' + id); } But it still an error : Returned expression type Observable<Object> is not assignable to type Compte
Of course. An Observable<Compte> is not a Compte. I never advised you to make such a change. I even said that the service can not return a Compte. Read my answer again (not just the first two lines). It tells you what to do, and why you need to do that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.