18

Unfortunately the total code to reproduce this would be extensive, so I'm hoping that my problem is obvious with what I can easily provide. If required, I'll post a more complete solution.

First, I am defining an interface:

export interface ITest {
    myDate: Date;
}

Then I create an array of these for testing:

export const TEST: ITest[]=[{myDate: new Date(1995, 8, 1)}]

I expose these using a service in Angular2 that is hitting the InMemoryDbService from angular2-in-memory-web-api. The code where I call this and get the array is as follows:

get(): Promise<ITest[]>{
    return this.http.get(this.testUrl)
        .toPromise()
        .then(response => response.json().data as ITest[])
        .catch(this.handleError);
}

...and then I bring it into my component with:

    this.testService.get().then(tests => {
        this.tests = tests;
        console.log("Date Type:"+typeof(this.tests[0].myDate));
    });

This all works fine, but the problem is the console.log statement shown there results in:

Date Type:string

The data in it is correct, in that the string held by my date is 1995-09-01T07:00:00.000Z, but the main issue is - it isn't a Date it is a string! In VS Code I even get code completion for methods like toDateString but when I execute them I (of course) get toDateString is not a function.

I am pretty sure that the issue is occurring with response => response.json().data as ITest[], but why isn't the date data being cast to an actual Date? I'm doing it wrong, that I understand. How should I be handling this such that I can have my objects obtain the types I expect?

2 Answers 2

22

You are using an interface and type assertion to basically tell TypeScript that the object conforms to that interface.

But this is not actually the case as what you are casting is a json object in which the "myDate" property is being represented as a string.

Using type-assertion does not affect generated javascript code in any way - you have to do the actual type conversion yourself.

The reason why it comes as string is that there is no type defined in JSON format to represent Date, so the server in all likelihood is just sending a result of date.toString().

One option for you would be to have a class for representing the returned value and instantiate an object from the JSON properties like so:

var response = JSON.parse(JSON.stringify({ myDate: new Date() }));

class Test  {
    constructor(json: { myDate: string }) {

        this.myDate = new Date(json.myDate);
    }

    myDate: Date;
}

let test = new Test(response);
console.log("Type: " + typeof (test.myDate));
console.log("Value: " + test.myDate);
Sign up to request clarification or add additional context in comments.

5 Comments

And it's not event called cast in the documentation, it's called type assertion, and it does not affect generated javascript code in any way - you have to do actual type conversion yourself. And the reason why it comes as string is there is no type defined in JSON format to represent Date, so the server in all likelihood is just sending a result of date.toString().
Thanks, removed cast from my answer as it was not the correct term at all. Your comment is actually much more helpful.
Feel free to reuse it in the answer :-)
Yeah I figured this was the case; I guess I was hoping there was a more automated way to accomplish that. In reality the object being returned is not so simple, and it will be quite a chunk of code to do this. Oh well, if that's as good as it gets at least I won't waste more of my time trying to find a better way!
this sucks.... i was hoping for a C# style casting... basically to reuse classes for front/server end and DB
0

I am using angular. When dealing with date, I use this:

  1. when making interface, for example in User.ts:

    export interface User { id?: string; date?: any; }

  2. In component file (ts file), I declared it as :

    date = new Date();

That line initialized the date with current date.

  1. Assign the date value with toDate() method like this:

    this.date = this.outputDate.toDate()

  2. Display it in template file (html) as usual

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.