Intl.DateTime formatter get invalid time every time even after rerendering component. React

Viewed 22

We have a component that receives information from the backend and has to render it, its properties are as follows:

interface CitizenshipProps {
    citizenship?: Citizenship;
    name?: string;
    lastName?: string;
    onUpdateClick?: () => void;
}

Now, the Citizenship type is:

export interface Citizenship {
    nationalId: string;
    dateOfBirth: string;
    city: string;
    district: string;
    streetName: string;
    unitNumber: number;
    postCode: number;
    updatedAt: string;
}

We want updatedAt to be Date type (instead of string shown above). We intended to render it as follows:

<S.ProfileContentRowData
    type="body"
    size="medium"
    variant="regular"
>
    {dateTimeFormatter.format(citizenship?.updatedAt)}
</S.ProfileContentRowData>

Where

const dateTimeFormatter = Intl.DateTimeFormat(userLang, {
    dateStyle: 'full',
    timeStyle: 'medium',
});

It should has sense since Inte.DateTimeFormat.format accepts either number, Date or undefined:

interface DateTimeFormat {
        format(date?: Date | number): string;
        resolvedOptions(): ResolvedDateTimeFormatOptions;
    }

However, it is not the case and the component always throws RangeError: Invalid time value.

We can say it is understandable at the first rendering since the Citizenship property is undefined (and the formatter receives undefined, it should not be a problem); but, when the card receives the data, it even shows the same error(and we checked it by using effect, trying to check it both with and without formatter, and the date comes as Date).

We really don't understand this behavior.

Right now, we solved it by getting the updatedAt as a string instead, and enforcing the rendering by checking if Citizenship is not undefined:

{citizenship?.updatedAt !== undefined && (
    <S.ProfileContentRowData
        type="body"
        size="medium"
        variant="regular"
    >
        {dateTimeFormatter.format(
            new Date(citizenship?.updatedAt || '')
        )}
    </S.ProfileContentRowData>
)}

We would like to understand why are we getting that error, and whether fetching DateTime values from the backend as Date in the front-end is a good practice or not.

Thank you

1 Answers

whether fetching DateTime values from the backend as Date in the front-end is a good practice or not

It depends on the channel you use between back and front, and the data serialization that channel performs.

In most cases, one uses a standard HTTP request/response with JSON data format.

In that case, Date format is not supported as a type, but converted to string instead (e.g. "2022-09-08T12:34:56Z").

So you will need a conversion first (typically new Date(dateStr) as you have done in your workaround) before formatting.

Related