5

I have a typescript interface that has a variable (start) as a Date | null typing. This data is fetched from dotnet API which returns a DateTime object. The start variable is run through a Date-fns function which throws the error a RangeError because Date-fns has changed the function to only accept dates.

Invalid time value

react_devtools_backend.js:4026 Starting with v2.0.0-beta.1 date-fns doesn't accept strings as date arguments. Please use parseISO to parse strings

The problem I'm having is that I thought that start was already a date object, but when I print to console, it's actually a string. I could fix this problem by simply parsing it, however, I'd like to know why its not the correct typing.

console.log("I am a" + typeof(raceEvent.start!))
console.log(raceEvent.start)

I am astring

2022-04-28T08:30:00

Typescript interface:

export interface RaceEvent {
    id: string;
    sponsor: string;
    logo: string;
    prefix: string;
    name: string;
    postfix: string;
    start: Date | null;
    end: Date | null;
}

C# Class:

public class RaceEvent
{
    public Guid Id { get; set; }

     public string? Sponsor { get; set; }

     public string? Prefix { get; set; }

     public string Name { get; set; }

     public string? Postfix { get; set; }

     public string? Logo { get; set; }

     public DateTime Start { get; set; }

     public DateTime End { get; set; }
}

Load Event function

loadEvent = async (eventId: string) => {
    this.loadingInitial = true;
    
    try {
        let raceEvent = await agent.Events.details(eventId);
        runInAction(() => {
            this.selectedEvent = raceEvent;
            this.loadingInitial = false;
        });
    } catch (error) {
        console.log(error);
        runInAction(() => {
            this.loadingInitial = false;
        });
    }
};

agent.ts

const Events = {
    details: (id: string) => requests.get<RaceEvent>(`/raceEvents/${id}`),
};

const responseBody = <T>(response: AxiosResponse<T>) => response.data;

const requests = {
    get: <T>(url: string) => axios.get<T>(url).then(responseBody),
    post: <T>(url: string, body: {}) => axios.post<T>(url, body).then(responseBody),
    put: <T>(url: string, body: {}) => axios.put<T>(url, body).then(responseBody),
    del: <T>(url: string) => axios.delete<T>(url).then(responseBody),
};
3
  • you declared your RaceEvent interface, but where do you parse the result of the API call to that type? Commented May 20, 2022 at 13:08
  • There's no way for the default JSON parser to know it's handling a date as the underlying javascript code doesn't check types. You could add a reviver to theJSON.parse function that attempts to convert it to a date (under certain conditions). Commented May 20, 2022 at 13:40
  • Ive added the missing information Commented May 20, 2022 at 14:30

2 Answers 2

2

Some informations are missing, but i imagine that you're using JSON to exchange data between frontend (some js library) and backend (dotnet). The first thing is that JSON doesn't specify a Date type in its specification, but there are some practices to represent Date as a string in JSON.

date-fns library requires Date object to manipulate date. Then, you'll need to transform this string received from API to date object through new Date(dateString).

Just a note, Typescript type declarations are only a 'simulation' on top of Javascript, it only works on type checking on compile time, there isn't any type of coercion in runtime.

Sign up to request clarification or add additional context in comments.

3 Comments

Is there a way I can get the RaceEvent to be a DateTime at runtime as adding multiple parsing methods throughout my client app seems messy and inefficient.
Parsing methods occurs everywhere, any communication between applications will need some kind of parsing methods. When you believe that there isn't any parsing methods, in reality is because it's transparent to you. The 'inefficient' you're saying maybe is insignificant for your problem.
@Adam you could use a custom transformResponse in axios where you use JSON.parse with custom reviver that checks your result values and in case of encountering an ISO 8601 date (possibly using regex?) have it automatically parsed.
1

I am having the same problem. What works for me is, that i just create a new Date before using the date-fns function.

start = new Date(Start)

After that the fns-date functions work without a problem. Of course it is not the solution i want. :)

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.