0
votes

I'm using Angular 6.

I have a data class defining JSON object parameters and used as observable like

contact-list.component.ts

export class ContactListComponent implements OnInit {

  contacts: Contact;

  constructor(
    private contactService: ContactService   
  ) { }

  ngOnInit() {
    this.getContacts();   
  }

  getContacts(): void {
    this.contactService.getContacts().subscribe(
      contacts => {
        this.contacts = contacts;
      }
    );   
  }
}

contact.service.ts

export class ContactService {

  private contactUrl = '/api/contacts/';

  constructor(
    private http: HttpClient,
  ) { }

  getContacts(): Observable<Contact> {
    const url = 'api_url' + this.contactUrl;

    return this.http.get<Contact>(url)
      .pipe(
        catchError(this.handleError('getContacts', null))
      );
  }
}

contact.model.ts

export class Contact {
  count: number;
  next: boolean;
  previous: boolean;
  results: Array<ContactDetails>;
}

class ContactDetails {
  id: string;
  first_name: string;
  last_name: string;
  full_name: string;
  private _gender: string;
  private _avatar: string;

  get gender(): string {
    if (this._gender === 'm') {
      return 'Male';
    } else if (this._gender === 'f') {
      return 'Female';
    } else {
      return '';
    }
  }

  get avatar(): string {
    if (this._avatar === null) {
      console.log('null is');
      return '../assets/img/bg5.jpg';
    } else {
      console.log('avatar');
      return this._avatar;
    }
  }
}

In ContactDetails class of contact.model.ts file, There are two functions to gender() and avatar().

The response from the server has m for male and f for female and avatar field is null when there is no avatar.

I want to display Male or Female as gender avatar default avatar when the avatar is not present.

contact-list.component.html

<div class="col-md-4" *ngFor="let contact of contacts.results">
    <img src={{ contact.avatar }} />
    <h2> {{ contact.full_name }}<h2>
    <h4> {{ contact.gender }}</h4>        
</div>

But contact.gender prints the value returned from the server and not the one specified in the gender() function.

How can I modify the content of the response data in template?

1
which result do you obtain? - firegloves
like in the case of gender according to getter function gender() it should return Male if gender is m but it is giving m in the template. - Anuj TBE
have you tried to debug into browser to see if that function is executed? - firegloves
I tried, that function is not calling. - Anuj TBE

1 Answers

2
votes

You must map json response (that in fact is a plain object not Contact instance as you would expect) to your mapping class. You can do that using map and eg. constructor

  getContacts(): Observable<Contact> {
    const url = 'api_url' + this.contactUrl;

    return this.http.get(url)
      .pipe(
        map(data=>new Contact(data));
        catchError(this.handleError('getContacts', null))
      );
  }

Obviously you must add Contact constructor implementation.

export class Contact {
  count: number;
  next: boolean;
  previous: boolean;
  results: Array<ContactDetails>;

 constructor(data:Object){
   ///do the mapping here
 }
}

Typed responses are good as long as you are using interfaces not implementations. After you add this mapping, it will work as expected.