I am trying to change the status of the button when the user clicks, it's all part of the xstate, where the buttons are getting, according to the State the button is going to work.in typescript, it's working fine but not in react hooks
const ProjectStatus = {
UN_ASSIGNED: 'UN_ASSIGNED',
ASSIGNED: 'ASSIGNED',
CHECKED_OUT: 'CHECKED_OUT',
CHECKED_IN: 'CHECKED_IN',
QC_START: 'QC_START',
QC_FAIL: 'QC_FAIL',
QC_PASS: 'QC_PASS',
CUSTOMER_REVIEW: 'CUSTOMER_REVIEW',
CUSTOMER_REJECT: 'CUSTOMER_REJECT',
RE_ASSIGN: 'RE_ASSIGN',
HOLD: 'HOLD',
DONE: 'DONE',
CUSTOMER_APPROVE: 'CUSTOMER_APPROVE'
};
function MachineButton() {
const classes = useStyles();
const dispatch = useDispatch();
const params = useParams();
const [anchorEl, setAnchorEl] = useState(false);
const [current, send] = useState({ ...ProjectStatus });
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const projectEntity = useSelector((states) => (states.taskDetails.entity));
useEffect(() => {
dispatch(getTaskById(params.id));
}, []);
const toggleMachine = (currentState, action) => {
const nextState = machine.transition(currentState, action);
if (currentState !== nextState.value) {
send(ProjectStatus[nextState.value]);
dispatch(updateTask({ ...projectEntity }));
}
};
const getButton = (currentState) => {
if (currentState !== undefined) {
const nextStates = machine.states[currentState].on;
if (Object.keys(nextStates).length !== 0) {
return (
<div>
<Button
color="primary"
variant="contained"
aria-controls="simple-menu"
aria-haspopup="true"
onClick={handleClick}
>
{Object.keys(nextStates)[0]}
</Button>
<Menu
id="lock-menu"
anchorEl={anchorEl}
keepMounted
getContentAnchorEl={null}
open={Boolean(anchorEl)}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
{Object.keys(nextStates).map((action, index) => (
<MenuItem
key={action}
selected={index === currentState}
onClick={() => toggleMachine(currentState, action)}
>
{action}
</MenuItem>
))}
</Menu>
</div>
);
}
}
};
return (
<div className={classes.actions}>
{getButton(projectEntity.status)}
</div>
);
}
export default MachineButton;
I am getting status is undefined but when I reload the button, the values are updating
this is the error I am getting.
TypeError: Cannot read property 'status' of undefined
181 |
182 |
183 | return (
> 184 | <div className={classes.actions}>
| ^ 185 | {getButton(projectEntity.status)}
186 | </div>
187 |
Is there something that I missed out, kindly do rectify, what else do I need
It might happen because when code gonna get to getButton(projectEntity.status)
, projectEntity
useSelector
result still haven't calculated, and therefore it still undefined. Just add an || {}
to your decoration to avoid it
const projectEntity = useSelector((states) => (states.taskDetails.entity)) || {}
Or checker before activation
projectEntity && getButton(projectEntity.status)