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.
THe event object has data property that can be set. To pass data, I do the following:
buttonClickService.send('LOGIN_FAILURE', { data: errorMessage })