00:00:00
in this video i want to talk about risk
00:00:02
js rxgs streams observables and how to
00:00:06
use rxjs inside angular
00:00:09
[Music]
00:00:11
and actually inside the rxjs we have
00:00:14
hundreds of different methods and it is
00:00:16
really difficult for beginners to
00:00:18
understand all these methods together
00:00:20
with angular this is why in this video i
00:00:23
want to focus only on things that i am
00:00:25
using inside rxjs every day because they
00:00:29
are super efficient and is needed in
00:00:31
every single project and the first thing
00:00:33
that i want to talk about in rxjs is the
00:00:36
function off as you can see here i have
00:00:38
an array of users and this is just a
00:00:40
plain javascript array and let's say
00:00:43
that we want to create a stream from
00:00:45
some data and for this we can create
00:00:47
user swiss dollar and with dollar bill
00:00:49
market our streams and here we can write
00:00:52
off and this is a function of rick's
00:00:54
jazz and inside we can pass whatever we
00:00:57
want this is just a plain data in our
00:01:00
case we can write directly these dot
00:01:02
users and we must import this off from
00:01:05
rxjs so what a function does it converts
00:01:09
plain data in the stream and now as you
00:01:11
can see here user's dollar is an
00:01:14
observable of an array with objects of
00:01:17
id name and dejective and this is really
00:01:19
a nice way to just convert your plain
00:01:22
data inside stream if you for some
00:01:24
reason want to work with them like with
00:01:26
stream and typically what all people are
00:01:29
doing when they're just starting with
00:01:30
rickjs or angular they simply write here
00:01:34
implements only need and after this they
00:01:37
just subscribe to all the streams we
00:01:39
subscribe and use plain data inside so
00:01:42
they are writing something like this
00:01:44
users subscribe and we are getting here
00:01:47
our list of users and now we are doing
00:01:49
something with them for example
00:01:51
console.log and here we are getting
00:01:53
users this is totally fine as a beginner
00:01:55
approach as you can see it is working we
00:01:58
are getting here inside subscribe access
00:02:01
to our array of users but actually this
00:02:03
is not how it is intended to be used
00:02:06
because risk js inside angular shines
00:02:09
when we are using it together with a
00:02:10
sink pipe and actually when we are using
00:02:13
subscribe as little as possible so the
00:02:16
typical use case here will be to render
00:02:18
this array of the users and for this we
00:02:20
should not use subscribe we can use a
00:02:23
sync pipe inside angular this is why
00:02:26
what we can do here we can just write
00:02:28
here div and we want to loop through our
00:02:30
users this is why here we are just
00:02:32
writing in g4 and we want to access
00:02:35
every single user inside of a stream of
00:02:37
users but this is a stream we can't
00:02:40
write code like this after this we must
00:02:42
write a sync pipe and in this case n
00:02:45
global itself subscribe to the stream
00:02:48
and when it gets data it will convert
00:02:51
these users to just plain array of users
00:02:53
and here inside this div now we have
00:02:56
access to every single user and we can
00:02:58
simply render here user.name for example
00:03:01
let's check this out as you can see here
00:03:04
we just see our plane array we don't
00:03:06
need to bother here with subscriptions
00:03:09
or with streams which actually means if
00:03:11
you can use a sink pipe inside angular
00:03:13
instead of word subscribe just do it it
00:03:16
is much better because in this case
00:03:18
angular itself creates this subscription
00:03:21
and destroys it when you are destroying
00:03:24
your component if you are doing
00:03:25
subscribe like this then you must
00:03:28
yourself unsubscribe inside on destroy
00:03:31
if you won't do it then you will have a
00:03:33
hanging subscription but typically
00:03:35
people don't understand how they can
00:03:37
transform data with rxjs this is why
00:03:40
they just want to get rid of rxjs and
00:03:42
just write subscribe and inside plain
00:03:45
javascript code this is a bad approach
00:03:48
this is why here i want to show you some
00:03:50
methods that will help you to work with
00:03:52
subscriptions let's say here we have an
00:03:54
array of users and this is actually a
00:03:56
stream and we can say that these users
00:03:59
maybe are not available inside this
00:04:00
component so we simply work with this
00:04:03
stream these users might come for
00:04:05
example from an api so this is just a
00:04:08
stream and we want to get here an array
00:04:10
of our user names which actually means
00:04:13
here from every single object we want
00:04:15
just to take a name and typically people
00:04:17
will write subscribe and write it to
00:04:19
some property but we can do much better
00:04:22
we can create here a new stream which is
00:04:24
called usernames and here we want to
00:04:27
take our stream these users and now we
00:04:30
can transform it and to transform a
00:04:32
stream we must use a pipe this is
00:04:35
mandatory but as pipe this is a function
00:04:38
which help us to organize one by one all
00:04:41
our functions inside which actually
00:04:43
means here inside we have function one
00:04:45
function two and function three for
00:04:47
example which actually means this is a
00:04:50
list of functions which will transform
00:04:53
one by one our stream so these users are
00:04:56
going through function 1 then function 2
00:04:58
then function 3 and the result of that
00:05:00
function will be written here inside
00:05:03
username so how we can use it here for
00:05:06
example inside our pipe we can write
00:05:08
another function which is a map and
00:05:10
actually map is the most popular
00:05:12
function inside the rix chess and we use
00:05:15
map if we want to transform our data
00:05:18
which actually means here inside map now
00:05:20
we're getting access to our users and we
00:05:23
can simply just return these users and
00:05:25
don't do anything with them as you can
00:05:27
see here users is an array of our
00:05:30
objects exactly what was here in the
00:05:32
stream and the main idea is that here
00:05:34
inside map we can write synchronous code
00:05:37
like plain javascript which actually
00:05:39
means if here we want to get our names
00:05:41
we can simply write users.map we're
00:05:44
getting access to every single user and
00:05:46
here we can write user dot for example
00:05:49
name and we will map every single user
00:05:52
which actually means here in usernames
00:05:54
dollar as you can see here we get an
00:05:56
observable of string array so it is not
00:06:00
object array anymore this is an array of
00:06:03
names and actually for this we don't
00:06:05
need subscribe we don't need to create
00:06:07
additional local properties and check
00:06:09
that we fulfilled our subscribe here we
00:06:12
simply have a stream which is based on
00:06:14
our first stream and now we can just
00:06:16
jump inside our html copy paste this
00:06:19
code within g4 and write it for our user
00:06:22
names with dollar and with the sync pipe
00:06:25
and here we are getting access to every
00:06:27
single username and we can simply render
00:06:30
it here it is user name and now i just
00:06:33
want to comment out our first div we
00:06:35
don't need it anymore and as you can see
00:06:37
in browser it is still working just as
00:06:40
intended but here we are using
00:06:42
completely another stream which we just
00:06:44
created based on our first stream so if
00:06:47
you need to transform data inside the
00:06:49
stream to another stream it makes a lot
00:06:51
of sense to leverage map function inside
00:06:54
rxjs another super important function is
00:06:57
filter inside rxjs and actually you can
00:07:00
understand from the name it filters our
00:07:02
data but actually it is not working like
00:07:05
filter inside javascript when we are
00:07:07
filtering an array inside javascript we
00:07:10
simply leave less elements but when we
00:07:12
are filtering stream it means that we're
00:07:15
just coming through the stream later if
00:07:18
the predicate is true what does it mean
00:07:20
for example here we can create filtered
00:07:23
users and this is also a stream and we
00:07:26
want to get here only users when they
00:07:28
are active which actually means if every
00:07:31
single user in our array of users is
00:07:33
active then we will get here our users
00:07:36
if one of the users is inactive then we
00:07:38
will never get here this stream will
00:07:41
never be fulfilled how we can write it
00:07:43
we can write here these users and we
00:07:46
want to use also pipe as always and
00:07:48
inside we pack not map but we are
00:07:50
packing here filter and inside we are
00:07:52
getting access to our users and we must
00:07:55
return here true or false which means if
00:07:57
we are returning here true as a
00:07:59
predicate then the stream will be
00:08:01
directly fulfilled but here we want to
00:08:03
write some logic and we want to check
00:08:06
that every single element inside users
00:08:09
is active this is why here we want to
00:08:11
check user dot is active so a function
00:08:14
inside filter must return true or false
00:08:16
in our case here we are checking every
00:08:18
single element for is active and now
00:08:21
here let's try to render our filtered
00:08:23
users for this i will copy paste the
00:08:25
first div that we have and just
00:08:27
uncomment it here and we want to go
00:08:30
through our stream filtered users here
00:08:32
we have access to every single user and
00:08:34
we are rendering it let's check this out
00:08:37
as you can see here is our list and they
00:08:39
want to comment out this thief because
00:08:41
we don't need it anymore as you can see
00:08:43
here all our names are there which
00:08:46
actually means the stream was fulfilled
00:08:48
but what will happen if one single user
00:08:51
here will be false
00:08:53
in this case here inside filter we will
00:08:55
get false and this stream won't be
00:08:58
filled with data and as you can see here
00:09:00
nothing was rendered and actually if you
00:09:02
will try here to uncomment this user
00:09:05
subscribe and change it to filtered
00:09:07
users then you will never get inside
00:09:10
subscribe as you can see here it is not
00:09:12
happening because it is filtered our
00:09:14
user is inactive but here now we can
00:09:17
change it to true and at this very
00:09:19
moment we are getting here users inside
00:09:21
console and our users are rendered here
00:09:24
and it makes a lot of sense to write
00:09:25
code like this when you want to filter
00:09:28
your stream and as i already said we are
00:09:30
using pipe and actually we can combine
00:09:32
different things for example here we
00:09:34
could take our map completely from here
00:09:37
from our pipe and just put it here after
00:09:40
our filter which actually means here is
00:09:42
our first function inside pipe here is
00:09:44
our second function to map our data this
00:09:47
is completely fine and typically we
00:09:49
combine our functions like this another
00:09:51
thing that you will use every single day
00:09:54
is behavioral subject and it might sound
00:09:56
really scary but it is not what we can
00:09:59
do here we can create a new stream which
00:10:01
is a user and here we simply write new
00:10:04
behavior subject and inside we must pass
00:10:07
what data we have inside so for example
00:10:10
i would say that we have here id string
00:10:13
and name string or we have here now
00:10:16
which actually means inside this stream
00:10:18
we have two possible values this object
00:10:20
or a null and here we must open round
00:10:23
brackets and set the default value and
00:10:25
typically we'll write here null which is
00:10:28
a default value while we're writing code
00:10:30
like this typically we want to fetch
00:10:33
some data from the backend from the api
00:10:35
and this will be your stream which you
00:10:37
want to fill with data which actually
00:10:39
means you have a page where you are
00:10:41
rendering your user and by default you
00:10:43
don't have any user this is why inside
00:10:45
stream you have a null but then after
00:10:48
some time you fetched the data and you
00:10:51
put them inside your user stream at that
00:10:53
very moment your stream must be
00:10:55
automatically rendered this is exactly
00:10:58
why we need behavior subject behavior
00:11:00
subject is a stream that we can update
00:11:03
and how we can do that for example here
00:11:05
inside engine in it what we can write is
00:11:08
set timeout to show that this is an api
00:11:11
call and here inside set timeout for
00:11:13
example with 2 seconds i want to update
00:11:16
this user for this we are writing this
00:11:18
dot user with dollar and here dot next
00:11:22
and we are using next function when we
00:11:24
want to update our behavior subject and
00:11:26
as you can see here we can't just throw
00:11:28
foo it is invalid we must write here
00:11:30
either now or our valid user this is why
00:11:33
here i will write id 1 and name john and
00:11:38
this is the valid type of data so once
00:11:40
again what we have here we have a
00:11:42
behavior subject which is just a stream
00:11:44
and by default it is now then at any
00:11:47
moment we can use this user next and set
00:11:50
some other data there and this will
00:11:52
update our stream which actually means
00:11:54
in different places we can subscribe to
00:11:56
the stream and then all these places
00:11:59
will be notified about new data this is
00:12:01
why here we can write this dot user with
00:12:04
dollar subscribe and here we're getting
00:12:06
access to our user and now here i just
00:12:09
want to console.log user so you can
00:12:11
understand how it is working i'm
00:12:13
reloading the page as you can see here
00:12:14
user is now and then after two seconds
00:12:17
we are getting user and here is our
00:12:19
object which actually means this is a
00:12:21
typical approach when you are working
00:12:23
with api by default your data is now
00:12:26
then after you fetch them you can simply
00:12:28
write this user next for example and
00:12:31
then you are setting data inside your
00:12:33
stream and your stream will be rendered
00:12:35
on the page this is why how we can
00:12:37
render this data now we can just write
00:12:40
here div and we want to write here ng if
00:12:43
because actually we want to render this
00:12:44
user only when it is not null for
00:12:47
example we want to render a name and for
00:12:49
this we can write here user dollar a
00:12:52
sync pipe and actually a lot of people
00:12:54
are writing like this inside this div
00:12:56
they simply render user dollar then a
00:12:59
thing and actually this can return you
00:13:02
now this is why they are writing
00:13:03
question mark dot and then name which
00:13:06
actually means here we are waiting for
00:13:08
this sync pipe if it is there and it is
00:13:10
not now then we are rendering name as
00:13:13
you can see this code is working here is
00:13:15
our john but this code is really bad why
00:13:18
that because here we first of all create
00:13:20
two different subscriptions and yes
00:13:22
angular creates them for us but it
00:13:25
doesn't matter this is first
00:13:26
subscription this is second subscription
00:13:29
it doesn't make any sense and also this
00:13:32
code is not looking really good what we
00:13:34
can write instead we can write here as
00:13:37
user in this case here we're creating
00:13:39
inside this div a local property user
00:13:42
and now inside we can write
00:13:44
user.name and actually this code is
00:13:47
working completely fine because first of
00:13:49
all this ngif checks if our user is
00:13:52
there which actually means if our user
00:13:54
stream is null then we won't come here
00:13:56
inside div and we don't need to write
00:13:58
any checks like with question mark that
00:14:01
this name property exists we will get
00:14:03
here only when our user will be
00:14:05
fulfilled another important function
00:14:07
that you will use from time to time is
00:14:09
from event inside rick's chess and
00:14:12
actually from event helps you to work
00:14:14
with dom events like with streams and
00:14:17
this is extremely efficient for example
00:14:19
here i can write document click and this
00:14:22
is a stream and here i can use from
00:14:25
event and inside i must first of all
00:14:27
pass a dom element this is a document
00:14:30
and then the event for example click in
00:14:33
this case here i am not working with dom
00:14:35
events i have here a stream and i can
00:14:38
work with stream just like with any
00:14:40
stream for example here we can write
00:14:42
this document click subscribe and here
00:14:45
we are getting our event and here we can
00:14:47
just write console log event let's check
00:14:50
this out i'm reloading the page and i'm
00:14:52
just clicking on our page and as you can
00:14:54
see here we're getting our event just
00:14:57
like normal subscription to the document
00:14:59
click but here you might say okay but it
00:15:02
doesn't make any sense for me using this
00:15:04
from event is confusing i can just write
00:15:07
plain javascript with dom and yes you
00:15:10
can but the main idea of streams is to
00:15:12
combine them which actually means if you
00:15:14
have just a single event it doesn't make
00:15:17
a lot of sense but if your api calls are
00:15:19
streams if your data for your state are
00:15:22
also streams and your dom events are
00:15:24
streams then you can combine them
00:15:26
together and this is really easy
00:15:28
insiderix chess this is why rxgs by
00:15:31
default is not better than a single
00:15:33
event on the document but if you want to
00:15:36
write more advanced stuff inside angular
00:15:38
it makes a lot of sense to use rixjs
00:15:40
everywhere and the last method that i
00:15:42
want to show you is extremely important
00:15:45
and this is exactly a topic of combining
00:15:47
our streams of data and what i want to
00:15:50
show you is a function which is called
00:15:51
combined latest and we're using it to
00:15:54
combine our streams and typically what
00:15:56
you want to do you want to take all your
00:15:58
streams for the component and combine
00:16:01
them in one single object in this case
00:16:03
it is much easier to support a component
00:16:06
and your markup inside html will be much
00:16:08
cleaner let's try this out now as you
00:16:11
can see here we have our users dollar
00:16:13
usernames dollar and filtered user
00:16:16
dollar and let's say that we need all
00:16:18
these data all the streams inside our
00:16:20
html and what we can do we can combine
00:16:23
them in a single stream of data this is
00:16:26
why here i want to create data dollar
00:16:28
and they typically name combined streams
00:16:30
like data dollar and here we can simply
00:16:32
write combine latest and this is also a
00:16:35
function from rick's jazz and here
00:16:38
inside we're throwing an array of
00:16:39
streams and here first of all we want to
00:16:42
write this user's dollar then this
00:16:45
usernames dollar and then this dot
00:16:48
filtered users dollar and actually here
00:16:51
we could also write document click but
00:16:53
it doesn't make a lot of sense the main
00:16:55
idea is that any streams can go here
00:16:58
inside but here is a problem what we
00:17:01
will get back an observable of array and
00:17:03
inside array we have these three
00:17:05
elements it is not comfortable to work
00:17:08
like this inside html this is why what i
00:17:10
like to do is map this data so here we
00:17:13
can write pipe map like we did
00:17:15
previously and here we have access to
00:17:17
all three data inside our array so this
00:17:20
is first of all users then our user
00:17:23
names and then our filtered users and
00:17:25
what we can do here we can just return
00:17:28
this data like an object and inside we
00:17:31
will have first of all our users then
00:17:33
our user names and then our filtered
00:17:36
users which actually means we simply
00:17:38
combine our streams we map them to the
00:17:40
object and now this data dollar is an
00:17:43
observable of the object and here we
00:17:45
have first of all key users then user
00:17:47
names and then filtered users and with
00:17:50
this structure it is much easier to
00:17:52
write html we can jump to our app
00:17:55
component and now just write here div
00:17:58
and give and what we want to do here we
00:18:00
want to resolve this data stream this is
00:18:02
by here data dollar is sync as data and
00:18:06
now inside this div we have access to
00:18:08
everything inside data data users data
00:18:12
filtered users data usernames which
00:18:14
actually means we can copy paste all
00:18:17
this code inside our div and change it
00:18:20
and now we just work with the data
00:18:22
without any streams this is why here let
00:18:25
user of data dot users now here we have
00:18:29
user names and actually it will be data
00:18:32
dot usernames and we can remove a sync
00:18:34
pipe and here is our filtered users this
00:18:37
is data dot filtered users and now just
00:18:40
to bring some understanding i want to
00:18:42
put dashes here inside markup let's
00:18:44
check this out as you can see now on the
00:18:46
page it is working and we have three
00:18:48
sections first of all our users then our
00:18:51
usernames and then our filtered users
00:18:53
and actually this is the best possible
00:18:55
approach that you can use if you want to
00:18:57
combine different streams of data and
00:19:00
render them inside your component and
00:19:02
actually if you are interested to know
00:19:04
how angular animations are working make
00:19:06
sure to check this video also