jkk / formative

Web forms for Clojure and ClojureScript - rendering, parsing, and validating

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

java.lang.IllegalArgumentException: No matching method found: valueOf

lkrubner opened this issue · comments

Any thoughts about what could trigger this error? I get it when I try to parse the form input:

item-type-as-keyword (keyword (get-in request [:params :item-type]))

the-form (secretary/get-from-interactions [:schema item-type-as-keyword])

item (:params request)

item (if (:item-name item)
item
(assoc item :item-name (make-item-name item)))

item (fp/parse-params the-form item)

That last line triggers the error.

"the-form" is the Formative form definition. "item" is the :params from request when the form is submitted.

Could you provide sample inputs for the-form and item that fail?

Sure, I'll post examples below. I had a thought -- I did implement a custom render-field. Do I need to also implement a custom validator for that?

This is :params from the request map that Ring gives me:

{:submit "Submit",
:scheduled-for-deletion "false",
"created-at[month]" "2",
:top-winner-bio "",
:mailing-address "",
:country "",
:cash-total "",
:is-true-elite "false",
:subscribe-to-questions-via-email "false",
:is-monthly-asker "false",
:previous-item-name "",
:is-winner "false",
"created-at[day]" "6",
:paypal-email "",
:is-top-monthly-winner "false",
"updated-at[m]" "55",
:clients-can-contact "false",
:this-user-is-disabled "false",
:is-top-asker "false",
"updated-at[year]" "2014",
"updated-at[h]" "2",
:item-type "users",
:is-allowed-to-vote "false",
:phone-number "",
:last-name "",
:first-name "",
:admin-note "",
:netvotes-all-time "0",
:secret-signup-key "3c3a78d5b56f4dc9005c519dcf081dfc",
:html-and-css-for-discourse-page "",
:paypal-email-for-community-owners "",
:netvotes-this-month "0",
:city "",
"created-at[ampm]" "am",
:private "false",
:is-asker "false",
"created-at[m]" "55",
:special-requests-for-handling-payments-for-owners-of-communities "",
"updated-at[month]" "2",
:url "",
:email "",
:is-top-winner "false",
:payoneer-email "",
:_id "52c0c7460364c1ef3de601e7",
"updated-at[day]" "6",
:do-not-notify-regarding-community-pot "false",
:landing-page "",
"created-at[h]" "2",
:item-name "wpquestions-sf_guard_user-12962",
:netvotes-90-days "",
:community-item-name "wpquestions",
:file-2
{:size 0,
:tempfile
#<File /var/folders/85/50nmp8fx3q72pxv4zlh_74pm0000gn/T/ring-multipart-6802873987403228717.tmp>,
:content-type "application/octet-stream",
:filename ""},
:is-allowed-to-post-recommendations "false",
:file-1
{:size 0,
:tempfile
#<File /var/folders/85/50nmp8fx3q72pxv4zlh_74pm0000gn/T/ring-multipart-4838150394525761606.tmp>,
:content-type "application/octet-stream",
:filename ""},
:subscribe-to-all-discourse "false",
:machine-cookie-item-name "",
:gift-credit-cash-fund "",
:file-3
{:size 0,
:tempfile
#<File /var/folders/85/50nmp8fx3q72pxv4zlh_74pm0000gn/T/ring-multipart-875231396126035484.tmp>,
:content-type "application/octet-stream",
:filename ""},
:password "30161f6cf5332f147d60d984ae2013350a702839",
"created-at[year]" "2014",
:is-good-citizen "false",
:description "",
:twitter-address "",
"updated-at[ampm]" "am"}

The form definition, in this case, is a long one:

