clojureclojurescriptdata-drivenre-frameshadow-cljs

Why does this re-frame command only work when the browser is on a specific local host address? Shouldn't it be just an interface to the the database?


I have been using Clojure, ClojureScript, lein, shadow-cljs, Emacs, and CIDER to work on a Clojure/ClojureScript dynamic web app project.

Usually, I build the project executing command cider-jack-in-cljs in Emacs, choosing shadow-cljs, then shadow for REPL type, and, finally, app for building option.

It works fine. I can watch changes on the UI on localhost:3005.

There is something weird though that I do not understand (take into consideration that I am new to the Clojure stack).

On the REPL I can do:

cljs.user> @(re-frame.core/subscribe [:the-selections])

{:firm "cb08795f-378b-4eb0-9404-ad83b83a8474",
 :active-client "Random-client",
 :active-atb "c6193c35-bf91-4711-8523-d905bd7f0a03"}

The keywords inserted by me and retrieved by the REPL are related to the project.

My doubt is about the fact that this only works if the browser is in a specific page (address). Authentication here is not relevant.

On http://localhost:3005/link/random-numbers-asidadbsadkfbajhksdbf9283492374, it works:

cljs.user> @(re-frame.core/subscribe [:the-selections])

{:firm "cb08795f-378b-4eb0-9404-ad83b83a8474",
 :active-client "Random-client",
 :active-atb "c6193c35-bf91-4711-8523-d905bd7f0a03"}

But, if change the address bar on the Chrome browser to another valid path being properly rendered by the browser: http://localhost:3005/another-path.

And if try the same command, surprisingly the REPL retrieves nil:

cljs.user> @(re-frame.core/subscribe [:the-selections])
nil

Even after authentication and even if the browser address is inside the home page, the command above does not work. It only works after the address is on a specific page.

In addition, based on @ThomasHeller's comment, it seems to be relevant to post how :the-selections is defined. I am not sure this is the root of the definition, but it is my best bet:

(rf/reg-sub
  :the-selections

  ;; Only returns something if all :firm, :active-client, and
  ;; :active-atb are present. :raw-selections defined in
  ;; selections.cljs omits validation if (rarely) needed.  selections
  ;; are only stored locally in re-frame's app-db, not in firebase,
  ;; like :the-client and :the-atb. Minor selections components which
  ;; are not part of the validation are :active-account and :active-je

  (fn [_q _d]
    (rf/subscribe [:raw-selections]))
  (fn [selections _q]
    (tc-selections/valid-selections selections)))

This behavior intrigues me. Isn't a re-frame.core/subscribe an interface to the database?

According to re-frame's documentation:

When a View Function uses a subscription, like this (subscribe [:something :needed]), the sub-graph of nodes needed to service that subscription is created. The necessary sub-graph will "grow backwards" from the View Function all the way to app-db.

If so, why should the address bar on the browser matter after proper build and authentication?


Solution

  • This is impossible to answer without knowing how :the-selections is defined.

    However, a guess would be that the value is provided by the "router". It basically takes the URL and puts some data related to it into the app-db. In case of URIs starting with /link it may be creating the necessary data, while others don't.