interop – How to work with javascript promises in clojurescript?

I have a problem with js promises:
I am trying to convert this js code:

stripe.createToken(card).then(function(result) {
    if (result.error) {
      // Inform the customer that there was an error.
      var errorElement = document.getElementById('card-errors');
      errorElement.textContent = result.error.message;
    } else {
      // Send the token to your server.
      stripeTokenHandler(result.token);
    }

And I have the following:

(go
     (let (result (

But I get "No ReadPort.take protocol method! Defined for object type: (object promise)"

How can I do the js .then () part in cljs?

clojure – n-jigsaw puzzle in Clojurescript

I am creating an n-puzzle solver in Clojurescript. The base model is operational and I can move mosaics on the screen. I plan to implement A * or such an algorithm to solve a given puzzle. Before doing that, I welcome any general comments to improve the quality of the code for the moment.

I'm just pasting the most important files only here. The whole report is here

puzzle.cljs

                (ns npuzzle.puzzle
(:require [cljs.test :refer-macros [deftest testing is run-tests]]
                [clojure.zip :as zip]))

(defn get-tiles [puzzle] (nth enigma 0))
(defn get-size [puzzle] (nth puzzle 1))

(defn set-tiles [puzzle tiles] (assoc puzzle 0 tiles))

(defn make-puzzle
([size]
       [(conj (vec (range 1 (* size size))) :space) size])
([tiles size]
       [tiles size]))

(defn index-> ​​row-col [puzzle index]
      (let [size (get-size puzzle)]
        [(quot index size) (mod index size)]))

(defn row-col-> index [puzzle [row col]](let [size (get-size puzzle)]
        (+ (* size of the line) col)))

(defn get-tile [puzzle [row col]](((get-tiles puzzle) (+ (* row (get-size puzzle)) col)))

(defn get-index-of-space [puzzle]
      (.indexOf (get-tiles puzzle): space))

(defn get-space-coords [puzzle]
      (index-> ​​row-col puzzle (get-index-of-space puzzle)))

(defn is-space? [puzzle coords]
      (=: space (get-tile puzzle coordinates)))

(defn valid-coords? [puzzle [row col]](let [size (get-size puzzle)]
        (and (> = row 0) (> = pass 0)
(<size of the line) (< col size))))

    (defn get-adjacent-coords [puzzle [row col]]
      (->> & # 39;[0 1] [-1 0] [0 -1] [1 0]) ;; & # 39;
(map (fn [[dr dc]]
                  [(+ row dr) (+ col dc)]))
(filter # (valid-coords? puzzle%))))

(inversions defn [puzzle]
      (let [size (get-size puzzle)
            tiles (get-tiles puzzle)
            inversions-fn
            (fn [remaining-tiles found-tiles inversions]
              (If-let [i (first remaining-tiles)]
                (recurrence (remaining tiles remaining)
(conj-found-tiles i)
(+ inversions (- (dec i) (count (found filters) (range i))))))
inversions))](inversions-fn (remove # {: space} tiles) # {} 0)))

(is it solvable? [puzzle]
      (let [inv-cnt (inversions puzzle)
            size (get-size puzzle)
            [row col] (get-space-coords puzzle)](if (odd? size)
(same? inv-cnt)
(if (same? (- row size))
(odd? inv-cnt)
(even? inv-cnt)))))

(defn can-move? [puzzle coords]
      Check if any of the adjacent tiles match the space.
(- >> (get-adjacent-coords puzzle jigsaw)
(filter # (is-space? puzzle%))
(first)))

(defn swap-tiles [puzzle coord1 coord2]
      (let [index1 (row-col->index puzzle coord1)
            index2 (row-col->index puzzle coord2)
            tile1 (get-tile puzzle coord1)
            tile2 (get-tile puzzle coord2)
            tiles (get-tiles puzzle)]
        (puzzle set-slabs
(-> tiles
(assoc index1 tile2)
(assoc index2 tile1)))))

(defn move [puzzle coords]
      (if (can you move puzzles)
(swap puzzle tiles with coords (get-space-coords puzzle))
puzzle))

(defn random-move [puzzle]
      (let [space-coords (get-space-coords puzzle)
            movable-tiles (get-adjacent-coords puzzle space-coords)
            random-movable-tile (nth movable-tiles (rand-int (count movable-tiles)))]
        (move the random-mobile-tile puzzle)))

(defn shuffle puzzle
"Shuffles by moving a random step"
([puzzle]
       (let [num-moves (+ 100 (rand 200))]
         (shuffle-puzzle num-move puzzle)))
([puzzle num-moves]
       (if (> num-move 0)
(recurs (puzzle of random movements) (dec num-movements))
puzzle)))

puzzle_test.cljs

(ns npuzzle.puzzle-test
(:require [cljs.test :refer-macros [deftest testing is run-tests]]
            [npuzzle.puzzle :as pzl]))

(skillful puzzle tests
(let [p1 (pzl/make-puzzle 3)]
    (test "make the puzzle"
(is (= [1 2 3 4 5 6 7 8 :space] (pzl / get-tiles p1)))
(is (= 3 (pzl / get-size p1))))
(tests "get-tile"
(is (= 1 (pzl / get-tile p1 [0 0])))
(is (= 2 (pzl / get-tile p1 [0 1])))
(is (= 5 (pzl / get-tile p1 [1 1]))))
("get-index-of-space" test
(is (= 8 (pzl / get-index-of-space p1)))))
("get-space-coords" test
(is (= [2 2] (pzl / get-space-coords p1))))
(tests "is-space?"
(is (pzl / is-space? p1 [2 2]))
(is (not (pzl / is-space? p1 [2 1]))))
(tests "index-> ​​row-col"
(is (= [1 1] (pzl / index-> ​​row-col p1 4)))
(is (= [2 3] (pzl / index-> ​​line-pass (pzl / make-puzzle 5) 13))))
(test of "row-col-> index"
(is (= 4 (pzl / row-col-> index p1) [1 1])))
(is (= 13 (pzl / row-col-> index (pzl / make-puzzle 5)) [2 3]))))
(test "valid coords?"
(is (pzl / valid-coords? p1 [1 1]))
(is (not (pzl / valid-coords? p1) [2 3]))))
("get-adjacent-coords" test
(is (= # {[0 1] [1 0] [1 2] [2 1]} (in # {} (pzl / get-adjacent-coords p1 [1 1]))))
(is (= # {[0 1] [1 0]} (in # {} (pzl / get-adjacent-coords p1 [0 0])))))
(test "can you move?"
(is (pzl / can-move? p1 [1 2]))
(is (pzl / can-move? p1 [2 1]))
(is (not (pzl / can-move? p1 [1 1]))))
(test "move"
(is (= [1 2 3 4 5 :space 7 8 6] (pzl / get-tiles (pzl / move p1 [1 2]))))
(is (= [1 2 3 4 :space 5 7 8 6] (pzl / get-tiles (pzl / move (pzl / move p1) [1 2]) [1 1]))))
(is (= [1 2 3 4 5 6 7 8 :space] (pzl / get-tiles (pzl / move p1 [0 1])))))
("inversions" test
(is (= 10 (pzl / inversions (pzl / make-puzzle) [1 8 2 :space 4 3 7 6 5] 3))))
(is (= 41 (pzl / inversions (pzl / make-puzzle) [13 2 10 3 1 12 8 4 5 :space 9 6 15 14 11 7] 4))))
(is (= 62 (pzl / inversions (pzl / make-puzzle) [6 13 7 10 8 9 11 :space 15 2 12 5 14 3 1 4] 4))))
(is (= 56 (pzl / inversions (pzl / make-puzzle) [3 9 1 15 14 11 4 6 13 :space 10 12 2 7 8 5] 4)))))
(test "is it soluble?"
(is (pzl / is it soluble? (pzl / make-puzzle [1 8 2 :space 4 3 7 6 5] 3)))
(is (pzl / is it soluble? (pzl / make-puzzle [13 2 10 3 1 12 8 4 5 :space 9 6 15 14 11 7] 4)))
(is (pzl / is it soluble? (pzl / make-puzzle [6 13 7 10 8 9 11 :space 15 2 12 5 14 3 1 4] 4)))
(is (no (pzl / is it soluble? [3 9 1 15 14 11 4 6 13 :space 10 12 2 7 8 5] 4)))))
("shuffle-puzzle" test
(is pzl / is soluble? (pzl / shuffle-puzzle (pzl / make-puzzle 4)))))
(is (pzl / is soluble? (pzl / shuffle-puzzle (pzl / make-puzzle 6)))))
(is pzl / is soluble? (pzl / shuffle-puzzle (pzl / make-puzzle 9)))))
(is (not = (pzl / shuffle-puzzle (pzl / make-puzzle 3))) (pzl / make-puzzle 3)))
(is (not = (pzl / shuffle-puzzle (pzl / make-puzzle 8)) (pzl / make-puzzle 8))))))

(functional tests)

views.cljs

(ns npuzzle.views
(:require
   [re-frame.core :as re-frame]
   [npuzzle.subs :as subs]
   [npuzzle.events :as ev]))

(Defn-on-puzzle-size-modified [e]
  (crop / send [::ev/change-puzzle-size (int (-> e .-target .-value))]))

(defn-on-tile-mouse-down [e]
  (let [idx (.getAttribute (-> e .-target) "data-tileindex")]
    (crop / send [::ev/move-tile (int idx)])))

(defn-tile-div [idx tile]
  [:div {:style {:text-align :center
                 :padding "15px"
                 :font-size "20px"
                 :border (if (not= :space tile) "1px solid black" :none)
                 :background (if (not= :space tile) :lightblue nil)
                 :height "25px"
                 :width "25px"
                 ;;cursor = default for disabling caret on hover over text
                 :cursor :default}
         :onMouseDown on-tile-mouse-down
         :data-tileindex idx}
   (if (= :space tile)
     " "
     tile)])

(defn-tiles-container [puzzle size tile-fn]
  (in [:div {:style {:display :inline-grid
                       :grid-template-columns (apply str (repeat size "auto "))
                       :grid-gap "2px"
                       :border "2px solid black"}}]
        (indexed on the map
(fn [idx tile]
           (tile-fn idx tile)) puzzle)))

(defn hand-panel []
  (let [name (re-frame/subscribe [::subs/name])
sizes (crop / subscribe [::subs/size-choices])
current size (re-frame / subscribe [::subs/puzzle-size])
puzzle (crop / subscribe [::subs/puzzle])]
    [:div
     [:h1 "Hello to " @name]
     [:div
      {:style {:padding "10px"}}
      (into [:select {:name "puzzle-size"
                      :on-change on-puzzle-size-changed
                      :defaultValue @current-size}]
            
            
            
            (for [size @sizes]
              (in [:option {:value size} size])))](tiles-container @ puzzle @ current-size tile-div)]))