The default value of window.guardian that's injected into the page goes through JSON.strigify, this strips any incompatible keyvalues - namely functions and keys with undefined values.
This is somewhat unexpected! There are a few functions stubbed in createGuardian, that do not actually get on to the page, until they're later added by client side code.
this
{
...
modules: {
// This is a stub for the sentry module, which is later initialised on the client with the `reportError` function.
sentry: {
reportError: () => {},
},
// This is a stub for the abTests module, which is later initialised on the client with the `getParticipations`, `isUserInTest` and `isUserInTestGroup` functions.
abTests: {
getParticipations: () => ({}),
isUserInTest: () => false,
isUserInTestGroup: () => false,
},
},
}
becomes this when stringified:
{"modules":{"sentry":{},"abTests":{}}}`
This led to a hard to track bug in commercial where we expected window.guardian.modules.abTests to be
{
getParticipations: () => ({}),
isUserInTest: () => ({}),
isUserInTestGroup: () => ({}),
} || undefined
but {} wasn't expected!
type-fest has some types to check for this sort of thing, perhaps they could be incorporated to ensure that the returntype of createGuardian is safely serializable?
The default value of
window.guardianthat's injected into the page goes throughJSON.strigify, this strips any incompatible keyvalues - namely functions and keys withundefinedvalues.This is somewhat unexpected! There are a few functions stubbed in
createGuardian, that do not actually get on to the page, until they're later added by client side code.this
becomes this when stringified:
This led to a hard to track bug in commercial where we expected
window.guardian.modules.abTeststo bebut
{}wasn't expected!type-festhas some types to check for this sort of thing, perhaps they could be incorporated to ensure that the returntype ofcreateGuardianis safely serializable?