date-fns: Can't resolve RangeError: Format string contains an unescaped latin alphabet character `n`
Currently facing this error from a functional component using date-fns. Here is the component I created.
`import 'date-fns';
import React, { useState } from "react";
import Grid from '@material-ui/core/Grid';
import DateFnsUtils from '@date-io/date-fns';
import {
MuiPickersUtilsProvider,
KeyboardDatePicker,
} from '@material-ui/pickers';
const DatePicker = ({ date, onChange,label})=> {
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Grid container justify="space-around">
<KeyboardDatePicker
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
label={label}
value={date}
onChange={onChange}
KeyboardButtonProps={{
'aria-label': 'change date',
}}
/>
</Grid>
</MuiPickersUtilsProvider>
);
}
export default DatePicker;`
Then I call the components and provide the props I declared.
import React, { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import DatePicker from "../artifacts/Calendar/Calendar";
const defaultValues = {
StartDate: "",
EndDate: "",
TextField: "",
Select: "",
Checkbox: false,
PlatformToSearch: "",
};
const SearchBar =()=> {
const [data, setData] = useState(null);
const { handleSubmit, register, reset, control } = useForm({ defaultValues });
const [selectedStartDate, setSelectedStartDate] = useState(new Date('2014-08-18T21:11:54'));
const handleStartDateChange = (date) => {
setSelectedStartDate(date);
};
const onSubmit = data => {
console.log("Data:",data)
setData(data)
};
return (
<div>
<form onSubmit={handleSubmit(data => onSubmit(data))}>
<div className="flex">
<DatePicker
label="START DATE"
value={selectedStartDate}
onChange={handleStartDateChange}
/>
</div>
</form>
</div>
);
}
export default SearchBar;
package.json
`
"dependencies":
{
"@brightleaf/react-hooks": "^4.2.0",
"@date-io/date-fns": "1.3.13",
"@material-ui/core": "^4.0.0-rc.0",
"@material-ui/pickers": "^3.2.10",
"date-fns": "2.13.0",
"isomorphic-unfetch": "^3.0.0",
"react": "^16.13.1",}`
Any help is appreciated
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 15
- Comments: 18 (3 by maintainers)
Any luck with this error?
I debugged the provided codesandbox and concluded that this is not a bug in the date-fns code.
The React code eventually provides date-fns
format()functionundefinedas the second parameter; however, the second parameter is required and should be a format string of type String.In the codesandbox demo the
format()function convertsundefinedto a string with a text value ofundefined. Then the format string validation block executes against the string valueundefinedas the format string, one character at a time. Theucharacter is considered a valid format character (determined bylongFormattingTokensRegExp) butnis not, so aRangeErroris thrown mentioning the latin charactern.An improvement would be for date-fns
format()to check the type of the second parameter to ensure that it is of typestringand non-empty.@roysantu2002
I think it was explained well already here https://github.com/date-fns/date-fns/issues/1857#issuecomment-807272204 but I wanted to add a few things.
The
formatfunction requires you to wrap non-token latin characters (a-zA-Z) in single quotes if you want to use those as literals. The secondformatargument gets converted to a string right away internally. If that argument isnullorundefined, it will become the string"null"or"undefined"and throw a RangeError because of the presence of the non-tokenncharacter in those words.https://github.com/date-fns/date-fns/blob/ea3f05069605388af0bb6a27f8cf4539f3d70db6/src/format/index.js#L348-L351
Couple scenarios with v2:
@kossnocorp A TypeError is thrown when the second argument is missing. Here, I think the issue is that you’ll get this seemingly unrelated RangeError when the format string is
nullorundefined(see above). So while it’s not a bug in the library, that internal string conversion is a bit sneaky and ends up obfuscating the real root cause of the bug in the program using the library.I wanted to make a suggestion. Wouldn’t removing the string conversion in
formatpotentially be a win for everyone? One less runtime check/conversion (it was no-op for the happy path anyways). Let it fail if it’s not a proper string, at least the runtime error would be easier to comprehend from a developer’s perspective. I believe it would fail on a.match()call internally, so they would receive something more logical likeTypeError: Cannot read property 'match' of nullinstead.I can confirm this is not fixed even with release
2.22.1.@Dinnall, check out the demo: https://codesandbox.io/s/z9k3z
Your version of
date-fnsdoesn’t match the demo’s. That might be it.✅ For me, the only solution was downgrading the
@date-io/date-fnsversion usingyarn add @date-io/date-fns@1.3.13ornpm i @date-io/date-fns@1.3.13.It seems working just with the
V1.3.13but not with the version 2.I found if I use @date-io/date-fns2.x , there will truely occur the problem ‘Can’t resolve RangeError: Format string contains an unescaped latin alphabet character n’, and when I downgraded the version to 1.3.13, this problem has gone, but I meet another problem like ‘Can’t resolve RangeError: Format string contains an unescaped latin alphabet character
o’,and it’s not every time, but occasionally, does anybody meet the same problem like me? I don’t know why and I wanna find the solution to fix this problem, thanks.Hey everyone, sorry for the confusion. As @JeffBudaTR noted, this is not a date-fns issue. I can’t see the issue in the provided Sandbox, but I understand it correctly, date-fns throws an error when the
formatprop is missing. I would recommend opening an issue in Material UI and ask them to provide prop types for the component in question. Additionally, I would make sure that TypeScript definitions are present.Regarding the @JeffBudaTR’s suggestion to validate the arguments. The thing is that we don’t want to make any runtime checks because those who want to have type safety can use TypeScript/Flow definitions, and runtime checks add a lot of extra bytes to the library, and one of our main goals is to make date-fns as light as possible.
I know that we have some runtime checks in the code already, but we will remove those upon complete transition to TypeScript in v3.
Please let us know if there’s anything else we can do.