Fork me on GitHub
#clojurescript
<
2021-07-01
>
Simon10:07:25

What is the best way to fetch something from an API and display it in a reagent component? I found this approach where they use ajax to reset the state of a reagent atom. But is there a better way?

(ns breaking-bad-quotes.core
  (:require [reagent.core :as r :refer [atom]]
            [ajax.core :refer [GET]]))

(defn fetch-link! [data]
  (GET ""
    {:handler #(reset! data %)
     :error-handler (fn [{:keys [status status-text]}]
                      (js/console.log status status-text))}))

(defn quote []
  (let [data (atom nil)]
    (fetch-link! data)
    (fn []
      [:div.cards>div.card
       [:h2.card-header.text-center "Breaking Bad Quotes"]
       [:div.card-body.text-center
        [:p#quote @data]
        [:p#author @data]]
       [:div.card-footer.center.text-center
        [:button#twitter.outline>a#tweet
         {:href "#"
          :target "_blank"}
         [:i.fi-social-twitter " Tweet"]]
        [:button#new-quote.outline
         [:i.fi-shuffle " New Quote"]]]])))
https://www.rockyourcode.com/tutorial-clojurescript-app-with-reagent-for-beginners-part-1/

p-himik10:07:45

"Better" in what sense? Impossible to give any advice without knowing exactly what you want to achieve.

Simon11:07:42

You are right @U2FRKM4TW. I was mainly just thinking that coming from React.js and JS it is such a standard practice to make a component with a useEffect hook where fetch is called, which uses setState to update a value which then gets displayed. Is there a similarly standard approach for this in CLJS with Reagent? I have looked into cljs-http, core.async and even js/fetch . But I'm not quite sure about which one to use in this scenario: I simply need to fetch something from and external HTTP API and display it in a reagent component.

p-himik11:07:43

Even in React, using a hook is a practice, not something standard.

p-himik11:07:04

You can use hooks with Reagent just fine. Or you can use atoms. Or you can use re-frame. Or maybe something else.

p-himik11:07:37

Generally, people don't use hooks with Reagent simply because Reagent atoms are simpler and sufficient.

p-himik11:07:31

> I simply need to fetch something from and external HTTP API and display it in a reagent component. If you care about nothing else, then your current code LGTM.

Simon11:07:57

Thank you for your response. i'm still quite new in the Clojure world. When would it make sense to make use of re-frame?

p-himik11:07:01

When you have a decent amount of state that you have to manage.

Simon11:07:13

Yes that was also my understanding 🙂 Thanks again for responding so quickly and well @U2FRKM4TW

👍 2
Krishan V11:07:09

Hey everyone, I am quite curious to hear from those who built applications with Elm before, what benefits does Clojurescript bring to the dev experience over Elm? Sadly, Elm React-Native never took off so I'm looking into Cljs RN. Might as well use Cljs for the SPA while I'm at it.

hkjels11:07:23

interop with javascript is at least a lot easier

hkjels11:07:22

also, the dev-experience ones you get used to a REPL, hot-reloading etc

hkjels11:07:17

I’m almost done with an app using Krell and I had to interop quite a bit with react libraries, so I think it would be awefull with Elm to be honest

nate sire14:07:57

For me... the ability to use Clojure Script interop with Node/TypeScript because of WASM

Tomaz Bracic19:07:53

but what about other great Elm benefits...like refactoring and maintenance of a codebase, when you can literaly dig into some specific part that you still remember about ...and then for the rest ... compiler directs you. Don't get me wrong... i just recently "moved" here... but for reasons around how Elm core team drives development of Elm... where you have a feeling that Elm is just a private project... shared with public... and that rarely community is heard

Tomaz Bracic19:07:36

But i am still not fully sure, that i did the right decision. I still try to persuade myself i did.... every day

Tomaz Bracic19:07:48

so i am interested in others opinion

nate sire19:07:35

I think the role you use a language (contractor, enterprise employee, cofounder) will impact your reasoning to keep commited to Clojure

Tomaz Bracic19:07:03

what do you mean with that exactly?

nate sire19:07:43

for example.... I think many of us want to use a popular language because we think that helps us find a job

nate sire19:07:29

even though Clojure is simple... it can take time to learn... so demand can be high in the market and there is a barrier to entry

nate sire19:07:49

contrast that to JS... low barrier... bigger market

nate sire19:07:00

but more competition

nate sire19:07:44

that's why I use JS, Typescript, Clojure and CLJS... it gives me both strategies

nate sire19:07:36

big fish in small pond (I am still a small fish)... or small fish in big pond

nate sire19:07:17

other than that... ignoring any market reason... just pick what you like to work with

Tomaz Bracic19:07:52

would you say (since you use both worlds) ... that for instance.... you need to equaly frequently devote time for maintaining the past projects... (updating, upgrading packages...) or would you say that Clojurescript allows you to do that less frequently. This is one really big plus for Elm ... you might be aware of, for some, slow development... but for some... this is a huge plus.

Tomaz Bracic19:07:34

or your two ponds require equally amount of effort for this? :)

nate sire18:07:26

Clojure is incredibly stable and requires very little maintenance... but Node seems to be always breaking things.

nate sire18:07:29

Also... Node added a really weird way of supporting 2015 ecma script modules... where you need to copy all your files to an .mjs extension.... but I do like Node because it's rapid when building things.

nate sire18:07:59

Clojure takes more thought but over the long term... much more stable... it's a trade off

Simon12:07:58

#beginner is there a similar option to the || fall back from javascript. For example as used in this context:

<img src={image.might.be.nil || "default.jpg"} />

p-himik12:07:52

(or value1 value2)

p-himik12:07:35

Note that in both cases the second value will be used if the first one is false.

Simon12:07:36

oh yeah that actually works

Simon12:07:03

probably it compiles to the same expression

Tomaz Bracic19:07:38

sorry for my really beginners questions. i am a bit confused about Reagent and Re-frame. What exactly does this "relation" to React ecosystem means? Is the "output" of my clojurescript project that is based on Reagent ...like editable React "component" that someone can use as part of react codebase in a project or what?

Tomaz Bracic19:07:07

or is output pure javascript code?

Tomaz Bracic19:07:17

like vanila js

p-himik19:07:23

Re-frame uses Reagent. Reagent uses React. Regardless of what you use, in the end you will have a JS file or files that browsers can run.

emccue19:07:53

A react component is usually a function that returns a "react element"

emccue19:07:05

which is an object you get from calling React.createElement(...)

emccue19:07:36

A reagent component is usually a function that returns "hiccup" data, which is a format that can be converted to a react element

Tomaz Bracic19:07:17

aha... so Reagent uses React functionalities... which i need to be aware of then. :) and the output of a project is vanila JS. ok, thanks!