I created a button to create a fence with 50,200,500 meters. It works perfectly, but the circle only appears after refreshing the page, so I used the window.location.reload(); function, but I didn't want to keep refreshing the page every time I create or remove the anchor.
Below is my code, can someone help me see why the geofence circle doesn't appear as soon as it is created?
const StatusCard = ({ deviceId, position, onClose, disableActions, desktopPadding = 0 }) => {
const classes = useStyles({ desktopPadding });
const navigate = useNavigate();
const dispatch = useDispatch();
const t = useTranslation();
const deviceReadonly = useDeviceReadonly();
const shareDisabled = useSelector((state) => state.session.server.attributes.disableShare);
const user = useSelector((state) => state.session.user);
const device = useSelector((state) => state.devices.items[deviceId]);
const deviceImage = device?.attributes?.deviceImage;
const positionAttributes = usePositionAttributes(t);
const positionItems = useAttributePreference('positionItems', 'fixTime,address,speed,totalDistance');
const [removing, setRemoving] = useState(false);
const [snackbarOpen, setSnackbarOpen] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState('');
const [snackbarSeverity, setSnackbarSeverity] = useState('success');
const [anchorEl, setAnchorEl] = useState(null);
const [geofence, setGeofence] = useState(null);
const [geofenceDistance, setGeofenceDistance] = useState(null);
const [geofenceDialogOpen, setGeofenceDialogOpen] = useState(false);
const [isEngineBlocked, setIsEngineBlocked] = useState(false);
const checkExistingGeofence = useCatchCallback(async () => {
if (!position || !position.latitude || !position.longitude) return;
const response = await fetch(`/api/geofences?lat=${position.latitude}&long=${position.longitude}`);
if (response.ok) {
const geofences = await response.json();
if (geofences.length > 0) {
setGeofence(geofences[0]);
}
}
});
useEffect(() => {
checkExistingGeofence();
}, [position]);
const handleRemove = useCatch(async (removed) => {
if (removed && geofence) {
const response = await fetch(`/api/geofences/${geofence.id}`, { method: 'DELETE' });
if (!response.ok) {
const errorText = await response.text();
setSnackbarMessage(errorText || t('geofenceError'));
setSnackbarSeverity('error');
setSnackbarOpen(true);
return;
}
setGeofence(null);
setSnackbarMessage('Anchored successfully!');
setSnackbarSeverity('success');
setSnackbarOpen(true);
window.location.reload()
}
});
const handleCreateRemoveGeofence = useCatchCallback(async () => {
if (geofence) {
const confirmation = window.confirm('Do you want to remove the anchor?');
if (confirmation) {
await handleRemove(true);
}
return;
}
if (!position || !position.latitude || !position.longitude) {
setSnackbarMessage(t('geofencePositionError'));
setSnackbarSeverity('error');
setSnackbarOpen(true);
return;
}
setGeofenceDialogOpen(true);
}, [geofence, position]);
const handleGeofenceDistanceChange = (event) => {
setGeofenceDistance(event.target.value); };
const handleCreateGeofence = async() => {
if (!geofenceDistance) {
setSnackbarMessage('Please select a distance!');
setSnackbarSeverity('error');
setSnackbarOpen(true);
return;
}
const newItem = {
name: t('sharedGeofence'),
area: `CIRCLE (${position.latitude} ${position.longitude}, ${geofenceDistance})`,
};
const response = await fetch('/api/geofences', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newItem),
});
if (!response.ok) {
const errorText = await response.text();
setSnackbarMessage(errorText || t('geofenceError'));
setSnackbarSeverity('error');
setSnackbarOpen(true);
return;
}
const createdGeofence = await response.json();
setGeofence(createdGeofence);
setSnackbarMessage('Anchor created successfully!');
setSnackbarSeverity('success');
setSnackbarOpen(true);
setGeofenceDialogOpen(false);
window.location.reload()
};
You should add your geofence locally or refresh the whole store.
I don't know if I understand, or what to actually do to resolve this.
I created a button to create a fence with 50,200,500 meters. It works perfectly, but the circle only appears after refreshing the page, so I used the window.location.reload(); function, but I didn't want to keep refreshing the page every time I create or remove the anchor.
Below is my code, can someone help me see why the geofence circle doesn't appear as soon as it is created?
const StatusCard = ({ deviceId, position, onClose, disableActions, desktopPadding = 0 }) => { const classes = useStyles({ desktopPadding }); const navigate = useNavigate(); const dispatch = useDispatch(); const t = useTranslation(); const deviceReadonly = useDeviceReadonly(); const shareDisabled = useSelector((state) => state.session.server.attributes.disableShare); const user = useSelector((state) => state.session.user); const device = useSelector((state) => state.devices.items[deviceId]); const deviceImage = device?.attributes?.deviceImage; const positionAttributes = usePositionAttributes(t); const positionItems = useAttributePreference('positionItems', 'fixTime,address,speed,totalDistance'); const [removing, setRemoving] = useState(false); const [snackbarOpen, setSnackbarOpen] = useState(false); const [snackbarMessage, setSnackbarMessage] = useState(''); const [snackbarSeverity, setSnackbarSeverity] = useState('success'); const [anchorEl, setAnchorEl] = useState(null); // State of the options menu const [geofence, setGeofence] = useState(null); // Geofence status const [geofenceDistance, setGeofenceDistance] = useState(null); // To store the selected distance const [geofenceDialogOpen, setGeofenceDialogOpen] = useState(false); // To control the popup const [isEngineBlocked, setIsEngineBlocked] = useState(false); // Status for blocking/unblocking the engine const checkExistingGeofence = useCatchCallback(async () => { if (!position || !position.latitude || !position.longitude) return; const response = await fetch(`/api/geofences?lat=${position.latitude}&long=${position.longitude}`); if (response.ok) { const geofences = await response.json(); if (geofences.length > 0) { setGeofence(geofences[0]); } } }); useEffect(() => { checkExistingGeofence(); }, [position]); const handleRemove = useCatch(async (removed) => { if (removed && geofence) { const response = await fetch(`/api/geofences/${geofence.id}`, { method: 'DELETE' }); if (!response.ok) { const errorText = await response.text(); setSnackbarMessage(errorText || t('geofenceError')); setSnackbarSeverity('error'); setSnackbarOpen(true); return; } setGeofence(null); setSnackbarMessage('Anchored successfully!'); setSnackbarSeverity('success'); setSnackbarOpen(true); window.location.reload() } }); const handleCreateRemoveGeofence = useCatchCallback(async () => { if (geofence) { const confirmation = window.confirm('Do you want to remove the anchor?'); if (confirmation) { await handleRemove(true); } return; } if (!position || !position.latitude || !position.longitude) { setSnackbarMessage(t('geofencePositionError')); setSnackbarSeverity('error'); setSnackbarOpen(true); return; } setGeofenceDialogOpen(true); // Opens the dialog to select the distance }, [geofence, position]); const handleGeofenceDistanceChange = (event) => { setGeofenceDistance(event.target.value); }; const handleCreateGeofence = async() => { if (!geofenceDistance) { setSnackbarMessage('Please select a distance!'); setSnackbarSeverity('error'); setSnackbarOpen(true); return; } const newItem = { name: t('sharedGeofence'), area: `CIRCLE (${position.latitude} ${position.longitude}, ${geofenceDistance})`, }; const response = await fetch('/api/geofences', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newItem), }); if (!response.ok) { const errorText = await response.text(); setSnackbarMessage(errorText || t('geofenceError')); setSnackbarSeverity('error'); setSnackbarOpen(true); return; } const createdGeofence = await response.json(); setGeofence(createdGeofence); setSnackbarMessage('Anchor created successfully!'); setSnackbarSeverity('success'); setSnackbarOpen(true); setGeofenceDialogOpen(false); // Close the dialog window.location.reload() };