Fork me on GitHub
#clojurescript
<
2020-04-14
>
Ahmed Hassan07:04:20

How I can get value inside promise? I want to save value in atom/var and give as an argument to a function.

p-himik08:04:21

(.then promise #(reset a %))

👍 4
p-himik08:04:44

Promises are async, you can't work with them in a sync manner.

👍 4
Ahmed Hassan09:04:29

How should I pass it to a function to process Promise's return value?

p-himik09:04:53

Call that function in .then.

👍 4
p-himik09:04:29

As soon as you encounter a promise, there's no longer a return value. There's a continuation, where everything must follow if it is to be sync'ed.

👍 4
Kevin12:04:41

Hi, I'm trying to run some Clojurescript tests with Shadow-cljs with the following config:

:builds
 {:test
  {:target    :node-test
   :output-to "out/node-tests.js"
   :ns-regexp "-test$"
   :autorun   true}}
This all works, except when I require a namespace, which in turn requires [ajax.core :as ajax] I get this error:
TypeError: util.randomUUID is not a function
Tracing this back, it's a reference to the following https://github.com/cognitect/transit-js/blob/master/src/com/cognitect/transit/util.js#L57 This file is also in my build result .shadow-cljs/builds/test/dev/out/cljs-runtime/com.cognitect.transit.utils.js Anyone have an idea of what I'm doing wrong?

Kevin12:04:58

Just noticed another error, which is probably the reason for this: SHADOW import error /Users/kwrooijen/my-app/.shadow-cljs/builds/test/dev/out/cljs-runtime/com.cognitect.transit.handlers.js Not sure why this is happening though

thheller13:04:48

there should be more to that error? or even multiple instances of that error? It is usually one error resulting in many others

Kevin13:04:13

Sorry, should've pasted this right away. Here's the complete stack

npx shadow-cljs compile test
shadow-cljs - config: /Users/kwrooijen/my-app/shadow-cljs.edn  cli version: 2.8.83  node: v10.16.3
[:test] Compiling ...
========= Running Tests =======================
SHADOW import error /Users/kwrooijen/my-app/.shadow-cljs/builds/test/dev/out/cljs-runtime/com.cognitect.transit.handlers.js

/Users/kwrooijen/my-app/out/node-tests.js:1122
  fn.call(goog.global);
     ^
TypeError: util.randomUUID is not a function
    at /Users/kwrooijen/my-app/.shadow-cljs/builds/test/dev/out/cljs-runtime/com/cognitect/transit/handlers.js:36:9
    at Object.goog.scope (/Users/kwrooijen/my-app/out/node-tests.js:1122:6)
    at /Users/kwrooijen/my-app/.shadow-cljs/builds/test/dev/out/cljs-runtime/com/cognitect/transit/handlers.js:27:5
    at global.SHADOW_IMPORT (/Users/kwrooijen/my-app/out/node-tests.js:64:44)
    at /Users/kwrooijen/my-app/out/node-tests.js:2258:1
    at Object.<anonymous> (/Users/kwrooijen/my-app/out/node-tests.js:2:2)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
===============================================
[:test] Build completed. (168 files, 10 compiled, 0 warnings, 3.54s)

thheller13:04:55

strange. which transit version is this?

Kevin13:04:59

from shadow-cljs --cli-info

[com.cognitect/transit-cljs "0.8.256"]
  [com.cognitect/transit-js "0.8.846"]

thheller14:04:43

sorry no clue why this is failing. works fine for me

thheller14:04:02

only guess is that you have some kind of dependency conflict

thheller14:04:18

works totally fine for me locally

thheller14:04:29

maybe try wiping the .shadow-cljs/builds cache

Kevin14:04:53

Tried deleting that. I'll make a fresh project and try again. Thanks!

Quentin Le Guennec13:04:07

Hello, my cider session hangs when I start figwheel. I can't evaluate anything, RET inserts newline without re-printing the prompt.

dpsutton15:04:17

Is it figwheel main with lein?

knubie13:04:17

Does something like rxdb’s https://github.com/pubkey/rxdb/blob/a7202ac7e2985ff088d53d6a0c86d90d0b438467/docs-src/query-change-detection.md exist in the cljs world? I know re-frame gets around this with https://github.com/day8/re-frame/blob/master/docs/SubscriptionInfographic.md#the-layers, but I was curious if there are any other front-end like databases that have this (Datascript? Pathom?).

Prometheus18:04:32

Anybody here use reitit for routes? How do you get it to work with hot reloading with shadow-cljs?

nenadalm16:04:09

If you're asking how not to lose state you created using def, you can use defonce instead: https://clojuredocs.org/clojure.core/defonce

Ahmed Hassan19:04:37

What really is the concept of goog.async.Deferred in Google Closure Library? Is it really like advanced form of Promises?

phronmophobic19:04:30

since “promises” have similar, but varying interfaces and ideas in different languages and frameworks, I avoid describing other concepts in terms of them. Deferred and promises are tools used for handling asynchronous code. When it comes to asynchronous code, I really recommend CSP (Communicating Sequential Processes) as a foundation as it has a more theoretical basis, http://usingcsp.com/cspbook.pdf. As an aside, both go’s async features and clojure.core.async use CSP as a basis as well

isak19:04:57

I just read the description, and I think Ahmed is right. Looks like a really useful feature of Deferred is that you can cancel them. You can't do that on promises.

phronmophobic19:04:14

generally, when comparing Deferred to Promise, Promise is about one asynchronous task (although some libraries/frameworks have promises do more). Deferred usually has extra tools for combining multiple asynchronous tasks and handling error states

Ahmed Hassan19:04:05

Many namespaces in Google Closure Library depend on Deffered. They're backbone of asynchrony here IMO.

phronmophobic19:04:59

for the google closure library, yes

phronmophobic19:04:07

there are lots of options for handling asynchrony if you’re using clojurescript though. for example https://github.com/clojure/core.async

Ahmed Hassan19:04:35

I wanted to save Canvas as a PNG image to local filesystem, so I approached goog.fs where I saw Deffered very heavily used.

👍 4
Ahmed Hassan19:04:48

It seems Deferred already provides with what JS community is celebrating in the twitter thread you shared: https://google.github.io/closure-library/api/goog.async.Deferred.html

isak21:04:20

yea, that was my point

orestis06:04:30

Probably Deferred was there before JS got Promises. There’s similar things in Python Twisted.

Ahmed Hassan06:04:09

@U7PBP4UVA do you consider Deferred feasible?

orestis06:04:57

Not sure what you mean by feasible in this sense. I only meant that JS promises was kind of a late arrival. goog.async.Deferred was (probably, I never checked) there well before JS got Promises as even a 3rd-party library. These days native JS Promises have direct support in most engines, but the concept isn’t something new.

phronmophobic06:04:39

the wikipedia article is kinda interesting (https://en.wikipedia.org/wiki/Futures_and_promises) > The term promise was proposed in 1976 by https://en.wikipedia.org/wiki/Daniel_P._Friedman and David Wise,https://en.wikipedia.org/wiki/Futures_and_promises#cite_note-1 and Peter Hibbard called it eventual.https://en.wikipedia.org/wiki/Futures_and_promises#cite_note-2 A somewhat similar concept future was introduced in 1977 in a paper by https://en.wikipedia.org/wiki/Henry_Baker_(computer_scientist) and https://en.wikipedia.org/wiki/Carl_Hewitt. > The terms futurepromisedelay, and deferred are often used interchangeably, although some differences in usage between future and promise are treated below.

Ahmed Hassan07:04:14

By feasible I mean: what are trade offs of JS Promise when compared with Deferred?

Ahmed Hassan08:04:37

There's https://google.github.io/closure-library/api/goog.Promise.html too. > NOTE: This class was created in anticipation of the built-in Promise type being standardized and implemented across browsers. Now that Promise is available in modern browsers, and is automatically polyfilled by the Closure Compiler, by default, most new code should use native `Promise` instead of `goog.Promise`. However, `goog.Promise` has the concept of cancellation which native Promises do not yet have. So code needing cancellation may still want to use `goog.Promise`. EDIT: Also https://google.github.io/closure-library/api/goog.promise.NativeResolver.html and https://google.github.io/closure-library/api/goog.promise.Resolver.html

😮 4
Ahmed Hassan08:04:49

Great definition of Promise from https://promisesaplus.com/: > A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its `then` method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.

Spaceman21:04:25

Hi, I'm running a shadow-cljs app, and getting the following error in my browser: WebSocket connection to '<ws://localhost:9631/ws/worker/app/d220add9-aa54-43e3-be71-b121ec13636f/e2fa1a2b-01cf-44e7-9bf0-c5db8cb75503/browser>' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

Spaceman21:04:43

And the shadow-cljs has stopped reloading, and I don't know what's causing this.

Spaceman21:04:22

How do I even start to debug this, if there aren't any other errors in the console?

Spaceman21:04:08

Well there's also this error: shadow-cljs: websocket error Event {isTrusted: true, type: "error", target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …} bubbles: false cancelBubble: false cancelable: false composed: false currentTarget: WebSocket {url: "<ws://localhost:9631/ws/worker/app/d220add9-aa54-43>…636f/e2fa1a2b-01cf-44e7-9bf0-c5db8cb75503/browser", readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …} defaultPrevented: false eventPhase: 0 isTrusted: true path: [] returnValue: true srcElement: WebSocket {url: "<ws://localhost:9631/ws/worker/app/d220add9-aa54-43>…636f/e2fa1a2b-01cf-44e7-9bf0-c5db8cb75503/browser", readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …} target: WebSocket {url: "<ws://localhost:9631/ws/worker/app/d220add9-aa54-43>…636f/e2fa1a2b-01cf-44e7-9bf0-c5db8cb75503/browser", readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …} timeStamp: 147976.1250000156 type: "error" proto__: Event

dnolen22:04:56

@pshar10 you might want to ask in the #shadow-cljs channel?

Mitch Dzugan23:04:36

Anyone familiar with wrapping defprotocol in a macro from clojurescript. This is the minimal repro of an issue I'm currently having:

# src/app/macros.cljc

(ns app.macros
  #?(:cljs (:require-macros [app.macros :refer [testproto]])))


#?(:clj
   (defmacro testproto [proto nm args]
     `(defprotocol ~proto
        (~nm ~args))))
This macro works fine when used from clojure but when used from clojurescript like so
# src/app/core.cljs
(ns app.core (:require [app.macros :refer [testproto]]))

(testproto MyProtocol proto-method [b])
I get build error
Caused by: java.lang.Exception: Invalid protocol, MyProtocol received unexpected argument
	at cljs.core$defprotocol$fn__4490.invoke(core.cljc:2047)
	at cljs.core$defprotocol.invokeStatic(core.cljc:2032)
	at cljs.core$defprotocol.doInvoke(core.cljc:1989)
	at clojure.lang.RestFn.applyTo(RestFn.java:146)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at clojure.core$apply.invoke(core.clj:660)
	at cljs.analyzer$macroexpand_1_STAR_$fn__2556.invoke(analyzer.cljc:3879)
My guess would be this has something to do with the different defprotocol implementations in clojurescript vs clojure and the #?(:clj) reader making the clojurescript implementation try to use the clojure version but I even tried replacing defprotocol with cljs.core/defprotocol in the macro definition to see if I could get that to work from clojurescript but got the same error