Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 1046 of the free egghead.io lessons, plus get RxJS content delivered directly to your inbox!



Existing egghead members will not see this. Sign in.

The Cycle.js principle: separating logic from effects

3:30 RxJS lesson by

This lesson is the first in an introduction to Cycle.js. We will see how to build from scratch a toy version of Cycle.js. See how to use RxJS to create simple web apps, and how to separate logic from effects.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

This lesson is the first in an introduction to Cycle.js. We will see how to build from scratch a toy version of Cycle.js. See how to use RxJS to create simple web apps, and how to separate logic from effects.

Avatar
Julio

more, more, please!

In reply to egghead.io
Avatar
Nils

Sweet!

Avatar
Julio

Meu deus, que alegria André
Oh my god, What a wonderful day

In reply to Julio
Avatar
David

What is an observable? Do you have any suggestions for RX tutorials/videos before this?

Avatar
Steve

For anyone else wondering how that string template works I found this and it must be why this code requires Babel:
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings?hl=en

Avatar
Briisk Sp. z o.o.

Andre, estou usando Cycle DOM version: 12.1.0, Gulp e Browserify (e algums midlewares). Quando eu faco a injecao dos scripts no elemento HEAD, nao funciona e eu recebo um erro 'Cannot render into unknown element body'. Se por outro lado eu injeto os scripts no elemento BODY tudo funciona. Cycle ta tentando montar antes do DOM esta completamente renderizado. Ha alguma maneira de injetar os scripts no elemento HEAD ?

Avatar
Andre

Hi Briisk,
Yes, you can inject the scripts in HEAD, but then you also need to delay Cycle.run and makeDOMDriver until the document is ready. For instance

document.addEventListener('DOMContentLoaded', function () {
  Cycle.run(main, {
    DOM: makeDOMDriver('body'),
  });
});

In the future we need to support your use case, see this issue https://github.com/cyclejs/cyclejs/issues/222.

In Portuguese

Sim você pode injetar os scripts no elemento HEAD, mas aí você também precisa adiar o Cycle.run e makeDOMDriver até o documento ficar pronto. Por exemplo:

document.addEventListener('DOMContentLoaded', function () {
  Cycle.run(main, {
    DOM: makeDOMDriver('body'),
  });
});

No futuro queremos dar suporte a essa forma de usar, e está registrado nesse item: https://github.com/cyclejs/cyclejs/issues/222.

In reply to Briisk Sp. z o.o.
Avatar
Briisk Sp. z o.o.

I wasn't expecting such a quick reply :-) thanks for that. I noticed that when I put the same bit of code that you wrote in a setTimeout with 1 ms of delay, it worked but it's better to use your solution with an event listener. BTW, I'm Francisco, Briisk is the company where I work here in Poland.

In reply to Andre

Hi. In this series we're going to learn about Cycle.js, a JavaScript framework based on RXJS and the virtual DOM. We're going to start by building our own toy version of Cycle.js. It's not going to be that hard, and it will help you understand what happens under the hood, and it's actually quite simple. Here we have JSBin and it's an empty project. First we need to add our RXJS as a library. Then after that, we just make a DIV here, and empty DIV say with ID app, and empty content. This is where our app will be mounted on.

You can see everything will happen under this element. So that's on the HTML side, everything is ready and our goal will be to build on the DOM a timer saying seconds elapsed, and 0, 1, 2, and so forth. So how do we do that? First we create an observable of a timer that starts at 0 and tickets every 1 second. If you plot this over time it starts at the number 0, and ever second it gets incremented. It's a timer. We can match each of these i numbers in this observable to a string saying seconds elapsed is i.

Now that we have that, what we just need to put that on the DOM. How do we do that? By subscribing to this event stream, and then we need to somehow get this text string and put that on the DOM. We need to fetch the container element that we created on the DOM, the id app element by val, and then we just need to put the text string on the text content. There we go. So now we have this app that shows seconds elapsed and ticking every second. This is not Cycle.js yet, but it's getting there.

The guiding principle in Cycle.js is we want to separate logic from effects. This first part here was logical, and this second part here was effects. Effects are everything that change the external world somehow, the real world such as the DOM is connected to the browser, which is the connected to the user, so when we do something like set the text content, we are changing the screen that will shown to the user. So things like console.log and HTTP network requests, all of these things are effects, and these things live in subscribes.

Logic on the other hand, this is not changing the external world anyhow, it's just an event stream of numbers every second, and we're mapping that event stream to another event stream with strings. This part here is functional, it's all about mapping some primitives to others, and this side is imperatives. Our guiding principle for Cycle.js is we want to push subscribes as far away as we can from our app.

So this part of subscribe we want this to live in the framework, and this part is the only thing that the developer will write as the app. That is the guiding principle to separate logic from effects.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?