Fork me on GitHub
#biff
<
2022-08-31
>
2FO20:08:47

Good day, How can I render resources from the db in the UI, I'm trying to create list-games and show-game functions, but I'm running into 500 "internal server errors". app.clj

(defn list-games [db]
  (let [games (xt/q db
                    '{:find [title]
                      :where [[_ :game/title title]]})]
                      (ui/page
                      [for game games]
                      [:h1 game])))

(defn show-game [db]
  (let [game (xt/q db
                    '{:find [id title]
                      :where [[e :game/title title]
                              [e :game/id id]]})]
                              (ui/page
                              [:h1 game])))
(def features
  {:routes ["/app"
            ["" {:get app}]
            ["/index/" {:get list-games}]
            ["/game/" {:get show-game}]]})

Jacob O'Bryant20:08:25

Whenever there's an internal server error, you can check the terminal. There should be an error message there with more information. What does it say?

2FO21:08:58

Got it 👍

[qtp1009357130-21] INFO com.biffweb.impl.middleware -   4ms 500 get  /app/index

Jacob O'Bryant21:08:41

is there a stack trace above that?

2FO22:08:39

[qtp57305467-25] ERROR com.biffweb.impl.middleware - Exception while handling request
java.lang.IllegalArgumentException: No implementation of method: :q* of protocol: #'xtdb.api/PXtdbDatasource found for class: clojure.lang.PersistentHashMap
        at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:584)
        at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:576)
        at xtdb.api$eval7763$fn__7820$G__7732__7829.invoke(api.clj:139)
        at xtdb.api$q.invokeStatic(api.clj:366)
        at xtdb.api$q.doInvoke(api.clj:360)
        at clojure.lang.RestFn.invoke(RestFn.java:425)
        at $list_games.invokeStatic(app.clj:24)
        at $list_games.invoke(app.clj:23)
        at com.biffweb.impl.middleware$wrap_render_rum$fn__16091.invoke(middleware.clj:26)
        at com.biffweb.impl.middleware$wrap_anti_forgery_websockets$fn__16084.invoke(middleware.clj:22)
        at ring.middleware.anti_forgery$wrap_anti_forgery$fn__14646.invoke(anti_forgery.clj:94)
        at reitit.ring$ring_handler$fn__23128.invoke(ring.cljc:329)
        at clojure.lang.AFn.applyToHelper(AFn.java:154)
        at clojure.lang.AFn.applyTo(AFn.java:144)
        at clojure.lang.AFunction$1.doInvoke(AFunction.java:31)
        at clojure.lang.RestFn.invoke(RestFn.java:408)
        at muuntaja.middleware$wrap_params$fn__13829.invoke(middleware.clj:52)
        at muuntaja.middleware$wrap_format$fn__13833.invoke(middleware.clj:73)
        at com.biffweb.impl.middleware$wrap_resource$fn__16107.invoke(middleware.clj:49)  
        at com.biffweb.impl.middleware$wrap_internal_error$fn__16113.invoke(middleware.clj:55)
        at com.biffweb.impl.middleware$wrap_log_requests$fn__16118.invoke(middleware.clj:63)
        at clojure.lang.Var.invoke(Var.java:384)
        at ring.middleware.flash$wrap_flash$fn__13949.invoke(flash.clj:39)
        at ring.middleware.session$wrap_session$fn__14380.invoke(session.clj:108)
        at ring.middleware.keyword_params$wrap_keyword_params$fn__14426.invoke(keyword_params.clj:53)
        at ring.middleware.nested_params$wrap_nested_params$fn__14484.invoke(nested_params.clj:89)
        at ring.middleware.multipart_params$wrap_multipart_params$fn__14782.invoke(multipart_params.clj:171)
        at ring.middleware.params$wrap_params$fn__14806.invoke(params.clj:67)
        at ring.middleware.cookies$wrap_cookies$fn__14259.invoke(cookies.clj:214)
        at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__14960.invoke(absolute_redirects.clj:47)
        at ring.middleware.content_type$wrap_content_type$fn__13881.invoke(content_type.clj:34)
        at ring.middleware.default_charset$wrap_default_charset$fn__14932.invoke(default_charset.clj:31)
        at ring.middleware.not_modified$wrap_not_modified$fn__14908.invoke(not_modified.clj:61)
        at ring.middleware.x_headers$wrap_x_header$fn__13912.invoke(x_headers.clj:22)     
        at ring.middleware.x_headers$wrap_x_header$fn__13912.invoke(x_headers.clj:22)     
        at ring.middleware.x_headers$wrap_x_header$fn__13912.invoke(x_headers.clj:22)     
        at com.biffweb.impl.middleware$wrap_env$fn__16137.invoke(middleware.clj:112)      
        at ring.adapter.jetty9$proxy_handler$fn__23619.invoke(jetty9.clj:75)
        at ring.adapter.jetty9.proxy$org.eclipse.jetty.servlet.ServletHandler$ff19274a.doHandle(Unknown Source)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1378)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:463)      
        at ring.adapter.jetty9.proxy$org.eclipse.jetty.servlet.ServletHandler$ff19274a.doScope(Unknown Source)
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1300)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)  
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
        at org.eclipse.jetty.server.Server.handle(Server.java:562)
        at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:418)     
        at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:675)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:410)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282)    
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:319)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
        at org.eclipse.jetty.io.SocketChannelEndPoint$1.run(SocketChannelEndPoint.java:101)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:894)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1038)
        at java.base/java.lang.Thread.run(Thread.java:833)
