I'm not really sure if the following solution is the best fit, and I would like to know best practices when manipulating state and/or Ajax isomorphic fetch requests, in this case, in intervals.
Users Module
import { createAction, handleActions } from 'redux-actions'
import { api } from '../utils/api'
export const REPORT_POSITION_INTERVAL = 'REPORT_POSITION_INTERVAL'
export const CLEAR_POSITION_INTERVAL = 'CLEAR_POSITION_INTERVAL'
export const POSITION_UPDATED = 'POSITION_UPDATED'
export const positionUpdated = createAction(POSITION_UPDATED, (value) => value)
export const setReportPositionInterval = createAction(REPORT_POSITION_INTERVAL, (interval) => interval)
export const clearPositionInterval = createAction(CLEAR_POSITION_INTERVAL)
export const reportPosition = () => {
return (dispatch, getState) => {
if (!navigator.geolocation) {
return
}
function success (position) {
var latitude = position.coords.latitude
var longitude = position.coords.longitude
if (getState().user.userId !== null && getState().user.currentCheckup !== null) {
var data = {
lat: latitude,
lng: longitude,
user_id: getState().user.userId,
vehicle_id: getState().user.currentCheckup.vehicle_id
}
api(dispatch, getState, '/api/positions/add', 'POST', data, positionUpdated)
}
}
function error () {
alert('error')
}
if (getState().user.currentCheckup !== null) {
var options = {enableHighAccuracy: true}
navigator.geolocation.getCurrentPosition(success, error, options)
}
}
}
export const reportPositionPeriodically = () => {
return (dispatch, getState) => {
dispatch(setReportPositionInterval(setInterval(() => {
dispatch(reportPosition())
}, 10000)))
}
}
export const actions = {
reportPositionPeriodically,
clearPositionInterval
}
export default handleActions({
[REPORT_POSITION_INTERVAL]: (state, { payload }) => {
return {
...state, reportPositionInterval: payload
}
},
[CLEAR_POSITION_INTERVAL]: (state, { payload }) => {
var clearedInterval = clearInterval(state.reportPositionInterval)
return {
...state, reportPositionInterval: clearedInterval
}
},
[POSITION_UPDATED]: (state, { payload }) => {
return state
}
}, {reportPositionInterval: null})
The reportPositionPeriodically
action is called from the view.
The reportPositionPeriodically()
passes along a setInterval
arrow function to setReportPositionInterval
which keeps the interval in the state and runs reportPosition()
.
reportPosition
calls a function named api()
imported from utils.
Utils API
import fetch from 'isomorphic-fetch'
import config from 'config'
export const api = (dispatch, getState, endpoint, method, data, success)
...
fetch(config.api_host + endpoint + query, params).then((response) => {
dispatch(loaderActions.finished())
return response.json()
}).then((value) => {
if (value.message) {
dispatch(loaderActions.fetchError(value.message))
}
if ((value.code !== undefined && value.code >= 200 && value.code <= 300) || (value.success !== undefined && value.success)) {
dispatch(success(value))
}
})
To clear the timer and stop the fetch requests, I perform a call to clearPositionInterval()
which runs clearInterval
on the interval in the state.
I find redux very hard and I'm having a hard time finding out how to do things properly.