Redux isomorphic fetch in interval 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) =&gt; value)
export const setReportPositionInterval = createAction(REPORT_POSITION_INTERVAL, (interval) =&gt; interval)
export const clearPositionInterval = createAction(CLEAR_POSITION_INTERVAL)

export const reportPosition = () =&gt; {
  return (dispatch, getState) =&gt; {
    if (!navigator.geolocation) {
      return
    }

    function success (position) {
      var latitude = position.coords.latitude
      var longitude = position.coords.longitude

      if (getState().user.userId !== null &amp;&amp; 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 = () =&gt; {
  return (dispatch, getState) =&gt; {
    dispatch(setReportPositionInterval(setInterval(() =&gt; {
      dispatch(reportPosition())
    }, 10000)))
  }
}


export const actions = {
  reportPositionPeriodically,
  clearPositionInterval
}


export default handleActions({
  [REPORT_POSITION_INTERVAL]: (state, { payload }) =&gt; {
    return {
      ...state, reportPositionInterval: payload
    }
  },
  [CLEAR_POSITION_INTERVAL]: (state, { payload }) =&gt; {
    var clearedInterval = clearInterval(state.reportPositionInterval)
    return {
      ...state, reportPositionInterval: clearedInterval
    }
  },
  [POSITION_UPDATED]: (state, { payload }) =&gt; {
    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) =&gt; {
    dispatch(loaderActions.finished())
    return response.json()
}).then((value) =&gt; {
    if (value.message) {
        dispatch(loaderActions.fetchError(value.message))
    }
    if ((value.code !== undefined &amp;&amp; value.code &gt;= 200 &amp;&amp; value.code &lt;= 300) || (value.success !== undefined &amp;&amp; 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.
It looks OK, but I would just return the promise from the api module, and handle the errors, success and so on in the place where redux lives.. namely in reportPositionPeriodically

This way your API-module will be smaller and more reusable, for instance:


  I find redux very hard and I'm having a hard time finding out how to do things properly.


you could replace it later, but the api methods would still work ;)
If you do so, you also have a better overview of your state and whats happening to your store