XState and periodical service invoking

699 views Asked by At

in my React.js application I would like to use XState framework to solve following problem: in specific state I need to fetch data periodically (interval 1 second) and check, if a transition can be launched. I have tested this construct:

// We are waiting for PIN
pinentering: {
    on: {
        // tick event
        TICK: {
            actions: [
                assign({
                    pinSpawn: () => {
                        return spawn({
                            invoke: {
                                id: 'idPinEntering',
                                // Fetch data
                                src: (context, event) => context.tokenService.getSessionStatus(context.sessionId),
                                onDone: [
                                    {
                                        target: 'insertion',
                                        cond: 'readerIsEmpty',
                                        actions: ['storeSessionStatus']
                                    },
                                    {
                                        target: 'busy',
                                        cond: 'readerIsBusy',
                                        actions: ['storeSessionStatus']
                                    }
                                ],
                            }
                        })
                    }
                        
                })
            ]
        }
    },
    // Actions after state entering
    entry: ['onEntryPining']
},
cardempty: ...

If TICK event is received, this error appears: Unable to spawn entity "1" of type "object". My question is: how to periodically invoke services properly?

Thank you a lot,

Mira

1

There are 1 answers

0
David Khourshid On

The syntax is incorrect; invoke is a property of the state config. You can also use after to specify an external transition after 1 second that re-enters the same state.

pinEntering: {
  invoke: {
    id: 'idPinEntering',
    // ...
  },
  after: {
    1000: {
      target: 'pinEntering',
      internal: false // exit and re-enter
    }
  }
}