I've got dynamically generated forms, so I was trying to validate them this way:

(defn valid? [media-id data] ;media-id it's just a number, data is the form input
  (let [fields (common/get-fields-to-show media-id)] ; list of strings (the field names)
    (map (fn [f]
           (vali/rule (vali/has-value? ((keyword f) data))
                      [(keyword f) "Write something!!"]))
         fields))
    (not (apply vali/errors? (map keyword fields))))

but it won't work. There's no exception or message at all, valid? is evaluated as true so the flow continues as if there were no errors although all fields are empty. I even tried (vali/has-value? nil) to force the error but nothing changes.

Experimenting, I removed the map, took two specific fields, build their rules "by hand" this way:

(defn valid? [media-id data]
  (let [fields (common/get-fields-to-show media-id)
        f1 (first fields)
        f2 (second fields)]
    (vali/rule (vali/has-value? ((keyword f1) data))
               [(keyword f1) "Testing"])
    (vali/rule (vali/has-value? ((keyword f2) data))
               [(keyword f2) "Testing"])
    (not (apply vali/errors? (map keyword fields))))

And it works perfectly for those lucky fields.

I suspect it has something to do with the way noir.validation saves the errors (a dynamic declared thing), but I'm not sure.

有帮助吗?

解决方案

Don't use map for sequence of operations. map is for transforming a sequence to something else. What you need to use is doseq

Instead of:

(map (fn [f]
           (vali/rule (vali/has-value? ((keyword f) data))
                      [(keyword f) "Write something!!"]))
         fields))

Use this:

(doseq [f fields]
    (vali/rule (vali/has-value? ((keyword f) data))
                          [(keyword f) "Write something!!"]))

其他提示

map returns a lazy seq. You can force evaluation by using doall:

(doall (map ...
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top