{:action "/admin/process-input/",
:fields
[{:name :password, :type :password}
{:name :first-name, :note " :first-name "}
{:name :last-name, :note " :last-name "}
{:name :email, :type :email, :note " email "}
{:name :url,
:note "Please include 'http' or 'https' as part of the URL. "}
{:name :description, :type :textarea, :note " :description "}
{:name :cash-total, :note " :cash-total "}
{:name :secret-signup-key, :note " :secret-signup-key "}
{:name :twitter-address, :note " :twitter-address "}
{:name :landing-page, :note " :landing-page "}
{:name :payoneer-email, :type :email, :note " :payoneer-email "}
{:name :subscribe-to-questions-via-email,
:type :checkbox,
:note " :subscribe-to-questions-via-email "}
{:name :clients-can-contact,
:type :checkbox,
:note
" This user does not mind if people want to contact them to offer them jobs. "}
{:name :country, :type :country-ad-hoc, :note " :country "}
{:name :city, :note " :city "}
{:name :paypal-email,
:type :email,
:note
" Optional, but if you put an email here, we will send your whole account balance to this address, every night. "}
{:name :do-not-notify-regarding-community-pot,
:type :checkbox,
:note " do-not-notify-regarding-community-pot "}
{:name :subscribe-to-all-discourse,
:type :checkbox,
:note
" Do you want email notifcation of all discourse posted to this website? "}
{:name :is-allowed-to-vote,
:type :checkbox,
:note
" This user is allowed to vote (on money, answers, discourse, etc) "}
{:name :is-top-winner, :type :checkbox, :note " :is-top-winner "}
{:name :is-top-monthly-winner,
:type :checkbox,
:note " Is this user one of the top winners of the last 30 days? "}
{:name :is-monthly-asker,
:type :checkbox,
:note " Has this person asked a question in the last month? "}
{:name :is-asker,
:type :checkbox,
:note " Has this person ever paid to ask a question? "}
{:name :is-winner, :type :checkbox, :note " :is-winner "}
{:name :is-true-elite,
:note " Is one of the top experts? ",
:type :checkbox}
{:name :is-allowed-to-post-recommendations,
:note
" Is allowed to post recommendations? (Top experts and top donors can post 1 reccomendation a month.) ",
:type :checkbox}
{:name :top-winner-bio, :note " :top-winner-bio "}
{:name :is-top-asker,
:type :checkbox,
:note " Is top asker? (is this person one of our best customers?) "}
{:name :netvotes-90-days,
:note " :netvotes-this-month ",
:datatype :int}
{:name :netvotes-this-month,
:note " :netvotes-this-month ",
:datatype :int}
{:name :netvotes-all-time,
:note " :netvotes-all-time ",
:datatype :int}
{:name :is-good-citizen,
:type :checkbox,
:note " Is this user a Good Citizen (votes often)? "}
{:name :html-and-css-for-discourse-page,
:note
"You can create your own HTML and CSS for your discourses page."}
{:name :gift-credit-cash-fund,
:type :currency,
:note
"Sometimes TMA admins give gifts of credit to certain users, to encourage them to ask questions. We keep this credit in its own fund, so the user does not simply withdraw it. We don't want them to withdraw it, we want them to spent it on questions.",
:datatype :decimal}
{:name
:special-requests-for-handling-payments-for-owners-of-communities,
:note
"If the owners of this community have special requests for TMA admins, they should record them here."}
{:name :mailing-address,
:note
"If the owners of this community want us to use snail mail to send them a paper check, they should put their street address here."}
{:name :phone-number,
:note
"A telephone number where we can reach the owner of the community. Please include the country code."}
{:name :paypal-email-for-community-owners,
:type :email,
:note
"If we are given a 'PayPal email for Community Owner', then we will send payments automatically, as soon as a question successfully concludes."}
{:name :community-item-name,
:type :hyperlink-value,
:note
"Every question needs to belong to a particular community, such as Wordpress or SEO."}
{:name :item-name,
:note
"Secret name used internally by the software. Do not change this."}
{:name :item-type,
:note
"The type of the record, used internally by the software. Do not change this."}
{:name :previous-item-name,
:note
"This is the name of the current version of this item. If this record was edited, then this backup was made to keep track of old versions."}
{:name :this-user-is-disabled,
:type :checkbox,
:note
" if a user has been downvoted or caught cheating, we disable their account and disable all of their posts and answers and discourse "}
{:name :scheduled-for-deletion,
:type :checkbox,
:note " if marked yes, this item will soon deleted? "}
{:name :private,
:type :checkbox,
:note
" if marked yes, then this item should only be seen by the owner and the admins "}
{:name :file-1,
:type :file,
:note "Attach up to 3 files or images",
:datatype :file}
{:name :file-2,
:type :file,
:note "Attach up to 3 files or images",
:datatype :file}
{:name :file-3,
:type :file,
:note "Attach up to 3 files or images",
:datatype :file}
{:name :admin-note,
:note "If an admin edits this record, they should say why."}
{:name :created-at,
:type :datetime-select,
:note "When was this item first created?"}
{:name :updated-at,
:type :datetime-select,
:note "When was this item most recently modified?"}
{:name :_id,
:note "The id assigned by the database. Do not change this."}
{:name :machine-cookie-item-name,
:note
"The unique id that we assigned to the computer of this user, via putting a cookie on their computer."}],
:validations
[[:required [:item-name :item-type :user-item-name :password]]
[:email [:email]]
[:web-url [:url]]],
:values {:community-item-name "all", :item-type :users},
:enctype "multipart/form-data"}

