I’m new to xState state machine library and am trying to implement a database connection and get data states using a third-party library. This library has a connect, disconnect functionality. It publishes 3 events, loginSuccess,
loginFailureand
disconnect`. My state machine initially is in an idle state and on a button click, disconnects all existing connections and initiates a database connection attempt. When successful, it goes into getting data state. Below is my state machine:
const buttonClickMachine = createMachine({ id: 'GetTransactionButtonClick', initial: 'idle', context: { returnCode: undefined, waitTimeInMilliSeconds: _waitTimeInMilliSeconds, arg1: arg1, arg2: arg2, arg3: arg3, errorMessage: undefined }, states: { idle: { on: { BUTTON_CLICK: { target: 'disconnectingDB' } } }, disconnectingDB: { invoke: { src: (context, event) => disconnectDB(context.waitTimeInMilliSeconds), onDone: { target: 'waitingForDBConnection', actions: assign({ returnCode: (context, event) => event.data }) }, onError: { target: 'showingAlert', actions: assign({ errorMessage: (context, event) => event.data }) } } }, gettingTransactions: { invoke: { src: (context, event) => getTransactions(), onDone: { target: 'success', actions: assign({ returnCode: (context, event) => event.data }) }, onError: { target: 'showingAlert', actions: assign({ errorMessage: (context, event) => event.data }) }, on: { REJECT: 'showingDisconnectAlert' } } }, waitingForDBConnection: { invoke: { src: (context, event) => connectDB(context.waitTimeInMilliSeconds, context.arg1, context.arg2, context.arg3), on: { LOGIN_SUCCESS: 'gettingTransactions', LOGIN_FAILURE: { target: 'showingAlert', actions: assign({ errorMessage: (context, event) => event.data }) } }, onError: { target: 'showingAlert', actions: assign({ errorMessage: (context, event) => event.data }) }, on: { REJECT: 'showingDisconnectAlert' } } }, showingAlert: { invoke: { src: (context, event) => showAlert(context.errorMessage), onDone: { target: 'idle' } } }, success: { type: 'final' } } }); const _connectionObject = ConnectionObject.initialize(); const buttonClickService = interpret(buttonClickMachine).start(); function connectDB(waitTimeInMilliSeconds: any, arg1: any, arg2: any, arg3: any) { return new Promise((resolve, reject) => { setTimeout(() => { try { connect(Number(arg1), Number(arg2), Number(arg3)); }); } catch (error) { reject('[ErrorCode:-98] Unable to connect to database server. Please try again'); } }, Number(waitTimeInMilliSeconds)); }); } _connectionObject.on('loginSuccess', function() { buttonClickService.send('LOGIN_SUCCESS'); }); _connectionObject.on('loginFailure', function(errorMessage) { buttonClickService.send('LOGIN_FAILURE', //how do I send the errorMessage as a parameter that I can capture in my connectionToDB state); }); _connectionObject.on('disconnect', function() { console.log('disconnect to db'); buttonClickService.send('REJECT'); });
Any help is appreciated.
Advertisement
Answer
THe event object has data property that can be set. To pass data, I do the following:
buttonClickService.send('LOGIN_FAILURE', { data: errorMessage })