I develop project of music site using Angular. Back-end is written in Spring. I download Album array using get request from back-end, then I use ngFor in html to print all albums data. I try to call album.getArtists() function in html to get artists (bands and musicians) in string form. Unfortunately, I get following error:
AlbumsViewComponent.html:5 ERROR TypeError: _v.context.$implicit.getArtists is not a function
    at Object.eval [as updateRenderer] (AlbumsViewComponent.html:7)
    at Object.debugUpdateRenderer [as updateRenderer] (core.js:30068)
    at checkAndUpdateView (core.js:29443)
    at callViewAction (core.js:29679)
    at execEmbeddedViewsAction (core.js:29642)
    at checkAndUpdateView (core.js:29439)
    at callViewAction (core.js:29679)
    at execComponentViewsAction (core.js:29621)
    at checkAndUpdateView (core.js:29444)
    at callViewAction (core.js:29679)
Here is html file:
<h1 class="main-header">Albums</h1>
<ul class="albums-view">
  <li *ngFor="let album of albums">
    <img class="album-cover" src={{album.coverPath}}>
    <span routerLink="../album-view/{{album.id}}" class="albums-view-element-text" id="album-name">{{album.title}} </span>
    <br>
    <span class="albums-view-element-text" id="album-artist"> by {{album.getArtists()}} </span>
    <br>
    <span class="albums-view-element-text" id="album-release-date"> Release Date: {{album.getReleaseDate()}} </span>
    <br>
    <span class="albums-view-element-text" id="album-length album-length-hours-minutes-seconds" style="visibility: hidden;"> Length: {{album.duration.hours}}:{{album.duration.minutes}}:{{album.duration.seconds}} </span>
    <br>
    <span class="albums-view-element-text" id="album-length album-length-minutes-seconds" style="visibility: hidden;"> Length: {{album.duration.minutes}}:{{album.duration.seconds}} </span>
  </li>
</ul>
Here is AlbumsViewComponent class:
import { Component, OnInit } from '@angular/core';
import { Album } from '../album';
import { ALBUMS } from '../mock-albums';
import { AlbumsViewService } from './albums-view.service';
import { ActivatedRoute } from '@angular/router';
import { routes } from '../app-routing.module';
@Component({
  selector: 'app-albums-view',
  templateUrl: './albums-view.component.html',
  styleUrls: ['./albums-view.component.css']
})
export class AlbumsViewComponent implements OnInit {
  public albums :Album[] = [];
  constructor(private albumsViewService: AlbumsViewService) { }
  ngOnInit() {
    this.albumsViewService.getAlbums().subscribe(albums => {
      this.albums = albums;
    });
  }
}
Here is AlbumsViewService class:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Album } from '../album';
@Injectable()
export class AlbumsViewService {
  constructor(private http: HttpClient) { }
  getAlbums(): Observable<Album[]> {
    return this.http.get<Album[]>('http://localhost:8090/album/');
  }
}
Here is Album class:
import { Duration } from './duration';
import { Band } from './band';
import { Musician } from './musician';
export class Album {
    id: number;
    title: string;
    duration: Duration;
    releaseDate: Date;
    coverPath: string;
    bands: Band[];
    musicians: Musician[];
    constructor(id: number, title: string, duration: Duration, releaseDate: Date, coverPath: string, bands: Band[], musicians: Musician[]) {
        this.duration = duration;
        this.id = id;
        this.title = title;
        this.duration = duration;
        this.releaseDate = releaseDate;
        this.coverPath = coverPath;
        this.bands = bands;
        this.musicians = musicians;
    }
    public getArtists(): string {
        let artists: string[];
        let concatenatedArtists = "";
        artists = this.getBands().concat(this.getMusicians());
        for (let artist of artists) {
          concatenatedArtists += artist + ", ";
        }
        concatenatedArtists = concatenatedArtists.slice(0, -2);
        return concatenatedArtists;
  }
  public getReleaseDate(): string {
    let rd:any = this.releaseDate;
    let releaseDate = rd.split("/");
    var releaseDateString: string;
    releaseDateString = this.getMonth(+releaseDate[1]) + " " + +releaseDate[0] + ", " + +releaseDate[2];
    return releaseDateString;
  }
  public getMonth(releaseDate): string {
    switch(releaseDate) {
      case 1:
      return "Jan";
      case 2:
      return "Feb";
      case 3:
      return "Mar";
      case 4:
      return "Apr";
      case 5:
      return "May";
      case 6:
      return "Jun";
      case 7:
      return "Jul";
      case 8:
      return "Aug";
      case 9:
      return "Sep";
      case 10:
      return "Oct";
      case 11:
      return "Nov";
      case 12:
      return "Dec";
      default:
      throw new Error("wrong month number");
    }
  }
  public getBands(): string[] {
    var bands: string[] = [];
    if (this.bands == null) {
      return bands;
    }
    for (let band of this.bands) {
      bands.push(band.name);
    }
    return bands;
  }
  public getMusicians(): string[] {
    var musicians: string[] = [];
    if (this.musicians == null) {
      return musicians;
    }
    for (let musician of this.musicians) {
      musicians.push(musician.name + " " + musician.surname);
    }
    return musicians;
  }
}
 
    