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