Why cannot I reference a method declared within the same class as XState service? If I move the method outside of the class, it works fine.
export class LoaderMachine {
service = interpret(createMachine<LoaderContext, LoaderEvent, LoaderState>(
{
.....
}, {
actions: {
fetch() {
this.fetchDataInsideClass(); // not callable
fetchData(); // global declaration works
},
restart() {
console.log('Recovering from error')
service.send('RESTART');
},
finished(context, event) {
console.log('Done');
}
}
}));
async fetchDataInsideClass() {
try {
console.log('Started');
service.send('SUCCESS');
} catch (err) {
console.error(`Failed with ${err}`);
service.send('ERROR');
}
}
}
async function fetchData() {
try {
console.log('Started');
service.send('SUCCESS');
} catch (err) {
console.error(`Failed with ${err}`);
service.send('ERROR');
}
}
Results in a compilation error:
TS2349: This expression is not callable.
Not all constituents of type 'AssignActionObject<LoaderContext, LoaderEvent> | ActionObject<LoaderContext, LoaderEvent> | ActionFunction<...>' are callable.
Type 'AssignActionObject<LoaderContext, LoaderEvent>' has no call signatures
CodePudding user response:
The problem in your sample code is that actions.fetch
is a function declaration that will set its execution context (the this
binding) in the runtime depending on how it's called. For more information, check out the MDN reference.
A quick fix is to declare actions.fetch
(and all the other action implementations) as an arrow function that will be bound to the instance of LoaderMachine
class.
actions: {
fetch: () => {
this.fetchDataInsideClass(); // not callable
fetchData(); // global declaration works
},
restart: () => {
console.log("Recovering from error");
service.send("RESTART");
},
finished: (context, event) => {
console.log("Done");
},
},