valueOf appears 3 times here:

https://github.com/jkk/formative/blob/master/src/formative/parse.cljx

it appears in these 3 methods:

(defmethod parse-input :boolean [_ v]
#+clj (Boolean/valueOf v)
#+cljs (contains? #{"true" "on"} v))

(defmethod parse-input :booleans [_ v](map #+clj #%28Boolean/valueOf %%29 #+cljs #%28contains? #{"true" "on"} %)
(fu/seqify-value v)))

(defn- parse-double [spec x](when-not %28string/blank? x%29
%28try
#+clj %28Double/valueOf x%29 #+cljs %28js/parseFloat x%29
%28catch #+clj Exception #+cljs js/Error _
%28->ParseError x%29%29%29))

Clojure typically throws "java.lang.IllegalArgumentException: No matching method found" when a polymorphic Java method is being called with a signature that does not actually exist (that is, the wrong type is given as an argument to a method).

I suppose I can load all of this at the repl and work through it one value at a time till I find the wrong value, but if you have any thoughts please let me know.

At the most general level, am I correct that I can take (:params request) from the request map that Ring gives me (when some user has just filled out a form and hit the submit button) and then I can call parse-params on the map I get from calling (:params request)?

I see what happened. I had a field:

{
:name :is-private
:type :checkbox
:datatype :boolean
}

but checkbox is not boolean, it seems to be a vector. So (parse) tried to validate it as boolean and I got the error that I got.

To follow up on this. I have 3 fields defined as:

              {
               :name :subscribe-to-questions-via-email
               :type :radios
               :options [true false]
               :note " If true, then the user wants to be sent an email, every time someone posts a question. "
               }
              {
               :name :clients-can-contact
               :type :radios
               :options [true false]
               :note " This user does not mind if people want to contact them to offer them jobs. "
               }
              {
               :name :subscribe-to-all-discourse
               :type :radios
               :options [true false]
               :note "  Do you want email notifcation of all discourse posted to this website? "
               }

And this:

(pp/pprint (:params request))

gives me:

:subscribe-to-questions-via-email "true",
:clients-can-contact "false",
:subscribe-to-all-discourse "true",

but this:

(fp/parse-params the-form (:params request))

I get:

clojure.lang.ExceptionInfo

{:problems
({:keys (:subscribe-to-questions-via-email), :msg "not an accepted value"}
{:keys (:clients-can-contact), :msg "not an accepted value"}
{:keys (:subscribe-to-all-discourse), :msg "not an accepted value"})}

But I have placed no restrictions on the types for these fields:

     :validations [
                   [:required [:item-name :item-type :password]]
                   [:email [:email]]
                   [:web-url [:url]]
                   ]

So where does this error come from? It seems like Formative throws an error if these fields have a value, be it true or false. Why?

An, nevermind. I added :datatype :boolean and that fixed the problem:

              {
               :name :is-good-citizen
               :type :radios
               :datatype :boolean
               :options [true false]
               :note "  Is this user a Good Citizen (votes often)? "
               }