[qtp57305467-25] INFO com.biffweb.impl.middleware -  10ms 500 get  /app/index/

Jacob O'Bryant22:08:14

java.lang.IllegalArgumentException: No implementation of method: :q* of protocol: #'xtdb.api/PXtdbDatasource found for class: clojure.lang.PersistentHashMap means you're trying to call the q function, but instead of passing it an XT database it's getting a map. I see the error now from the code you pasted earlier. The argument for list-games and show-game should be called sys or req, not db. You can get the db like so: (defn list-games [{:keys [biff/db] :as sys}] ...

🙏 1
Jacob O'Bryant22:08:12

After that's fixed, there may be more errors--e.g. if you're using the default ui/page function, it needs to have a map as the first argument, like (ui/page {} [:h1 game]). Also the for in list-games has some incorrect syntax, see https://clojuredocs.org/clojure.core/for for some correct examples

🙏 1
2FO23:08:53

Thanks that cleared up a lot

👌 1
2FO23:08:37

The one thing I ran into, is a compilation error if I call list-games with :as sys e.g (defn list-games [{:keys [biff/db]] ...) works but (defn list-games [{:keys [biff/db] :as sys .. produces this error:

Syntax error macroexpanding clojure.core/defn at (com/game/feat/app.clj:24:1).
{:keys [biff/db]} - failed: vector? at: [:fn-tail :arity-n :bodies :params] spec: :clojure.core.specs.alpha/param-list
(:as sys) - failed: Extra input at: [:fn-tail :arity-1 :params] spec: :clojure.core.specs.alpha/param-list 
Same error if I replace sys with req

Jacob O'Bryant02:09:25

based on the error message, it looks like you had (defn list-games {:keys [biff/db]} ...). the parameter list needs to be wrapped with a vector, as in (defn list-games [{:keys [biff/db]}] ...)

🙏 1
Jacob O'Bryant20:08:32

Just made some updates to Platypub's default theme: • there's a new "Home logo image url" site option. If set, it'll display the image on the home page instead of the logo in the navbar. (It'll also get shown in other places where the subscribe form appears). • If you add an "about" tag to one of your pages, then the home page will include an about section with the contents, and your author image/name/url. • There's also additional metadata, so you can get a zipfile from https://realfavicongenerator.net/ and unzip it in themes/default/assets/, and it'll update the site icon for various apps/devices • The posts listed on the home page are now split into two separate "featured" and "recent" sections • There's a new page at https://<your website>/subscribe/ which has just a subscribe form. good for linking from other places where the reader has already been given context. For example: https://toolsforonlinespeech.org/, https://toolsforonlinespeech.org/subscribe/ Next up is migrating https://jacobobryant.com over to platypub... I'll probably add a new theme and call it "minimalist"