Using TypeScript to convert a JSON date string into a Date object

The backend is sending me a JSON data structure that resembles the following:

[{
    "schedulingId": "7d98a02b-e14f-43e4-a8c9-6763ba6a5e76",
    "schedulingDateTime": "2019-12-28T14:00:00",
    "registrationDateTime": "2019-12-24T16:47:34",
    "doctorViewModel": {
        "doctorId": "a49d9534-65a6-4730-ac45-4dc2f91165e0",
        "doctorName": "Ana"
    },
    "personViewModel": {
        "personId": "3607c475-e287-4e83-85e6-a46f4a0116d6",
        "personName": "João",
        "birthDate": "1970-09-18T00:00:00"
    },
    "consultaViewModel": null
}]

My goal is to parse this JSON into a Scheduling object with date format 'dd/MM/yyyy hh:MM:ss':

export interface Scheduling {
   schedulingId : string;
   schedulingDateTime : Date;
   registrationDateTime : Date;
   person : Person;
   doctor : Doctor;
   consulta? : Consulta;
}

export interface Person {
   personId : string;
   personName : string;
   birthDate : Date;
}

export interface Doctor {
    doctorId : string;
    doctorName : string;
}

export interface Consulta {
    consultaId : string;
    consultaDateTime : Date;
}

After calling my get method, I need to figure out how to deserialize the JSON properly:

this.httpClient.get<Scheduling>(`${applicationUrl}/scheduling/${date}`);

Answer №1

There are a couple of methods to achieve this goal, utilizing direct mapping and constructor usage.

You have the option to utilize the pipe and map operator from the rxjs/operators library.

1. Direct Mapping

import { map } from "rxjs/operators";

this.httpClient.get<Scheduling>(`${applicationUrl}/scheduling/${date}`)
   .pipe(
        map(scheduling => {
          scheduling.schedulingDateTime = new Date(scheduling.schedulingDateTime);
          scheduling.registrationDateTime = new Date(scheduling.registrationDateTime);
          scheduling.personViewModel.birthDate = new Date(scheduling.personViewModel.birthDate);
          return scheduling;
        })
    );

2. Utilizing Constructors

In this method, each JSON object received will be passed into the constructors of classes for date parsing.

export class Person {
  personId: string;
  personName: string;
  birthDate: Date;

  constructor(init: Person) {
    this.personId = init.personId;
    this.personName = init.personName;
    this.birthDate = parseDate(init.birthDate);
  }
}

export class Consulta {
  consultaId: string;
  consultaDateTime: Date;

  constructor(init: Consulta) {
    this.consultaId = init.consultaId;
    this.consultaDateTime = parseDate(init.consultaDateTime);
  }
}

export class Doctor {
  doctorId: string;
  doctorName: string;

  constructor(init: Doctor) {
    this.doctorId = init.doctorId;
    this.doctorName = init.doctorName;
  }
}


export class Scheduling {
  schedulingId: string;
  schedulingDateTime: Date;
  registrationDateTime: Date;
  person: Person;
  doctor: Doctor;
  consulta?: Consulta;

  constructor(init: Scheduling) {

    this.schedulingId = init.schedulingId;

    this.schedulingDateTime = parseDate(init.schedulingDateTime);
    this.registrationDateTime = parseDate(init.registrationDateTime);

    this.Person = init.Person !== undefined ? new Person(init.Person) : undefined;
    this.Consulta = init.Consulta !== undefined ? new Consulta(init.Consulta) : undefined;
    this.Doctor = init.Doctor !== undefined ? new Doctor(init.Doctor) : undefined;
  }
}



export function parseDate(str: string | Date): Date {
  if (str !== undefined && str !== null) {
    return new Date(str);
  }
  return undefined;
}

Service

this.http.get<Scheduling[]>(`${applicationUrl}/scheduling/${date}`)
      .pipe(
        map(schedulings => {
          const modifiedSchedulings = []
          for (const scheduling of schedulings) {
            modifiedSchedulings.push(new Scheduling(scheduling));
          }
          return modifiedSchedulings;
        })
      );

Answer №2

By transforming interfaces into classes, constructors can be created to facilitate the return of the desired response.

The classes are now defined as follows:

export class Scheduling {
  constructor(
    public schedulingId: string,
    public schedulingDateTime: Date,
    public registrationDateTime: Date,
    public person: Person,
    public doctor: Doctor,
    public consultation?: Consultation
  ) {}
}

export class Person {
  constructor(
    public personId: string,
    public personName: string,
    public birthDate: Date
  ) {}
}

export class Doctor {
  constructor(public doctorId: string, public doctorName: string) {}
}

export class Consultation {
  constructor(public consultationId?: string, public consultationDateTime?: Date) {}
}

Now it is possible to map the response using the defined classes in the following way:

this.httpClient.get<Scheduling[]>(`${applicationUrl}/scheduling/${date}`).pipe(
  map((schArr: any[]) => {
    const resp: Scheduling[] = [];
    schArr.forEach(sch => {
      resp.push(
        new Scheduling(
          sch.schedulingId,
          new Date(this.datePipe.transform(sch.schedulingDateTime, this.FORMAT)),
          new Date(this.datePipe.transform(sch.registrationDateTime, this.FORMAT)),
          new Person(
            sch.personViewModel.personId,
            sch.personViewModel.personName,
            new Date(this.datePipe.transform(sch.personViewModel.birthDate, this.FORMAT))
          ),
          new Doctor(sch.doctorViewModel.doctorId, sch.doctorViewModel.doctorName),
          sch.consultationViewModel != null
            ? new Consultation(sch.consultationViewModel.consultationId, sch.consultationViewModel.consultationId)
            : null
        )
      );
    });
    return resp;
  })
);

