8

I know that json does not treat dates in a special way and provides them as strings from the server. Is there a way to provide a json object response that has an ISO date property and map this to a class already with the date property mapped as a JS date?

Example:

Json Response:

{
    "data": {
        "id": 1,
        "name": "John",
        "surname": "Smith",
        "birthDate": "1986-05-04T22:59:59.000Z"
        "subscriptionDate": "2020-06-28T14:36:43.498Z"
    }
}

And I have this class:

export class User {

    id: string;
    name: string;
    surname: string;
    birthDate: Date;
    subscriptionDate: Date;

}

My service method:

getUser(id: string): Observable<User> {
    return this.http.get<User>(`${this.UrlService}estabelecimentos/${id}`, { headers: this.authenticationService.jwt() }).catch(super.serviceError);
}

But when I use it in my component birthDate and subscriptionDate are always treated as strings. Is there anyway to transform it to JS dates without having to format the date in every each request by iterating the json response and modifying the object?

4 Answers 4

4

The short answer is no as JSON format does not allow date types. See this: https://www.w3schools.com/JS/js_json_datatypes.asp

I don't think you have any choice other than to transform them into Date objects, and besides, it's relatively trivial given your string date format:

ndate = new Date("1986-05-04T22:59:59.000Z")
Sign up to request clarification or add additional context in comments.

5 Comments

The problem is not to convert the string into a Date but to do it for multiple fields and classes manually.
So what are you trying to achieve? "Is there anyway to transform it to JS dates without having to format the date in every each request by iterating the json response and modifying the object?" You're asking if you can transform the JSON field into a JS Date object without having to format the date, and the answer is no. JSON data types do not allow date objects as per the link above.
I think angular has mechanisms such as http interceptors that can intercept a response and modify data. That's what I need.
why would you want to use a http interceptor to modify data? Doesn't seem like an Angular best practice to me. Far better to create a service that sits between your Component and API service, and map/transform data there.
@lionbigcat It's funny you would say it's not Angular best practice, but the Angular team does not (at the moment) agree. The really sensible thing, from most people's perspective - that would make the common problem the OP is having trivial to deal with - would be to have a way to inject or tell angular to use a customer parser for JSON - the way you can with the standard javascript JSON and revivers. Sadly, the team did like that idea, and they tell people to use an http interceptor for this: github.com/angular/angular/issues/21079
4

I suggest to transform the json response before returning it, like this :

getAll(): Observable<Session[]> {
  return this.apiService.get(`/sessions`).pipe(
    map((data)=>{
      return data.map((session) => {
        session.startDate = new Date(session.startDate);
        session.endDate = new Date(session.endDate);
        return session;
      }
    )})
  );
}

1 Comment

See also stackoverflow.com/a/64994748/107013 for a detailed explanation.
0

Since the GET is going to return an observable, you should be able to do something like this:

getUser(id: string): Observable<User> {
  return this.http.get<User>(`${this.UrlService}estabelecimentos/${id}`, { headers: this.authenticationService.jwt() })pipe(
    map(response => {
      return {
        "data": {
          "id": response.id,
          "name": response.name,
          "surname": response.surname,
          "birthDate": new Date(response.birthDate)
          "subscriptionDate": new Date(response.subscriptionDate)
      }
    }),
    catchError(()=> super.serviceError)
  )
}

Comments

0

JSON doesn't provide any special support for date. You need to convert it manually. As follows:

new Date("1986-05-04T22:59:59.000Z");

Converting JSON object into a Javascript object can help you to achieve what you need.

Check this function:

function convertJsonIntoJavaScript(data){
let newObj = new Object();
   Object.keys(data).forEach(x=> {
   let d = new Date(data[x]);
   newObj[x]= (d instanceof Date && !isNaN(d))? d: data[x];
});
return newObj;
}

NOTE: I have not tested this function, write your feedback in the comment below if it works or not.

2 Comments

The problem is not to convert the string into a Date but to do it for multiple fields and classes manually.
@PhilippeGioseffi , Just added a function in answer. Although I couldn't test it but I believe this should work.

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.