Question

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.

Was it helpful?

Solution

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!!"]))

OTHER TIPS

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

(doall (map ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top