Angular 8 way to convert json response with string dates to JS date?

10.9k Views Asked by At

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

There are 4 best solutions below

4
lionbigcat On BEST ANSWER

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")
2
Arun Saini On

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.

0
Tucker On

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)
  )
}
1
Mustapha GANGA On

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