Значение атома реагента остается нулевым после функции сброса - PullRequest
0 голосов
/ 25 марта 2020

Я сделал API конечной точки сервиса для получения одного объекта по идентификатору, и он работает как положено. Я проверил это с почтальоном и в функции обработчика. Я использую библиотеку cl js - ajax для асинхронного клиента. Я не могу изменить состояние атома реагента, когда получаю ответ. Вот код:

(ns businesspartners.core
  (:require [reagent.core :as r]
            [ajax.core :refer [GET POST]]
            [clojure.string :as string]))

(def business-partner (r/atom nil))

(defn get-partner-by-id [id]
  (GET "/api/get-partner-by-id"
       {:headers {"Accept" "application/transit+json"}
        :params {:id id}
        :handler #(reset! business-partner (:business-partner %))}))

Когда я пытался получить доступ к атому бизнес-партнера, я получил нулевое значение для этого атома. Я не могу понять, почему, потому что другой метод почти такой же, за исключением того, что он получает список деловых партнеров и работает нормально.

Когда я меняю функцию get-partner-by-id:

(defn get-partner-by-id [id]
  (GET "/api/get-partner-by-id"
       {:headers {"Accept" "application/transit+json"}
        :params {:id id}
        :handler (fn [arg]
                   (println :handler-arg arg)
                   (reset! business-partner (:business-partner arg))
                   (println "Business partner from handler: " @business-partner))}))

Вывод в консоль браузера:

 :handler-arg {:_id 5e7ad2c84b5c2d44583e8ecd, 
               :address Main Street, 
               :email nenmit@gmail.com, 
               :phone 555888, 
               :name Nen Mit}

Business partner from handler:  nil

Итак, как вы можете видеть, У меня есть объект в обработчике по желанию, но когда я пытаюсь сбросить мой атом, ничего не происходит. Это ядро ​​проблемы, я думаю. Спасибо Алан.

1 Ответ

3 голосов
/ 25 марта 2020

В случае сомнений используйте отладочные операторы печати. Сделайте так, чтобы ваш обработчик выглядел следующим образом:

:handler (fn [arg]
           (println :handler-arg arg)
           (reset! business-partner (:business-partner arg)))

Вы также можете использовать clojure.pprint/pprint, чтобы красиво распечатать вывод, или также добавить (type arg) к выводу.

Вы можете также хотите инициализировать атом с указанным значением c, таким как :bp-default, чтобы вы могли видеть, является ли наблюдаемый вами nil исходным или сбрасывается на nil.


Обновление

Итак, ясно, что ключ :business-partner не существует на карте, которую вы получаете. Это то, что вы должны отладить.

Попытка извлечь несуществующий ключ из карты всегда возвращает nil. Вы также можете использовать 3-аргументную версию get, чтобы сделать это явным. Преобразуйте

(:business-partner arg)  =>  (get arg :business-partner ::not-found)

, и вы увидите ключевое слово ::not-found, которое будет отображаться в вашем атоме, чтобы проверить, что происходит.

Для раннего выявления этих проблем я почти всегда использую простое Функция grab из библиотеки Tupelo примерно так:

(:business-partner arg)  =>  (grab :business-partner arg)

Функция grab выдаст исключение, если ожидаемый ключ не найден. Это обеспечивает раннее предупреждение о проблемах, поэтому вы можете быстрее их отследить.

Еще один совет: в следующий раз используйте prn вместо println, и он будет сохранять двойные кавычки при выводе строки, например:

"Main Street"
...