Julien Rousé
Julien Rousé

Reputation: 1113

Time interval in clojurescript using Klipse and Reagent going very (too) fast

Hi I'm trying my hand at ClojureScript and I'm using Klipse as my REPL pretty much. It's maybe not it's intended use but because I don't do anything too complicated it's fine for now.

One problem I have is trying to setup a timer. My code is:

(ns my.reagent-examples
  (:require [reagent.core :as r]))

(when-let [element (js/document.getElementById "app")]
  (r/render-component [component] element))

;; State
(def app-state (r/atom 0)) ;; Initial value is 0

;; Increment seconds
(js/setInterval #(swap! app-state inc) 1000) ;; Increment app-state every 1000ms

;; "Seconds elapsed" component 
(defn timer []
  [:div (str "Seconds elapsed: " @app-state)])

It show a timer but it's too fast and seems to accelerate as time goes by. Intended result would be a counter incrementing every second.

My full Klipse file is like this:

<!DOCTYPE html>

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css">
  <script>
    window.klipse_settings = {
      selector: '.language-klipse', // css selector for the html elements you want to klipsify
      selector_reagent: '.language-reagent', // selector for reagent snippets
    };
  </script>
</head>

<body>

  <pre><code class="language-reagent">
(ns my.reagent-examples
  (:require [reagent.core :as r]))
(when-let [element (js/document.getElementById "app")]
  (r/render-component [component] element))
;; State
(def app-state (r/atom 0)) ;; Initial value is 0
;; Increment seconds
(js/setInterval #(swap! app-state inc) 1000) ;; Increment app-state every 1000ms
;; "Seconds elapsed" component 
(defn timer []
  [:div (str "Seconds elapsed: " @app-state)])
</code></pre>

  <script src="https://storage.googleapis.com/app.klipse.tech/plugin/js/klipse_plugin.js"></script>
</body>

(Run the snippet in full page to see the timer)

EDIT: I look like a fool because in the snippet the timer look like it run normally, but when I open the exact same HTML file with Google Chrome or Firefox, the timer goes nuts.. What could be the reason for that?

EDIT2: It seems if you change things on the snippet, you'll see the timer going faster, is that because there it is rendered too many time?

Upvotes: 3

Views: 351

Answers (1)

Piotrek Bzdyl
Piotrek Bzdyl

Reputation: 13175

The issue probably is that when you edit and save your code, it's hot-reloaded in your browser and starts another js/setInterval without stopping the previous one.

You can fix it by calling js/setInterval in defonce definition that will be executed only once on first load and won't be called on reloads:

(defonce timer-increment-interval
  (js/setInterval #(swap! app-state inc) 1000)) ;; Increment app-state every 1000ms

Upvotes: 2

Related Questions