Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Not a navigator: [object Object] cljs.core/MetaFn #312

Open
eneroth opened this issue Jun 8, 2021 · 8 comments
Open

Error: Not a navigator: [object Object] cljs.core/MetaFn #312

eneroth opened this issue Jun 8, 2021 · 8 comments
Labels

Comments

@eneroth
Copy link

eneroth commented Jun 8, 2021

I'm trying to write a function to replace all instances of a value in a data structure with another value.

Specter is black magic to me, so I started from an example and ended up with this:

(defn deep-replace
  "Given a nested data structure and two values, finds instances of the first
   value and replaces it with the second value.

   Will replace keys."
  [data from to]
  (let [walker (sp/recursive-path [] p
                 (sp/cond-path
                   map?
                   (sp/multi-path
                     [(sp/map-key from)]
                     [sp/MAP-VALS
                      (sp/if-path [(sp/pred= from)]
                        sp/stay-then-continue
                        [p])])
                   sequential?
                   [sp/ALL
                    (sp/if-path [(sp/pred= from)]
                      sp/stay-then-continue
                      [p])]))]
    (sp/setval walker to data)))

It works as I expect in Clojure,

(deep-replace [2 3 4 5 [6 7 8 {:a 2 :b [2 {:c 2 :d 10}]}]
               {#inst "2017" 2}
               {2 2}
               {2 {2 3}}]
  2 "Replaced")

Yields,

["Replaced"
 3
 4
 5
 [6 7 8 {:a "Replaced", :b ["Replaced" {:c "Replaced", :d 10}]}]
 {#inst "2017-01-01T00:00:00.000-00:00" "Replaced"}
 {"Replaced" "Replaced"}
 {"Replaced" {"Replaced" 3}}]

However, in ClojureScript, I get

Error: Not a navigator: [object Object] cljs.core/MetaFn

I thought my data structures in ClojureScript contained something surprising, but it's the case for this as well:

(deep-replace [] 2 "Replaced")

Am I doing something weird in the above function?

@nathanmarz nathanmarz added the bug label Jun 15, 2021
@nathanmarz
Copy link
Collaborator

This looks to be a bug. The fix might be as simple as extending the ImplicitNav protocol to MetaFn like is done already to function. You should be able to try doing that in your own project and see if it fixes it.

@WorldsEndless
Copy link

I have the same error, doing basically the same thing (trying to replace all keyword values within an arbitrarily nested structure. I'm working in CLJC, and it works on the CLJ side but not the CLJS.

@WorldsEndless
Copy link

This looks to be a bug. The fix might be as simple as extending the ImplicitNav protocol to MetaFn like is done already to function. You should be able to try doing that in your own project and see if it fixes it.

I have searched in vain for the example you are talking about, in which the implicitnav function is extended. Can you link where that is done, @nathanmarz ?

@nathanmarz
Copy link
Collaborator

@WorldsEndless https://github.com/redplanetlabs/specter/blob/master/src/clj/com/rpl/specter.cljc#L1252

@WorldsEndless
Copy link

I'm a newbie to programming with protocols and types, so feel pretty clumsy. I can't locate a definition of pred in this, and have scoured the namespace without success:

(extend-type #?(:clj clojure.lang.AFn :cljs cljs.core/MetaFn)
  com.rpl.specter.protocols/ImplicitNav
  (implicit-nav [this] (pred this)))

@WorldsEndless
Copy link

Ah, found pred.

@WorldsEndless
Copy link

WorldsEndless commented Dec 18, 2021

adding the following did indeed fix the issue, so my function now works in both clj and cljs:

(ns foo
  (:require [com.rpl.specter :as s]
            [com.rpl.specter.protocols]))

 (extend-type #?(:clj clojure.lang.AFn :cljs cljs.core/MetaFn)
    com.rpl.specter.protocols/ImplicitNav
    (implicit-nav [this] (s/pred this)))

@dmg46664
Copy link

Got the following error in CLJS when the path wasn't in a vector version 1.1.4.
Thought I'd report it as it's not very clojurey to care that it isn't a vector, but was easily fixed in project code.

      #error {:message "Not a navigator",
              :data {:this
                     (:my/cool
                      "key"),
                     :type-str "cljs.core/Cons"}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants