GithubHelp home page GithubHelp logo

gadfly361 / re-pollsive Goto Github PK

View Code? Open in Web Editor NEW
34.0 3.0 3.0 15 KB

Re-pollsive is a clojurescript library that handles polling events for re-frame applications

License: MIT License

HTML 1.83% Clojure 98.17%
reagent re-frame poll polling repulsive re-pulsive pollsive

re-pollsive's Introduction

re-pollsive

"Everywhere I look, I see the repulsive sight of hundreds, thousands of revolting little children."

  • Grand High Witch, The Witches

re-pollsive is a library that handles polling events for re-frame applications.

[re-pollsive "0.1.0"]

And in your ns:

(ns your-ns
  (:require [re-pollsive.core :as poll]))

The Problem

When you want to poll something, you will likely reach for javascript's setInterval. However, if you aren't careful, it is easy to add a bunch of setIntervals scattered throughout your application. When these setIntervals collide, this can lead to unexpected and hard to debug behavior.

In addition, if you are using a hot-reloading tool (such as figwheel), you will need to proactively defend against unintended setIntervals starting on reload.

Re-pollsive's solution

With re-pollsive, you only set up one setInterval when your application starts, by dispatching ::poll/init. This will start a counter that counts up every second.

Re-pollsive allows you to dynamically define polling rules by dispatching ::poll/set-rules. An interval is defined for each rule, and will be tracked against the aforementioned counter.

In addition, because you are anchoring off of only one setInterval, you can freely use hot-reloading tools (such as figwheel) without any problems.

API

::poll/init

::poll/init starts a counter for your polling rules to hang off of.

Note: This needs to be dispatched only once, when the application first loads.

(re-frame/dispatch-sync [::poll/init])

::poll/set-rules

::poll/set-rules takes a vector of hash-maps with the following shape:

key type default required?
:interval int (seconds) yes
:event re-frame event yes
:poll-when re-frame subscription no
:dispatch-event-on-start? boolean false no

:poll-when is a re-frame subscription vector (e.g. [:should-i-be-polling?]), and its value should be a boolean. :poll-when can be used to effectively start and stop the poller. If you do not supply :poll-when, then the poller will always run.

:dispatch-event-on-start? is a way to dispatch the event at time 0. Say you have an interval of 30, by setting :dispatch-event-on-start? to true, then the event will dispatch at 0 seconds, 30 seconds, 60 seconds, etc. If :dispatch-event-on-start? is false, then the event will dispatch at 30 seconds, 60 seconds, etc. (and not at time 0).

Here is an example:

(re-frame/dispatch
 [::poll/set-rules
  [;; rule #1
   {:interval                 4
    :event                    [::events/log "POLL (every 4 seconds)"]
    :poll-when                [::subs/poll?]
    :dispatch-event-on-start? true}

   ;; rule #2
   {:interval                 6
    :event                    [::events/log "POLL (every 6 seconds)"]
    :poll-when                [::subs/poll?]
    :dispatch-event-on-start? false}
   ]])

Usage

Create a new re-frame application.

lein new re-frame foo

Add the following to the :dependencies vector of your project.clj file.

[re-pollsive "0.1.0"]

Then require re-pollsive in the core namespace, and add the ::poll/init event.

(ns foo.core
  (:require [reagent.core :as reagent]
            [re-frame.core :as re-frame]

            ;; Add this (1 of 2)
            [re-pollsive.core :as poll]

            [foo.events :as events]
            [foo.views :as views]
            [foo.config :as config]
            ))

(defn dev-setup []
  (when config/debug?
    (enable-console-print!)
    (println "dev mode")))

(defn mount-root []
  (re-frame/clear-subscription-cache!)
  (reagent/render [views/main-panel]
                  (.getElementById js/document "app")))

(defn ^:export init []
  (re-frame/dispatch-sync [::events/initialize-db])

  ;; And this (2 of 2)
  (re-frame/dispatch-sync [::poll/init])

  (dev-setup)
  (mount-root))

Next, you will need to dispatch a ::poll/set-rules event somewhere. Personally, I like dispatching this in my routes file (because I may want to handle polling events differently on each page).

Non-goals

  • A perfectly accurate counter. The internal counter is not intended to be perfectly accurate. For example, if you set an interval to 30, expect the event to be dispatched roughly every 30 seconds, but not exactly. In other words, don't use re-pollsive for a clock.
  • Handling really quick events. The choice of having the :interval be measured in seconds as opposed to milliseconds was intentional. If you want to dispatch events with millisecond granularity, you are likely better off using a one-off setTimeout.

Questions

If you have questions, I can usually be found hanging out in the clojurians #reagent slack channel (my handle is @gadfly361).

License

Copyright © 2018 Matthew Jaoudi

Distributed under the The MIT License (MIT).

re-pollsive's People

Contributors

gadfly361 avatar maacl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

re-pollsive's Issues

Console Logging

Hello,

Thank you for this very useful library. I have a quick question. Is there a way to turn off logging to console? Sometimes it's helpful but other times it is a lot of noise.

Thanks!

Error: "got a function instead of an interceptor"

re-frame: when registering Object { ns: null, name: "poll-server", fqn: "poll-server", _hash: -733466844, "cljs$lang$protocol_mask$partition0$": 2153775105, "cljs$lang$protocol_mask$partition1$": 4096 } , got a function instead of an interceptor. Did you provide old style middleware by mistake? Got: function ()

Either this repo or the README instructions need an update to work with the latest software patterns re-frame is using :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.