(FRONT) FRONT (2022)

My RxJs learning conspectus

1. Animation with RxJs based on MouseStream + my small SelfTest

I found time to upload my old SelfTest to Github https://github.com/Alex-1347/RxJsSelfTest, this test interesting also for my solution to load RxJs library without WebPack, with Require.JS only.

   1:  <!DOCTYPE html>
   2:  <html lang="en">
   3:      <head>
   4:          <meta charset="UTF-8">
   5:          <meta name="viewport" content="width=device-width, initial-scale=1.0">
   6:          <title>RxJs-Canvas</title>
   7:          <script>var exports = {};</script>
   8:          <script src="http://requirejs.org/docs/release/2.3.6/comments/require.js"></script>
   9:          <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.1/rxjs.umd.min.js"></script>
  10:      </head>
  11:      <body>
  12:          <canvas id="canvas" width="800" height="800" style="border: 1px black solid;"></canvas>
  13:      </body>
  14:      <script type="text/javascript">
  15:          require.config({
  16:            paths: {
  17:                "rxjs": "https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.8.1/rxjs.umd.min.js",
  18:            },
  19:            waitSeconds: 5
  20:          });
  21:          </script>
  22:          <script type="text/javascript">
  23:                  const canvas = document.getElementById('canvas');
  24:                  const ctx = canvas.getContext('2d');
  25:                  function drawCircle(x, y) {
  26:                      ctx.beginPath();
  27:                      ctx.arc(x, y, 5+ Math.random() * 10, 0, Math.PI * 2)
  28:                      ctx.fillStyle = getRandomColor()
  29:                      ctx.globalAlpha = Math.random()
  30:                      ctx.fill()
  31:                  }
  32:                  function getRandomColor() {
  33:                      var letters = '0123456789ABCDEF';
  34:                      var color = '#';
  35:                      for (var i = 0; i < 6; i++) {
  36:                          color += letters[Math.floor(Math.random() * 16)];
  37:                          }
  38:                      return color;
  39:                  }
  40:                  require (['rxjs'], (x) => stream(x));
  41:                  function stream(x){
  42:                      var sourceStream = x.fromEvent(document, 'mousemove');
  43:                      var subscription = sourceStream.pipe(x.auditTime(100)).pipe(x.debounceTime(100)).subscribe((e)=> {
  44:                            console.log(new Date().toLocaleString(), `x:${e.clientX},y:${e.clientY}`);
  45:                            drawCircle(e.clientX, e.clientY)
  46:                      });
  47:                  }
  48:        </script>
  49:  </html>

2. RxJS Interview

14 - What are pros and cons of RxJS.mp4
15 - How to transform data in RxJS.mp4
16 - How filter works in RxJS.mp4
17 - How to implement error handling in RxJS.mp4
18 - What does combineLatest operator work in RxJS.mp4
19 - How Subject and Behaviorsubject work in RxJS.mp4
20 - Observables vs Promises what is the difference.mp4
21 - Cold vs hot observables what is the difference.mp4
22 - ConcatMap vs SwitchMap vs MergeMap vs Map vs ExhaustMap in RxJS.mp4

RxJS is stream transition library, what can transform data on observable stream. Click events, any data, API call, local storage - all of them is a stream, created by observable. We can combine stream, filter and processing data inside that stream. We can subscribe to stream at any time. When we receive data on stream we will rendering components, therefore application is reactive. Stream programming with RxJs mach more difficult than on JS, because we need combine a lot of operators and function from RxJs. Usually no sence to use Angular without RxJs.

15. Processing observable data inside Pipe with RxJs Map and JS Map.

Use '$' as suffix of RxJs variable this is conventional mark Observable variable.

Observable is generic, this is correct definition for required function.

We have to use Map, but inside Pipe, Pipe allow to use sequence, all of them will using inside Pipe one-by-one, and result of previous function will pass to next.

And inside RxJs Map we will use JS Map with every simgle user.

This is difference between RxJs Map and JS Map - inside JS Map callback we receive only one item of data, but inside RxJs map callback we receive all array of data.

16. Filter.

The same login with Filter. On JS we have inside filter logic to filter

Correct function interface

RxJs Filter we need to use inside Pipe

And inside RxJs filter we receive all data items

And inside RxJs Filter we need to use JS Filter with Every and only than comparison predicate.

And how we can call this function?

RxJs Of() function allow create observable stream from plain data

Result of this function will be observable, we can subscribe to this result

17. Error handling inside Observable pipe.

We can not use JS Throw, we need to use dedicated RxJs method CatchError inside pipe.

But result of Error handling function will be different than on normal case

Therefore we need to create empty pipe (observable result) with Of()

How we can use this function on Angular component? Put function inside Angular component (to constructor).

But if we generate JS Throw inside Mao, we receive exception on component and page failed

