Hello, Welcome to Adventures and Angular. It's been a while. This is
the podcast where you keep you updated on all things Angular related. This show
is produced by two companies, Top and Doves and Onoid. Top and Doves
is where we great Top and Doves we get top and pay and recognition while
working on interesting problems and making meaningful community contributions. And Onvoid, which offers
more design and software development services on a task basis, so clients only pay
when tests are delivered and approved. In today's episode, we will talk about
reactiveness and Angular and how you can still use urxgs, so that's correct.
We're not necessarily going to talk about signals today, although we might touch on
the subject, but how you can simplify your reactivity while still using rxgs and
well, for that we have a variouspect guests. So Dean Radcliffe is a
web developer of many years and the creator of our ex facts, which is
the library we're going to be talking about throughout this episode. So we're going
to get back to Dean in a second. But also joining me in today's
episode is Arman Vardanian. Hey, everyone, first episode this year. I
missed you, yeah, and well I am Lucas Paganini, one of the
other hosts in the show. So let's get started. So Dean, yes,
sir, please pitch our XFCX to the audience. All right, our
xffcts, that's our ex FX is framework independent state management and effect management with
concurrency control like our extra has, and it is built on r XJS.
It's interoperable with r XJS, but it brings a better developer experience and a
shorter learning curve than using only r x JS. Compared to r xjs,
RX effects will still concurrency control your ACYNC functions like with those concat map switch
map operators, but in a way that will be simpler, safer, and
with greater readability. Okay, that's really interesting, And I was I was
actually taking a look at the MEPO so the route. I noticed that,
like in the peckyjson file, you don't have RXS as a dependency. So
I do have our xs as a dependency, but not in the root.
Oh not in the route. Okay, repository is a is a the it's
a like Lucas said, there's an installation of libraries and they the primary ones
are going to be RX effects, slash bus, RX effects slash effect and
rx effects slash service, and they each provide similar reactive and concurrency control benefits,
but with a little bit of a flavor and different different mental models.
So, for example, the bus is an event bus. It was actually
derived from a simple rx JS event bus that the company I don't know,
somebody posted I can't remember the name or the exact company name it was.
I had to do with the RxJS creators. There was a simple event bus,
and then I built on that event bus, and the event bus brings
pub sub benefits. So so that's like you trigger an event somewhere and an
event listener responds by running an async function, but that listener can be concurrency
controlled. So imagine having your RxJS operators kind of baked in to the listener.
So that's the bus model. It has the advantage of your code that's
triggering events. Say you have a component that triggers an event when it's clicked
to save something to a database. But now you want to send an analytics
event that that button was clicked, right, So the published subscribe pub sub
metaphor says you don't have to go into that component with the button and add
code to it you can listen for that click event with a bus listener and
then you know, send analytics events that way. And I've done this on
an application that had many many questions gens. It was a survey application,
and the goal was that once we developed a question type that we wanted to
keep that component closed like closed to modification, we should be able to extend
the behavior of the components without having to go in and modify the components.
And so by having each component put an event on the event bus, it's
easy to add event listeners like an analytics listener. And suppose you want to
say your analytics events should be sent serially so that they don't take up more
than one HTTP connection at a time, Well, then you just set the
concurrency mode of that listener. And that also gets you out of the pickle
of you if you were to modify the component and you'd have some code that
says save to the database and some code that says analytics, Well, is
there a correct order to put those calls? And if you put the analytics
call first and that analytics call errors for some reason, is that going to
keep it? Are you going to keep from needing to you know, is
that going to prevent the database call from functioning. So it's actually much cleaner
not to keep piling things into the one component, but to set up separate
listeners. And another benefit of our x effects is error handling. So if
that analytics event listener acts up, it doesn't kill the safe to database event
listener. So you have separation through the pub sub metaphor like even more complete
separation and error handling then with raw rx JS. That's really that's really interesting
because in ourhgs, error handling can be a bit of a pain point for
lots of developers, Like there are are all of those tools. For example,
we have retry, retry when right with the count we have, we
could just schedule and so on, but some some of those tools, especially
I think from the perspective of the documentation, aren't readily like obvious that those
can be used for airror handling. And yeah, I'll honestly see lots of
people who have worked with the ourgis for a while, but they would probably
get confused by like what means we try when mm hmmm or something, or
how to what scenarios you can have with you know, error handling. So
yeah, there's this's this really sounds interesting. I'm just taking a look at
the effects library. Yeah yeah, Well you mentioned pain points with our x
g S and I was at a conference which side is a four years ago
called our x JAS Live, and I basically follow the RxJS core team and
I follow and listen to what people say the top pain points are with r
x JS, and of course as I hear them, I think, well,
maybe I could address that in rx effects, and I believe I have,
and so I'll touch on some of them. Tracy Lee and Ben Lesh
and j phelps the core people that give workshops on r x JS. What
they're suggesting you can, you know, get stuck on in which they'll help
you with. But our x effects will also help you with. Is okay,
So subscription management, when do you subscribe? What do you do with
subscription objects? How do you choose an operator? And is can cat map
or exhaust map correct for your case? And error handling? So I think
subscriptions, concurrency, and error handling are some of the biggest problems challenges people
have with r x JS, and our XFX has has solutions to all of
those with a simpler, developer friendly API. Oh one thing that I'm still
wondering about. Like, I'm seeing lots of different examples in the repole,
and I see very little RXGS in actuality. So is this meant to be
like a sort of total wrapper around rh just like you don't really need to
touch RGS itself for yes, but but you can grow to use all of
the r xjs features. It's truly interoperable. But so in the show notes,
I provided a link to a stack overflow post where I said, here's
a situation. You have a bell ringing function. It plays some audio,
and so it's async because it takes some time. Now you want to create
a web form with a button that rings the bell. Now, if that
button is wrung or clicked while the bell is ringing, you would have two
bells ringing at once, and it might overload your audio and sound bad.
So we want to concurrency control the bell like put them in a queue,
or cut off the previous bell, or throttle like. So we want a
concurrency control mechanism. And we also want cancelation because what if the user just
wants to cancel on that bell. Simple example, there's a there's one button
to ring, one button to cancel and a concurrency control. Well, I
sketched out what I thought the RxJS version of that was, and it was
about about fifteen lines. There were two subjects, there were various imported operators
take until there actually needs to be three subjects, uh take until a switch
map. It was. It was what I call operator soup and the rx
effects. Given a function that returns a promise or an observable for ringing the
bell the audio, it's you know, one line to wrap it in uh
an effect with the create effect function, and it's one line to request it,
which is the same for r XJS, one line to like trigger the
bell ringing. But then cancelation is just dot cancel current and canceling. The
entire queue is dot cancel, current and queue. So it's a question of
when should you like deep dive into r x JS. Well, if you
want to tap something, if you want to do retry, when if you
want to use any of the fancy operators, if you want to zip two
services together, that's fine. But as far as concurrency control and cancelation,
like you shouldn't need to go into that much detail or have that many imports,
Like think about load dash, how you just take your function, pass
it into a load dash function, and get a new function out that has
new behavior. It should be that simple. That's the premise of OURXFX.
So once really got me interested when I was thinking about this in the context
of Angular and jar X. Could I, for example, and I will
tell you in a moment why I'm asking this, Like I have an observable
that does something something, Can I just pick it up and turn it into
an effect? Like I already have an observable that works in a certain way
that I want to sort of turn into in an RX affects effect to be
able to I don't know, cancel it or add something to it, or
pose it or whatever capabilities it offers. Do you have the observable as like,
do you have a function that returns an observable like an endpoint that returns
an AJAX observable, Like I mean a function that returns an ajax observable observable?
Yeah? Let me yeah, let me just give you the exact thing
that I was that I had in moment. So for example, in JRX,
we have the jur affects package, and it's very decent to create like
effects based on actions and so on, but it doesn't have very many features.
So essentially it provides with the function to sort of register and observable that
j RX will listen to whatever you wanted to do, and it gives you
the actions observable like whatever actions have in your I don't know application, and
you just mix them and then you have to go and use a bunch of
rs if you want something complex like ninety scenarios, just like I make an
HDP request and despatch this or that action. But sometimes you need like oh,
I want to retry this, is this something specific appensode or maybe in
some cases I want to throw away the previous requests start a new one.
But in other scenario, I want to do something else, and it becomes
as you mentioned, like an operator soup. In the effects it becomes really
so. And the funny thing is like injr X, when you create an
effect, like you have functional effects. Now you have a variable that represents
this effect, but you never use it. It would be great if you
could bring it to your component and for example, in some scenario button less
click and you could say, okay, cancel this effect or pose this effect
or something in that regard. So I was thinking if I could take this
egg observable that that is the thing that I need from juris. I need
to know what actions have. Yeah, and just I don't know, plug
it into this effect and maybe use it this way. So okay, I'm
still maybe, but let me help clarify it. So there are observables that
are like the sources of effects running and is that what? There is one
observable, Yeah, Jelicks gives you one observable. It's called actions actions where
an action is dispatched somewhere this action, will you know, send the new
EMISI. So actions that sounds that sounds like a hot observable. Yes,
that right, Okay, it's a hot observable. So with you generally wouldn't
have that wrapped in RX effects. You would you would maybe trigger some effects
based on a filtered set of actions, right, yeah. So so you
have observables like that that are hot and they are like the sources of information.
And then you have observables that I usually call cold, that are like
doing the effect, doing the AJAX, ringing the ball in the in the
context, in the context of the specific what ang X does. It gives
you a custom operator called off type and you can pass it actions that you
want. I want this action for example, if the load data action was
triggered, then it will all sort of filter out and only start working.
And then you give this entire thing to the create effect function that AnGR x
does, and then it reduces these facts. I think it has one or
two methods that you can use. You can definitely it has methods using human
testing like but the object that it returns itself, it doesn't have very many
other useful things. So that's what got me wondering that sort of enhance.
It just you the same pattern but instead just fed this effect to something from
RX effects, so that I will be able to try stuff on demand or
you know, sort of modified concurrency or whatever without going deep into RGS operators.
Yes, I mean, I hope so. But my big disclaimer is
that I don't work in Angular much these days, though I have, and
I developed this library when I was consulting and switching between Angular and React,
and so I wanted something that was portable I could take with me. So
as far as how to make this interact with n g r X, I
have not explored that use case, but my general sense of it is that
you would have any effect like ringing a bell. You would have your actions
of type, and then you would basically subscribe to those actions of type and
say when those come through, ring the bell, and now you have a
concurrency controlled cancelable bell. On the one hand, it's independent, and then
you might use RxJS if your actions are not U n g r X.
If your actions were already available through n g RX, then you could just
you know, send them to the to the service or effect. So that's
probably how it would work, but I haven't tried it. Yeah, that's
interesting. Like from the top of my head, what I could do is
create one and jr X SOCI just takes all actions and sentences to like x
effects service. Sounds like effect service, yeah or yeah. And so what
would be different is like, if you were doing this purely an n g
RX to cancel the bell ringing, you might have another action that you would
dispatch to do it. But with rx effects you wouldn't need that. You
would just go to the ringing bell service or effect and just say dot cancel
current. So in some in some ways it factors some things out of the
rx JS g r X land that you don't necessarily need to live in that
land. So for example, the the like I just said, cancelation,
you can just go directly to the ringing bell and cancel it, right.
But another thing is the status of whether the bell is ringing or not.
And there's a linked code sandbox in the RX effects documentation that has one of
these bells you can play with, but you want to be able to display
to the user whether the bell is ringing or not. And prior to my
prior to my working on RX effects, almost and almost every app I did,
I had a field in state called loading right or for a bell ringing,
I would explicitly code that into the state model. But then I said,
well, if you've got a promise that isn't resolved, if you've got
a bell that's still ringing, how come we don't automatically have access to a
field, like how do I have to build that into the state model of
my app? Because the problem with that is, you know, you have
all these examples that say, all right, well you're gonna have an angular
component that has a button and then you're going to use the HTTP client to
you know, fetch some stuff. So the first thing you do is you're
gonna, you know, set is loading to true, then you're going to
do the effect. Then when it's done, you're going to set is loading
to false. And that manual tracking of the loading state is bundled into RX
effects. You can track the loading state. So I also have an example
of a counter that's asynchronous. It takes two seconds to increment the counter,
and the state model only contains the count, but RX effects keeps track of
whether it's executing or not. Yeah, that's what I was And of course
we will now inevitably stumble into the signals topic because I was just yeah,
because you know, signals got now very deep integration despite them being not being
like even one year old. But we have now njr X signals, so
we can build your yeah like state management without like without the reduct spattern,
just with signals without observables. And I was thinking, like, the weak
point for me in NJRX signal is probably the fact because effects are essentially the
same that we have in angoric effects just baked into you know the signal land.
Yeah, and yeah, that got me thinking, especially with the loading
example, because there you will have to do like even more work because you
are inside a signal state, and like you start an HTP goal for instance,
you have to go like patch state loading through something like that, and
then you will have to you will always have to add this line of code
and the other line that's something like finalized patch state loading falls. And it's
not a pattern that I personally like. And you can't sort of make a
generic function that doesn't because of the loading state can be different depending on whatever
you are trying to accomplish, unless it resorts some magic strings or something.
But that's not a good solution to that. But I mean, yeah,
we've had promises since twenty fifteen and nine years later, like how come we
don't have like an abstraction that just automatically knows, Like how come we're still
writing manual loading states, Like why don't we have an abstraction that knows whether
it's executing or not and is cancelable if the endpoint of course returns an observable
Because promises are not so simple to cancel as observables. And that's one of
the greatest things about observables, and I'm super geeked on observables. They're coming
into the language, into the browsers are starting to integrate it slightly different API
than r XJS observables. I'm still learning about, like how am I going
to have to adjust my code when when those come into play? But but
it's it's I mean, our XJS is a tremendous library. If I could
give your listeners a little history lesson of ASYNC, I did a little research
to find out like how rx JS and promises evolved and and could I I
could do that an hour later. I mean, I mean we sort of
can. Yeah, but it's intastic. I've never thought about it this way
because I've never really worked with promises. I have worked with pies since I
since I started doing while I worked with promises when I was doing Angular jes,
we didn't have like we don't know much about urges back then then Angular
two drops in twenty sixteen, and yeah, since then, I've not really
touched promises that much unless I was I don't know, teaching someone about them
or stuff. I was really using them in the cold. But it never
like I just thought, you know, promises are sort of weak and observables
are very powerful, and I can do HTP cols with observable that yeah,
I don't care about promises. No, I mean that's that's actually very true,
and I don't think it's judgmental or critical at all. Promises you could
say, are a subset of observables, definitely right, and so you can
build the promise with an observable, but the reverse is not true. And
so yeah, so let me talk about mental models, because my mental model
has been evolving a lot over time, and I think I can clarify for
the listeners a lot of things that you hear about what observables are, because
that's even kind of, you know, confusing. So observables have been described
any number of ways. They've been described as lazy. They've been called just
functions and observables just a function, which is the hardest explanation I have to
ask. They've been described as streams of values, or they've been described as
promises with more than one value, so a lot of those are confused.
Oh. They've also been described as push collections. They've been described as is
it unicast or multicast? Well, it's unicast, But how do I tell?
It's very hard to piece together, like what the heck is an observable
with all of these explanations. So I have what I think is going to
be the final explanation of observable that people will need to hear. And here's
this. Observables are a template for a running process. They are like the
string ls dash l. Okay, so they're like the string ls dash l
because the string ls dash l is not executing. It's just a template from
which you can create a process that lists the files in a directory. Right,
So observables aren't really lazy anymore than a template is lazy because when you
click on the template to create a new document, it creates new document.
When you have a string, a command string to run a process, it
runs a new process. So yes, you can call them lazy because they
don't give you values until you subscribe. But that's exactly like the way that
a Unix command line string doesn't give you lines of output until you execute it
and hit enter. So you will get what can a Unix process do?
And this is what's so strong about observables. They can do everything that a
Unix process can do. They can have an exit code of true or false.
I mean basically, they can complete or error like an observable, and
they can produce one or more values. They can also produce zero values,
which is why the description of an observable as a stream of values it misses
the mark. An observable is a template for a running process. A running
process, which is a subscription, consumes some resources. So the main thing
about an observable is that it explains how to consume and release some resources,
just like a command line string tells you how to consume some resources, and
then it has a standard way of canceling it. So it's perfectly valid to
have a Unix command line like r M r F node modules, which doesn't
produce a bunch of values, and it's perfectly valid to have an observable that
isn't about values, it's about getting some work done. That's a that's an
interesting way of looking at it. Actually, I've never thought of that sort
of comparison. And it makes sense especially that we have like the well,
like the pipe operator rather pipe commands, pipe results throw and yeah, yes,
yeah, we sort of have the same thing. We can take observable.
Yeah, yeah, yeah, that's really interesting way looking at it.
Yeah, it's it's just so oh, it's just such a perfect match.
It's a template, it's a command line string. That's like a perfect match
for me. And so what I've found is that the best use of an
observable, which is of course a description of some work that can be done,
a template for doing work, the best use of an observable, and
pretty much the only thing you need to do in RX effects is use an
observable as a return value. So that's kind of talking about old observables,
but it could also be a hot I don't really find there's much distinction between
hot and cold. There's still a allocation of a resource that you can release
either way, and they may produce values or they may not. But so
observable is a great return value. And in our X effects, when you
return an observable from a function into an effect or a bus listener or a
service, you don't have to call dot subscribe on it, right And it
works because if you're ringing a bell and you have an observable for ringing a
bell, when the bell is wrong, you return the observable for ringing the
bell. Well, RX effects knows that if you return an observable, well,
of course I have to subscribe to it if the concurrency model says subscribe
right now, because there are concurrency models that don't say subscribe right away,
for example a blocking concurrency model also known as exhaust map. So observables make
a lot of sense as a return value. And I've written very large and
very async applications with RX effects using observables, and I never call dot subscribe,
just return an observable. So, for example, my flagship app for
personal use that I can share around is called Inbox Radio, and it lets
me dream music that has been sent to me in my Gmail inbox. And
so there's a lot of async going on there. You have to get messages
that match a pattern, then you have to get the attachments, and you
don't want to download them in parallel. You want to download them serially because
you're going to play them serially, and then you have to decode the stuff
then you have to play it. And so uh, these these chains of
things are not explicitly chained. The bus, the bus, the event bus
is sitting there, you know, making one of them subscribe to another.
And basically this whole thing doesn't have a can haat map explicitly written in it.
It has create queueing service, and it doesn't have dot subscribe because you
return an observable and RXFFX call subscribe on it. So that kind of takes
care of where do you put your subscription objects. Well, you don't generally
need to see the subscription objects in this. The exception to that would be
if you had an observable of button clicks, for example, and you needed
to like call an effect on every button click from that observable, then you
would subscribe to that outer observable and say, okay, each time a notification
on the observable comes in, then call this effect. So that's where you
would if you had like a native r XJS observable, you could totally call
dot subscribe on it and do whatever you want. But if you were returning
it as the return value from an effect or a bus listener, you wouldn't
need to tag dot subscribe on the end of it. That's fascinating Actually,
as you mentioned exhaust map and stuff, so it's nice to hear that,
uh, those sources of things are taking care of about because for the life
of me, I couldn't explain the difference between exhaust map and concat map.
I've looked it out like a bunch of times. I can easily explain difference
between Merge map and swishmap. Okay, so here's here's yeah, so here's
a here's a gift. This is for everybody. It's a free uh way
to keep all these things straight? Can you? Can you scroll down?
Uh in the RX effects repo yep, until you see effects one. Yeah.
I wasn't a service one because I think either one of them. So
do you see some cards that you have pictures on them? Oh? Jez.
By the way, if you're comfortable with that, we could even share
your screens. Some people can be watching from YouTube, so they could be
seeing the I would. I would happily do that. Sure, let's do
that. Okay, I think you're seeing GitHub repo. Yeah, okay,
So this is the RX effects main repo. And if you scroll down,
there's some code examples, and then there's a list of the libraries. Yeah,
the one. There's the fascinating set of cards. Yes, and so
here here is the Here is the set of cards that you can use.
I have not printed them myself yet on like true quality card stock, but
if people are interested in that, I would I would do that. I'd
love to have these at my desk. Well, when we collaborated with desks
next to desks and other people. But yeah, so this gives friendly names
to each of the each of the modes, it has pictures, and then
in the little in this window it says also known as merge map, also
known as cat map. So you know, my bias is to kind of
tuck rx JS into something as a bunch of implementation details. I'm not trying
to teach people how to, you know, necessarily use our XJS better.
If they can get the first ninety percent of use cases under friendlier names and
in a friendlier library, then that's kind of what I'm advocating for. I've
gotten several teams that I'm on to adopt this early in the development life cycle,
and then when people can use one of these, they use that,
and then it comes up against something that doesn't fit into that paradigm. Well
then you know, hey, this this lets you use any amount of r
XJS on top of it. But yeah, I would say that this is
mnemonic and friendly for people to remember the modes and just have good pictures of
it, because these modes. This is what's amazing about what they came up
with our x When they came up with our XJS and I'm going to go
rewind a little bit in history up sharing though. So in two thousand and
four, Gmail came out and ajax started to get used, like in seriousness.
And as AJAX was getting used between two thousand and four and twenty eleven,
call back help was like really forming. And you know when you attach
an event listener to something, if that event listener starts some ASYNC process and
then that event comes in again, you know, you don't have concurrency control.
So seven years after like ajax appeared, Microsoft Labs our research and development
went down and said we got to solve this ACYNC problem and we got to
solve it for good and hit all of the use cases. And this is
four years before promises, and they came up with the Reactive x you know
project, which you know became our XJS and all the implementations in all the
languages. So they had you know, PhD computer science people and everything really
looking at this async problem and saying like, what are all the tools we
need to solve every use case in async? And they built it. But
by two fift by twenty twelve, the A plus team was working on promises
and promises were gaining traction. I think partly they were beating winning the race
because the documentation for our XJS was just really problematic. They you know,
like the documentation for gosh, for merge map, it's it's obtuse. It
projects inner observables into the output observable, and it's just it's just not descriptive
enough. So promises from twenty eleven to twenty fifteen were gaining mind share and
they were an improvement over just regular function, but they didn't get all the
way to RxJS. And then promises were adopted. But promises can't control concurrency
in all the ways that ox js can. And so those concurrency operators that
are so hard to remember but described in those cards that I showed, those
things are amazing because they solved for all async combinations and I can I can
describe this in real life too. It isn't just RxJS. They didn't just
solve like for web development. It's like extrapolatable. It can be extrapolated to
real life. So I gave the analogy on the React show. Suppose I
am making a sandwich, or my daughter she wants a grilled cheese sandwich.
I'm on the stove. I'm busy. I've been requested to make a sandwich.
I'm busy making the sandwich, and she says, Dad, I want
chicken nuggets instead. Well, these five concurrency modes well for them, or
in r x JAS, I added the fifth one. These five concurrency modes
describe what I can respond with. Right, I can merge MAP, So,
in other words, I can just start a new pan cooking the chicken
nuggets next to the grilled cheese. I can say, okay, Sierra,
but only after I make the grilled cheese. I'll get started on the chicken
nuggets. That's cancat MAP. I can say, oh, you want chicken
nuggets, Well, I better stop making the grilled cheese. I'll make you
chicken nuggets instead. And I can also say no, Sierra, I'm already
making your grilled cheese. I'm not going to start chicken nuggets. So that
happens to be exhaust MAP. Finally, the final one, which I just
came up with by looking at what are all the possibilities. The final one
is I'm making the grilled cheese. Sierra says, can I have chicken nuggets?
I just turn off the stove for the grilled cheese, and I say,
I can't deal with all these requests. Just make your own lunch,
so I can walk away from that. These are universal, right, and
so it's really cool that RxJS has all of the universal possibilities embedded in it.
It's not cool that everyone isn't using it. And I think the reason
is because the documentation isn't friendly enough. And so instead of trying to improve
the documentation and doing you know that kind of long but noble process of trying
to contribute back to an open source repository, you use. But I just
think, well, it's time for a higher level of abstraction. And I
don't think I'm on the wrong track because, like I ask for comparisons,
I say, how would you do this the RXGS way? And it's fifteen
to twenty confusing lines with you know, seven levels of nesting versus you know,
one or two levels nesting and like five lines. So I want to
stick with this approach of creating a rapper library and hopefully you know, hey,
if any of this ends up back in r x j S, if
it ends up in react, you know, I don't care, Like I'm
not I'm not saying everybody has to use this exactly this way, but I
am saying I think there is an abstraction just waiting to be uh, you
know, birthed into the community. This truly has been an evening of interesting
analogies. Thanks for thanks for explaining me the difference between I find that I
found it all Libray really fascinating and be surprised I haven't heard about it before.
I will. I will research it, you know, if it's okay,
if I PINU you with questions from this time. Yeah, you know,
the best place to engage with me right now is uh is through the
GitHub repo. Stars are welcome discussions and issues also, and uh you know,
that's that's where we can talk about the repo. If we want to
talk a little more generally about stuff, I'm on Twitter at slash x at
Dean dev Dad and that'll go in the show notes. And yeah, I
mean I would love to to engage on this more. Like I said,
I have my workplace where I've gotten now three teams you know, using this
as you know, a starting point, and so that's probably where you know,
more of my time gets spent in the workplace than marketing it. But
since I've reconnected with this awesome top end dev's team and and all the shows
that they run. I was like, well, sure, I'd love to
talk about it more widely. That's awesome. Yeah, and for anyone who's
listening to this and once to try out our ax effects and other frameworks,
we do have an entire episode about how this can be used and React,
so if you're interested, you can check out the latest episode we did on
React Round Up, where we also talk to Dean about how we can use
our ex effects to simplify some of the issues that React developers generally run into.
So yeah, this again, this has been great again because the React
episode was also awesome. I really love the the analogis to your daughter,
and it just it makes it so much easier to remember what exhaust map means
because now I can just remember being exhausted, like I'm so thanks, thanks
again, man. I hope you come back even even more times whenever possible.
So let's do a quick round of promos before wrapping things up. So
you're mentioning your Twitter, the GitHub repository for the project. Is there anything
else you would like to promote? Just that? Just that? Okay,
okay, awesome. So yeah, just reiterating anyone who's listening to this,
if you can't stop what you're doing for just ten seconds, then go into
the GitHub repository and give it a star that could create a chain reaction that
is going to lead to eventually us having better names to our rx jazz operator.
So please do that for the entire community and future generations. Well,
I should mention there is a thread a discussion in the RxJS repo that opened
up recently where they're seeking to do some renaming in RxJS eight. So you
can find that Ben Lesh's profile on Twitter, and so if you have opinions
about it, like I do, you can you can contribute in their discussion
directly. I'm sure they'd appreciate the community and put awesome Rman. I'm gonna
give this to you in a second. I know that you have a special
announcement, so I'm going to leave you to the end. Mine is just
going to be the regular episode interest. So if you're interested in outsourcing your
software or design teams, or even better, extending your design and software development
teams, you should definitely check out Onvoid dot com is U n v o
I D dot com and yeah, that's basically gonna be my promo. So
arman, please take away. I know you have a huge announcement. Well
it's not that huge. The huge announcement like a month ago, as I
mentioned on the previous episodes and also on Twitter and LinkedIn and all the other
places I visit. I don't know. I wrote a book on Angular.
It's called Modern Angular. It's with the many publications. It's in early access
now. So out of the ten total chapters, we have now five out.
I think two other chapters will drop like in a week or two,
I guess. But the entire manuscript is finished, so no worries if you
think I'm not going to finish it. I finished it. I'm just doing
some polishing and listening to early access leaders comments. And by the way,
the fifth chapter the last month, that is right now available is about our
issues. So yeah, if this episode got you interested, maybe you can
also take a look at that chapter. The book discusses all the new features
that we have. By the way, the sixth and seventh chapter that we
drop soon are all about signals, which is the idea hottest topic right now.
And for this episode, I actually got a special promo code from Manning
Publications, so you can use the promo code pod Angler twenty four. Let's
also put that in the description to get forty five percent of any Manning product.
I hope you spent it on my book, but yeah so, and
also yeah, thanks to many Publications for giving me that promo code specifically for
our episodes. So if anyone of the listeners is interesting, take a look
at the description. I will. Let's also put the link to the book
there. So yeah, that's it. That's my promotion. Gonna be the
same for a while. Yeah, Aaran, can you send it on the
internal chat so that I can put it in the comments section for anyone in
the livestream. Yeah, forty five percent discount? Is that what you said?
Yep, ye, that's a huge, huge discount, so awesome,
awesome, thanks Man. And I think the fact that you have two chapters
about signals in angular is really interesting because it's uncharted territory, right like in
terms of conventions and things like that. So I think this is the kind
of thing that is relevant even for those that are already experienced, like you
might be thinking, I don't need Arman's book, like I'm already experienced in
Angler, there's no need for that. And even Signals. Yeah, like
I'm comfortable with Signals. I know that they were released with whatever, but
I'm pretty sure there's something that you can learn from those two chapters specific to
Signals. So I would still highly recommend buying Arman's book, even if you
feel extremely comfortable with Angler already. So yeah, coupon is in the show
notes. Again, it's pod pod Angular twenty four altogether, no spaces,
no dashes. All right, thanks thanks Man for having coo cool book.
Just check it out. Thank you. All right, So, guys,
thank you so much. Also putting the link to Arman's book in the comment
section, so you have the coupon and the book link. There no reason
to not not buy it. But yeah, again, guys, thank you
so much. Dean. Thanks for being on the show, for not just
all the time that you spent in here, but also the effort to build
this amazing library that is available for everyone in open source. So that's really
that's really a major effort. Thank you for that. And yeah, at
least that's it for me. Yeah, thanks everyone. You're in the next
one here in the next year.