简体   繁体   中英

ClojureScript - assoc is not working inside a promise

I have an array of art pieces. I want to find the route length and associate it with each art pieces.

My code will look like:

(defn load-art-routes [art-list ctx]
 (doall (map-indexed (fn [index art]
   (let [user-location (select-keys (:coords (sub> ctx :geolocation)) [:latitude :longitude])
         art-location (:geoLocation art)]
       (->> (map-request {:origin (str (:latitude user-location) "," (:longitude user-location))
                     :destination (str (:lat art-location) "," (:lon art-location))
                     :mode (name (sub> ctx :transition-mode))})
             (p/map (fn [data]
                   (let [route-length (ocall js/Math "round" (/ (get-in data [:routes 0 :legs 0 :distance :value]) (* 0.621371192 1000)) 2)
                         route-duration (ocall js/Math "floor" (/ (get-in data [:routes 0 :legs 0 :duration :value]) 60))]
                     (js/console.log "load-art-routes route-length " route-length")
                     (assoc art :route-length route-length))))
             (p/error (fn [error]
                       (util/log (str "GOOGLE DIRECTIONS API ERRORS" params) error)
                       ))))) art-list))
                       art-list)
(defn map-request [params]
 (when params
   (let [endpoint google-directions-api-endpoint]
     (->> (make-get-req (str endpoint "&" (encode-query-params params))
                        {})
          (p/map (fn [data]
                   (util/log "GOOGLE DIRECTIONS API " data)
                   data))
          (p/error (fn [error]
                     (util/log (str "GOOGLE DIRECTIONS API ERRORS" params ) error)
                     ))))))

The route length calculation is correct but, assoc is not working. It is not actually associating it. I don't know what the issue is. Can anyone help me?

Please simplify this example! In the process, you will discover the problem.

First, update your question to include the require that shows what p/map , p/error , etc are. Also, put map-request before load-art-routes just like it must be in your source file.

Then, you should start by removing the thread-last ->> operator and use let with names for intermediate values:

(let [aa (map-request ...)
      bb (p/map (fn [data] ...)   aa)
      cc (p/error (fn [error] ...) bb) ]
  <bb or cc here?> )

My suspicion is that your p/error call is swallowing the results of p/map and returning nil .

This looks like you are trying to write "mutable" code.

Reformatting the code and fixing one error makes this more obvious:

(defn load-art-routes [art-list ctx]
  (doall (map-indexed (fn [index art]
                        (let [user-location (select-keys (:coords (sub> ctx :geolocation)) [:latitude :longitude])
                              art-location (:geoLocation art)]
                          (->> (map-request {:origin (str (:latitude user-location) "," (:longitude user-location))
                                             :destination (str (:lat art-location) "," (:lon art-location))
                                             :mode (name (sub> ctx :transition-mode))})
                               (p/map (fn [data]
                                        (let [route-length (ocall js/Math "round" (/ (get-in data [:routes 0 :legs 0 :distance :value]) (* 0.621371192 1000)) 2)
                                              route-duration (ocall js/Math "floor" (/ (get-in data [:routes 0 :legs 0 :duration :value]) 60))]
                                          (js/console.log "load-art-routes route-length " route-length)
                                          (assoc art :route-length route-length))))
                               (p/error (fn [error]
                                          (util/log (str " GOOGLE DIRECTIONS API ERRORS " params) error)
                                          ))))) art-list))
  art-list)

load-art-routes simply returns the original art-list and kicks of some work in promises. These promises only update their versions of the list but given that we are using immutable data structures the returned art-list themselves remain unchanged. There is also a suspicious second art-list in the p/error call?

You'll probably want to restructure this to something that either returns a Promise or accepts a callback that will be called once all route-length have been computed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM