In this case it will work despite being a hack, because you know that your
id argument affects only the display stage, not the processing stage:
however, you can't know in general that this will work for dynamically
generated formlets, and personally I would therefore be reluctant to rely
on this, both because it is fragile in terms of changes to your
implementation of matrix-formlet that you might make later.

If you are using native continuations (i.e. not the stateless #lang
web-server), you can use send/formlet or embed-formlet to deal with this
correctly and easily. (At a lower level, you could also do something like

> (define-values (xexpr-forest bindings->result i)
>   ((matrix-formlet "3") 0))

to access the low-level rendering, processing function, and next allowable
input integer directly.)

It is a little more tricky in #lang web-server, because your formlet and
it's generated processing function are plain functions, and thus not
serializable (see this old thread for discussion:
https://groups.google.com/d/topic/racket-users/lMYWjodgpmo/discussion). The
easy work-around is to keep the arguments you need to reproduce your
formlet around as part of the closure, e.g. by rewriting your
matrix-submission like this:

> (define (matrix-submission req id)
>   (define-values (number-of-ones user-id)
>       (formlet-process (matrix-formlet id) req))
>   ...)

The alternative is to either recompile the formlet library using #lang
web-server/base or to implement your formlet at a low level using
serial-lambda and not use any of the library tools.

In this specific case, though, if you are using this hidden input field
just to remember the user id from one request to the next (i.e. you
wouldn't ever change it on the client side with JavaScript or something),
the best solution is not to put it in the form at all, but have it be part
of the continuation. This could also have security advantages, if you
cryptographically sign your continuations or store them on the server. If
that works for your use case, you could simply write:
(define matrix-formlet
  input-string)
display it with

> (matrix-submission
>  (send/suspend
>   (λ (k-url)
>     (response/xexpr
>      `(html (body (form
>                    ((action "/the-matrix-submitted")
>                     (method "post"))
>                    ,@(formlet-display matrix-formlet)
>                    (input ([type "submit"]))))))))
>  user-id)

and then define matrix-submission as

> (define (matrix-submission req user-id)
>   (define number-of-ones
>       (formlet-process matrix-formlet req))
>   ...)


-Philip

On Tue, Mar 14, 2017 at 12:01 PM, Marc Kaufmann <marc.kaufman...@gmail.com>
wrote:

> Hi,
>
> I have created a formlet like so:
>
> (define (matrix-formlet id)
>   (formlet
>         (#%# ,{input-string . => . ones}
>              ,{(to-string (required (hidden id))) . => . user-id}
>                  )
>         (values ones user-id)))
>
> I display this as follows:
>
> `(form
>   ((action "/the-matrix-submitted")
>    (method "post"))
>  ,@(formlet-display (matrix-formlet user-id))
>  (input ([type "submit"]))))
>
> and process it like this:
>
> (define (matrix-submission req)
>   (define-values (number-of-ones user-id)
>                  (formlet-process (matrix-formlet "3") req))
>   ...)
>
> While this works, the formlet I use to display and process are not really
> the same, since they are created on the spot, and created with different
> parameters. So far it seems to work, but I am worried that this will break
> down, and clearly this isn't the right way to go about creating
> parametrizable formlets.
>
> The questions are (i) is the above going to work despite being a hack, and
> (ii) is there a correct and easy way to do the same thing?
>
> Cheers,
> Marc
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to