helpers.fake - patterns after root expression fail when referencing instance members
#3465 opened on Apr 4, 2025
Description
Pre-Checks
- Follow our Code of Conduct.
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Faker issue and not related to a combination with another package.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
- I am willing to provide a PR.
Describe the bug
What I am doing
I am trying to call instance methods of returned generated values from within a helpers.fake expression, for example '{{number.int.toPrecision}}'. The call failed, which led me down a rabbit hole of trying to figure out why. It turns out that, in many cases, referencing instance/prototype functions of the returned expression value in a pattern fails because the function is not setting this when being called.
What's more, the way it fails depends on how the expression is formatted. If the expression uses function shorthand syntax ('number.int.toPrecision'), the fake will fail due to the aforementioned bug of this not getting set. However, if the expression uses parameterized syntax ('number.int(100).toPrecision'), the fake will fail due to the expression not being resolvable. It's also worth noting that in this latter case, properties will also fail. (i.e. 'string.alpha.length' will succeed, but 'string.alpha(10).length' will fail.)
What I expected
Referencing an instance methods/prototype functions in an expression pattern to further modify the generated value.
What actually happened
Referencing an instance methods/prototype functions in an expression pattern results in an error. (The specific error depends on the type of the instance involved and format of the expression. See minimum reproduction.)
Minimal reproduction code
These expressions will all result in various errors that essentially boil down to "this is undefined":
const expNotation = faker.helpers.fake('{{number.int.toPrecision(2)}}'); // Number.prototype.toPrecision requires that 'this' be a Number
const trimmed = faker.helpers.fake('{{string.alpha.trim}}'); // String.prototype.trim called on null or undefined
const isoTimestamp = faker.helpers.fake('{{date.anytime.toISOString}}'); // Method Date.prototype.toISOString called on incompatible receiver undefined
These expressions will all result in "Cannot resolve expression ''":
const expNotation = faker.helpers.fake('{{number.int(100).toPrecision(2)}}');
const trimmed = faker.helpers.fake('{{string.alpha(5).trim}}');
const isoTimestamp = faker.helpers.fake('{{date.anytime({"refDate": 1735714800000}).toISOString}}');
const stringLength = faker.helpers.fake('{{string.alpha(10).length}}');
Additional Context
The impetus for this ticket was that I was trying to convert a Date object returned from a date expression (e.g. date.anytime) to an ISO timestamp within the resulting string using '{{date.anytime.toISOString}}'. The reason I cannot use alternative approaches (such as using helpers.mustache and passing the timestamp in as a parameter) is because I am using a utility I created that uses a JSON template object with properties defined using expression strings to generate entire complex objects.
Environment Info
System:
OS: macOS 15.4
CPU: (14) arm64 Apple M3 Max
Memory: 1.52 GB / 96.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.13.1 - ~/.asdf/installs/nodejs/22.13.1/bin/node
npm: 10.9.2 - ~/.asdf/installs/nodejs/22.13.1/bin/npm
pnpm: 10.5.2 - ~/.asdf/installs/nodejs/22.13.1/bin/pnpm
Browsers:
Chrome: 135.0.7049.41
Safari: 18.4
Which module system do you use?
- CJS
- ESM
Used Package Manager
pnpm