Therefore we need to provide Next branch inside Subscribe and handle error inside Subscribe (and maybe Complete branch.

18. CombineLatest allow processing only last emitted event from series

We create 3 separate streams, without CombineLatest we have all 3 streams

But with combineLatest and Interval we always receive result only from last stream

19. BehaviorSubject and Subjects. BehaviorSubject is possibility to create stream and than update data inside stream.

Prepare UserInterface and inside BehaviorSubject we will use UserInterface. Default value we need to use inside "()" BehaviorSubject

In this case defaul value will be empty array

We will use SetTimeout to simulate User Click

And inside SetTimeout we will use Next() method of BehaviorSubject to update Value inside stream. And we will subscribe to Observable stream.

So, after 2 seconds we have new value

BehaviorSubject also has method GetValue to ger access to data on stream. GetValue we can receive directly at any place without subscription.

Subject has we use without brackets, this method has no stored default value. But we alse can set value on Subject with method Next and read with GetValue. In reality usually we used BehaviorSubject instead Subjects.

20. On React we can not use Observable, usually we use Promise only. But in Angular we usually don't use Promise, we always working with Observable. Promise working only once, but with Observable we suscribe to stream and receive all events on that stream.

Simplest way to create observable with operator Of()

ToPromise allow to convert observable to Promise. For example mouse moving on the screen is observable, we can subscribe to this variable and receive all mouse events.

After converting Observable to Promise we need to use Then

With Promise we can receive another value than initial "1" on this case. There are no way to update value like Next on Observable.

21. Cold and Hot observables. Observable are lazy, HttpGet sending nothing, it will be never executing without subscription.

We provide Random value inside Next() method

And different Subscribe give us different value, because each Math.Random working inside different subscriptions (Observable stream, that working independently each on own thread, there are no sync between that thread).

But if we put to the Next() only reference to Math.Random, we will receive the same value on different observable stream.

22. Difference between RJs xxxMap() operators. All xxxMap operators just transform data inside observable pipe without subscription.

This demo allow to use different xxxMap() operators.

On this test we use RxJs From() allow allow create observable stream one-by-one. And inside pipe we just multiply each element.

And now we will create Delay inside pipe. FlatMap (the same as MergeMap)processing each value inside pipe without waiting previous one.

ConcatMap give us delay between value, because every next observable wait when previous observable to be complete before creation. This is cool method to wait HttpResponse before we doing something.

SwitchMap cancel all previous observable.

ExhaustMap ignore all next value on the same pipe (if we have running observable).

And now teacher try to demonstrate how different xxxMap give us the same result.

This two user simulate two different result, this is simulation of API call.

Second Observable pipe working inside first, ConcatMap is totally fine in this case

But with SwitchMap we receive the same result. Why? Because on Angular we always use HttpRequest just as Promises and therefore we always has only one result on pipe!

3. Объясняю RxJS

Usually RxJs give us more compact code rather than without RxJs

Promise is cool async realization on JS, and highly related with JS.

We usually mark Promise function with suffix Async, rather than Observable variable. Observable variable we marks with "$"

JS Async/Await is very similar to Async/Await on VB.NET/C#

New promise and "than/catch" is the same, we can call than/catch only once for each promise.

From and ToPromise allow converting Promise to Observable.

But Promise has another logic than Observable. With Obsevable we can subscribe to event many times, for example serial of click on button generate serial of events.

RxJs source (all functions) https://github.com/ReactiveX/rxjs/blob/master/packages/rxjs/src/operators/index.ts

And deescriptions https://github.com/ReactiveX/rxjs/tree/master/apps/rxjs.dev/content/guide

And descriptions https://www.learnrxjs.io/ - contains 4 subjects variables and various functions inside Pipe (grouped by type and marked as most important).

Observable Of can create serial of events, and finish function working after all events (this is difference with Promise). All Observable has methods "next/error/complete".

All meaningful and sensitive operation doing inside Pipe functions - https://www.learnrxjs.io/learn-rxjs/operators, each functions receive callback as parameter

After Map working Filter, and filter working with result of Map.

But Map/Filter and other function inside Pipe is only plan, real working doing only in subscribe, if we commented Subscribe - code don't working at all.

Tap function is usefull for logging, but this code is not a best practice, best practice to use all request to backend on separate service.

Test project woth FromEvent and two dynamic components

DebounceTime function and the same function without RxJs, this function filter events and events fire after user stop typing.

Both components subscribed to the same variable

But deleted component not showing on page, but can not deleted from memory, because it has subscribed variable. This is memory leak.

One way to avoid memory leak is OnDestroy event and UnSubscribe

Another cool method is Angular AsyncPipe

And alternative methods - with function TakeWhileand Angular Attribute

Other real project with map what sick to mouse.

This project based on Filter function (left mouse button only), than SwitchMap switch to another event. As a result we have drawing on another position.

Slider component with BehaviorSubject and without RxJs.

There are 4 objects what allow subscribe, this objects derived from simple Observable variable and can cast to Observable and has all observable methods

BehaviorSubject can store value, but Subject has no value.

4. Understanding Observables

5. RxJS Crash Course

6. RxJS Complete Course Guide

7. DecodedFrontend Interview questions

8. RxJs from Angular University.

Course source

Start on my computer

Backend data service

Two command need to start this project on two separate window - backend and frontend - npm run server and npn run start.

API working on port 9000

Current code idiotic, this is promise only code, really it working when Filter applied, therefore this code call API twice.

What is Callback hell on JS. Observable is only plan, real executing doing filter.

We need to reach this final point step by step.

So, start service. We can use Promise, but will use Observable with typed result.

Most important operator of RxJs is Map - https://rxjs.dev/api/operators/map

Convention about naming Observable variable with suffix $, we will use two Observable variable.

Standard consuming Observable variable on view, Angular Async pipe avoid any potential memory leak.

Idea is loading all course once, then filter twice. Sort Observable data with Pipe.Map.

This is sort handler.

We receive result even worst - API require 3 times, because API required from Form and 3 subscriber generate 3 request.

Solution is ShareReplay https://rxjs.dev/api/index/function/shareReplay, we keep result in memory than share to subscribers,

Go to refactoring next component, this component will working with Input parameters.

.... will continue soon...

9. RxJs book.


Related page

Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19>  <20>  <21>  <22>  <23
Link to this page: http://www.vb-net.com/RxJsLearning/Index.htm