4

I've a class as shown below

export class Story {
    id: number;
    title: string;
    storyText: string;
    utcDate: string;
    get displayDate(): string {
       const today = new Date();
       const postDate = new Date(this.utcDate);
       const td = today.getTime();
       const pd = postDate.getTime();
       return ((td-pd)/1000)+'ms';
    }
}

HTML view is shown below

<span>
   <i class="fa fa-clock-o" aria-hidden="true"></i>
   {{story.displayDate}}
</span>

Here, the html code block is inside and ngFor loop as *ngFor="let story of stories" and stories is an array of type Story , stories: Story[]; But its not displaying anything . No error also. What am I doing wrong here? Will this work like this without an explicit setter property? Or should I create a setter property and set the value manually?

edit: below my script that populate the story array and the service function

loadData() {
this.storyService.stories()
.subscribe(
data => {
  const response = <Story[]>data.message;
  this.stories = response;
},
error => {
    alert('error');
});

}

    stories() {
          return this.http.get<Result>(this.baseUrl + '/story/list/', this.httpOptions);

 }
16
  • 1
    Please give a minimal reproducible example; how do you create the story object? Also I'm surprised TypeScript isn't throwing an error pointing out that your getter doesn't return a string. Commented Jul 6, 2018 at 6:36
  • 5
    My guess is that story isn't actually an instance of Story: you probably get these stories as a JSON response to an HTTP request. But HTTP will never, ever create instances of any of your classes. Commented Jul 6, 2018 at 6:37
  • 2
    you should define it like public story = new Story ; in your app.component.ts Commented Jul 6, 2018 at 6:41
  • 2
    That is almost irrelevant. What you need to provide is the code creating these Story instances, i.e. the code where you have new Story(). Or better, a complete minimal example reproducing the problem. If you don't have new Story() anywhere, then you're never constructing any Story instance. Commented Jul 6, 2018 at 6:43
  • 2
    You aren't actually creating a class instance, giving a type hint does not cause any casting or conversion. This is what @JBNizet already said; you need to map to new Story for an accessor to work. Commented Jul 6, 2018 at 6:53

2 Answers 2

7

Your getter wont work unless you create a new instance. Also when you are putting stories: Story[], you are only telling that it is safe to assume Stories will contain properties in Story class. Typescript wont that there is a getter.

Since you are inside ngFor, I suggest using a Pipe.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'displayDate'
})
export class DisplayDatePipe implements PipeTransform {

  transform(value: any): string {
    const today = new Date();
    const postDate = new Date(value);
    const td = today.getTime();
    const pd = postDate.getTime();
    return ((td-pd)/1000).toString();
  }

}

then in your template make slight modification like this.

<span>
   <i class="fa fa-clock-o" aria-hidden="true"></i>
   {{story.utcDate | displayDate }}
</span>
Sign up to request clarification or add additional context in comments.

2 Comments

Yea, I think I should go with this instead of creating object for each of my array items. Thanks
Yes, creating instance for each object wouldn't be a good solution.
7

This is because when you cast in Typescript, you don't get the methods. So imagine you have this :

const data = {
    id: 1;
    title: 'foo';
    storyText: 'bar';
    utcDate: '01-01-2000';
}

const story = data as Story;
// OR
const story = <Story> data;

console.log( story.displayDate ); // Wrong, because the method doesn't exist

So instead, you need to create a new object

const story = new Story(data.id, data.title, data.storyText, data.utcDate);
console.log( story.displayDate ); // Will work !

But that mean you must have a constructor and you need to loop on your array of stories.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.