{{month.name + month.date.getFullYear()}}

{{month.name + month.date.getFullYear()}}

{{month.name + month.date.getFullYear()}}

Angular TypeScript Date.getFullYear() not a function when returning Observable from server

1.4k Views Asked by At

I am attempting to display data like so:

    <a *ngFor="let month of months">
      <div>
        <h4>{{month.name + month.date.getFullYear()}}</h4>
        <p *ngFor="let topic of month.topics">
            <span>{{topic.description}}</span>
            <li *ngFor="let item of topic.items">
                <span>{{item.content}}</span>
            </li>
        </p>
      </div>
    </a>

This works perfectly well when I use static Month[] data like so:

export const MONTHS: Month[] = [
    { id: 0, name: "September ", date: new Date(2020, 9), topics:[{id: 0, description: "I need a new description", items: [{ id: 0, content: "I need a new todo", isDone: false}]}]},
    { id: 1, name: "August ", date: new Date(2020, 8), topics:[{id: 0, description: "I need a second description", items: [{ id: 0, content: "I need a second todo", isDone: false}]}]},
];

However, when I attempt to get the Month[] from an in memory server like so:

///The database
export class InMemoryDataService implements InMemoryDbService {
  createDb() {
    const months = [
      { id: 0, name: "September ", date: new Date(2020, 9), topics:[{id: 0, description: "I need a new description", items: [{ id: 0, content: "I need a new todo", isDone: false}]}]},
      { id: 1, name: "August ", date: new Date(2020, 8), topics:[{id: 0, description: "I need a second description", items: [{ id: 0, content: "I need a second todo", isDone: false}]}]},
    ];
    return {months};
  }
}

///The month.service
/** GET months from the server */
  getMonths(): Observable<Month[]> {
    return this.http.get<Month[]>(this.monthsUrl)
      .pipe(
        tap(_ => this.log('fetched months')),
        catchError(this.handleError<Month[]>('getMonths', []))
      );
  }

///the .ts component of the html display
export class CurrentMonthComponent implements OnInit {
  months: Month[];

  constructor(private monthService: MonthService) { }

  ngOnInit(): void {
    this.getMonths();
  }

  getMonths(): void {
    this.monthService.getMonths()
    .subscribe(months => this.months = months);
  }

}

At that point the month.date.getFullYear() line in the html throws this exception:

core.js:4197 ERROR TypeError: month_r1.date.getFullYear is not a function
    at CurrentMonthComponent_a_3_Template (current-month.component.html:6)

Why does it no longer understand that date is a Date object when retrieving it from the server? Shouldn't the getMonths() method return a Month[] which defines date as a Date? Or does it have to do with the rxjs-observables? Here's my month.ts interface for reference. Thanks!

export interface Month {
    id: number;
    name: string;
    date: Date;
    topics: Array<Topic>;
}
2

There are 2 best solutions below

0
amdorsey12 On BEST ANSWER

Thanks for the help, it pointed me in the right direction to realize that my date was not being saved as a Date but rather a string that would then have to be converted back to a Date.

What finally worked and allowed me to call getFullYear() in that h4 tag was adding this map to the .pipe() in my http get method

map(months => months.map(month => ({...month, date: new Date(month.date)}))),

That changed it back to a Date object I was able to call getFullYear() on.

9
micronyks On

I think date property is just a type of Date and not the actual Date object.

Either while assign date to this.months array, you need to convert BE response to actual Date object then your piece of code will work

OR

<h4>{{month.name + (new Date(month.date)).getFullYear()}}</h4>