For better readability, define a constant named format and inject the DatePipe service:

constructor(private datePipe: DatePipe, private httpClient: HttpClient) {}
FORMAT = "yyyy-MM-dd HH:mm:ss";

Visit Stackblitz for demonstration

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

An error occurs when attempting to redirect with getServerSideProps

When I am logged in, I want to redirect to the /chat page using auth0 for authentication. The error seems to be related to returning an empty string for props, but it does not impact the website as redirection works correctly. The main issue here is the in ...

Maintaining the selected option on page refresh with React Remix

I have a dropdown menu with 2 choices (en, no) for switching the language when onChange event occurs. To save the selected language, I am using localStorage. Due to the server-side rendering in Remix, direct access to localStorage is not possible. Therefo ...

Retrieving routing information from directives within angular2

const APP_ROUTES: RouterConfig = [ { path: 'app/home', component: HomeComponent, data: { name: 'Home' } } ] Assuming the route configuration is set as displayed above, how can one ...

How can TypeScript objects be serialized?

Is there a reliable method for preserving type information during JSON serialization/deserialization of Typescript objects? The straightforward JSON.parse(JSON.stringify) approach has proven to have several limitations. Are there more effective ad-hoc sol ...

What are the steps to save information to Firebase's Realtime Database?

Currently, I am facing an issue where user location data is not being written into our Firebase Realtime Database even though the console confirms that the data is fetched correctly every 2 seconds. I am seeking assistance on how to resolve this problem. ...

Encountering difficulty invoking a component method from d3's call() function

My current setup involves using D3 to drag and drop links in the following manner: .call(d3.drag() .on("start", linkDragStart) .on("drag", linkDragging) .on("end", linkDragEnd)); Recently, I decided to extract this functionality into a separate met ...

Error in validating control groups in Angular 4

I'm currently working on setting up a standard form using Angular reactive forms. Below is the generic HTML code I have for input elements: <div class="form-input form-group" [formGroup]="group"> <div class="row"> <div clas ...

Strategies for handling superfluous or calculated information within Angular form components

I am faced with a challenge in managing informative fields within my component, especially when some inputs are derived from others. For instance, consider an order that includes a product ID and an amount. Here is a scenario: If a product is selected, I ...

I am looking for guidance on the proper way to import MatDrawer and MatDrawerContainer in the app.module.ts file for an Angular

When attempting to implement a side nav using angular material and clicking on the toolbar icon, everything was functioning correctly until I encountered an error while trying to open the navbar: The error message displayed: Unexpected directive 'Ma ...

Obtaining data from JSON using JSON path

Attempting to retrieve the id value tied to an email value from the given JSON data has been a challenge for me: [ {"id":11,"username":"John","address":"London","email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="84eeebece ...

Retrieve highlighted text along with its corresponding tag in ReactJS

my <span class="highlight">highlighted</span> word The text above is showing an example including HTML tags. However, when using window.getSelection(), only the text "my highlighted word" is returned without the surrounding <span& ...

Retrieving a JSON object from a serialized string using C#

Imagine you have a string that includes JSON data like this ... string s = "{ \"id\": \"1\", \"name\" : \"Test\" } has other text in the same string"; In C#, is there a method to isolate the JSON portion of the str ...

"Encountering an issue with Express.json where it fails to parse the

Receiving JSON POST data from an IoT API that includes multipart form-data. Occasionally, an image file may be included but I only want to focus on the JSON part: POST { host: '192.168.78.243:3000', accept: '*/*', 'content-le ...

Dynamic rows in an Angular 2 Material data table

I'm currently working on dynamically adding rows to an Angular 2 Data Table ( https://material.angular.io/components/table/overview) by utilizing a service called "ListService". This service provides me with the columns ("meta.attributes") to be displ ...

Struggling to find a solution for directing to the featured homes page without the content overlapping with my navbar and search component. Any assistance would be greatly

Looking for assistance with routing to the featured homes page without the content overlapping my navbar and search component. I simply want it to direct to a new URL without importing the components unless specifically needed. Check out this link I suspe ...

Matching Tables with JavaScript and JSON

After hours of coding, I'm stuck on a simple task and could really use some assistance. The "users" object contains user account information, with the function "get" meant to retrieve matching objects from this array. var users = [ { name ...

Troubleshooting: WordPress integration with PhoneGap not processing JSON data

I've been following a tutorial and I'm encountering some issues with the examples provided. Despite my attempts to run the examples, I am not seeing any results: app.html <!DOCTYPE HTML> <html> <header> <script src="https:/ ...

What are the steps to styling a component with CSS Emotion?

I am facing an issue with using a theme with TypeScript in this component const buttonDisabled = css` color: ${({ theme }) => theme.color}; `; Is there a way to correctly type this component? Error: No overload matches this call. Overload 1 of 2, & ...

A more efficient method for querying documents based on ids that are not in a given list and then sorting them by a specific publish date

After implementing the code provided below, I noticed that the performance tests indicate each request takes a second or longer to complete. My goal is to enhance this speed by at least 10 times. The bottleneck seems to be caused by the NOT operator resu ...

A more effective strategy for avoiding the use of directives or jQuery in AngularJS

I need guidance on using Angular directives, especially when deciding between JQuery and Angular 1 directives for a particular scenario. Here is an example of my object list: [ { "id":"sdf34fsf345gdfg", "name":"samson", "phone":"9876543210", ...