Briedis
Briedis

Reputation: 73

How to convert number to string for Web Applications in Racket

I created a simple web application where the user enters a number and it gets calculated into different currencies. The problem I found is that for the number to be displayed back out it first needs to be converted to a string. Normally, if it wouldn't be a web application I would just do number->string x but in this case, it does not want to work, or at least I'm doing something wrong.

My code:

#lang racket

(require web-server/servlet
         web-server/servlet-env)

(define (page request)
  ;; extract the key value if present
  (define bindings (request-bindings request))

  ;; print entered currency when available
  (cond ((exists-binding? `amount bindings)
         (define (mynumber) (extract-binding/single `amount bindings))
         (define usd (lambda (mynumber) (* mynumber #i1.25)))
         (define eur (lambda (mynumber) (* mynumber #i1.14)))
         (response/xexpr
          '(html (head (title "Currency Exchange"))
                 (body
                  (h1 "Currency Exchange")
                  (div ((class "amount"))
                       (p "entered amount" ,mynumber)
                       (p "amount in USD: " ,usd)
                       (p "amount in EUR: " ,eur))
                  ))))

        ;; If there is no currency entered
        (else
         (response/xexpr
          '(html (head (title "Currency Exchange"))
                 (body
                  (h1 "Currency Exchange")
                  (p "enter currency in GBP:")

                  (form
                   (input ((name "amount")))
                   (input [(type "submit") (value "Calculate")]))
                  ))))
        )
  )

(serve/servlet page
               #:port 8080
               #:listen-ip #f
               #:servlet-path "/currency")

Upvotes: 1

Views: 122

Answers (1)

Flux
Flux

Reputation: 10920

Not exactly answering your question, but here are a few mistakes I see:

1.

(define (mynumber) (extract-binding/single `amount bindings))

Should probably be:

(define mynumber (extract-binding/single 'amount bindings))
;; OR
;; (define mynumber (string->number (extract-binding/single 'amount bindings)))

There's no use in creating a procedure in this case. A simple definition does the job.

Use quote instead of quasiquote when you are not using unquote.

2.

(define usd (lambda (mynumber) (* mynumber #i1.25)))
(define eur (lambda (mynumber) (* mynumber #i1.14)))

Should probably be:

(define usd (* mynumber 1.25))
(define eur (* mynumber 1.14))

Again, there is no need to create a procedure, because all you want to do is multiply two numbers.

The #i (inexact number) prefix is redundant, because real numbers without an exactness specifier are usually inexact by default (details here).

3.

(response/xexpr
          '(html (head (title "Currency Exchange"))
                 (body
                  (h1 "Currency Exchange")
                  (div ((class "amount"))
                       (p "entered amount" ,mynumber)
                       (p "amount in USD: " ,usd)
                       (p "amount in EUR: " ,eur)))))

You can fix this by using quasiquote (i.e. ` [backtick]) instead of quote (i.e. '), because you are using unquote (i.e. ,).

Use quasiquote instead of quote when you are using unquote.

Upvotes: 2

Related Questions