Hello, everyone, Welcome to Adventures and Angler, the podcast where you keep
you updated on all things Anglar related. This show is produced by two companies,
Top Anddves and Onvoid. Top and Doves is where we create Top and
Doves to get top and pay and recognition while working on interesting problems and making
meaningful community contributions. And Onvoid, which provides remote design and software development services
on a performance basis, so clients only pay when tasks are delivered and approved.
In today's episode, we will talk about NNGRX version seventeen, which,
by the way, introduces a fully signal based store. My name is Lucas
Paganini. I'm the founder of Onvoid and your host in a podcast, and
joining me in today's episode is Arman Vardanian. Hey everyone, Subrette, Hello,
All right, let's get to it. So Aarman, I understand that
you read a lot about this new version of engr X seventeen, so let's
just start with a brief introduction of what's new. So what are the most
relevant changes in this new version of enngurr X. I didn't only read a
lot about this, I also wrote a lot. I wrote a small application.
Actually, I made a Twitter thread on this, I want to just
you know, cope, paste the link here. Okay, let's put it
in the comments, because it has all the source code on which I've tried
out. So what I did was I used the new Signal Store to build
a well, you know, to do least application. I find it,
you know, remarkably easy to you know, get yourself familiar with in ste
up by building such a sort of application because it sort of has everything that
we needed. It has you know, lists of data, it has htpicles,
it has modifications and so on. So yeah, I'm pretty impressed.
This is a really big step. In NNGRXB sixteen, the NJRX team introduced
signals overall, so you could not only just select data from the store as
observable, but you had the select method. It's always returned the observable of
whatever data you are selecting. You could also now select the data as signals.
There's a select signal method, So in the end of the day,
even if you don't like the Signal Store, but you want to have signals,
you can continue using NJRX store the conventional store which select signals. So
that was already there. It is now I guess stable so feel free to
use it in your applications if you want to have JRX and signals. But
of course, the big big thing that we now have is a fully signal
based store. It's functional, it's extensible, and it is relatively easier to
adopt than say n JRX store like the conventional store, because there you had
the reduct pattern, right, you need to learn some consopt selectors and reducers.
Obviously, if you are an Angular developer who knows signals but it's not
familiar with reducts or flux or whatever, adopting njr X signals will be way
easier for you and brings almost all the benefits that you have with NJRX store.
Okay, So how it works is that you can create lots of stores.
They can be decoupled from each other, or you can couple them.
You can provide them on any level of your application that you want. You
can have a I don't know, root level store for global stuff and component
level store for whatever this one particular component is doing. Okay, so how
you do it? There's a function called create store. Now create signal store.
I'm not sure this doesn't really matter, so and it can receive a
bunch of modifications. So if you just create a signal store and pass it
the wid state function so that you can give it an initial state, and
you could be down with that. You now have a signal based you know
store okay that only has this data. It automatically creates selectors to select the
data that you have there, okay, and you provide the data as a
plain object. But now you have signals of all that stuff, right,
which is you know, kind of cool little thing. You don't have to
write signal this, signal that all the time. But now you have a
store that has data that you can select as signals. Essentially, you would
just do I don't know my to do store, do all to do for
example, and you'll get the array of the signals. Then you can add
computed properties derived from you know, your state, and you will just you're
just going to be using the computed function. So it's fairly easy. It
gets a call back in the callback. You have an object that has all
your state. Now whichever signals from the state you use, it will be
a computed signal created from those pieces of state where you can create computed properties
there. For instance, in my in the example that I provided in the
Twitter thread, I use the query to search among the in the to do
list. So I have the list of all to dos. I have a
query which is an empty stream, I default and user tapes something. I
have a computed property that you know, selects all need to do that are
relevant to whatever the user has searched, and I do with computed signals.
And it's the same way in the end of the day, in the in
the component where you're using the store, you just get that value as a
signal. You don't really care how it works, and you cannot. Of
course, you cannot rewrite those signals. You cannot set those signals directly,
which was the bitchtick With, for example, a conventional store, you could
only use actions right reducers to change the state. You couldn't like say,
oh, I want this property to be something. You had to create an
action you have to create reduce it more or less. The same is going
on here. The third extension that you could do to your story is ad
methods. There's a with method function and you can give it an object of
methods that you can then call in order to you know, change your state
and if you want to change the state, you have to use a special
function called patch state, which is essentially a small small reducer to which you
can give the piece of the state you want to change and the new sort
of new value or the callback to use the previous value and so on,
liking reducts, but a bit shorter. You just call it a patch state.
If this method is called patch state, set this new whatever item.
You can provide arguments and so on. And the cool thing is that you
can also provide like RIX methods. That's literally a function called rix method,
and inside that RICS method function you can define some synchronous task like or for
this state modification. What I want to do is, you know, make
decision to be called get the response, change this I don't know property on
the store depending on the response and so on. So yeah, these are
kind of like the basics. Right, So you can create state, you
can create computed states, and you can create methods and also our methods.
Ok So that's the whole idea, and all of all of that stuff lives
in one place. Okay, just create one store here. It works.
Okay, I think pretty pretty nice. So one thing coming to my question
to my mind, like I think. Suppose someone is already doing a gr
X a lot and now they have on effects, wratting effects, writing actions
and all. I think, although this is also going to work with older
facts and accents. So suppose I think ad in the in the thread thread
asually you have Soon the WI method will will execute whenever there will way any
state change, right. Uh? No, The methods are the stuff that
you call when you want to change the state the computed properties will you know,
re executive there dependent track signals changed. Methods are for you know,
like actions were in the store. Okay, okay, so no, no
my question. I suppose, for example, I I want to make a
stra typical to the server, and for that I create actions. Action calls
the effectually called the bra uh the setuotypical get the data, then we call
the reducer, then pat the states. So can you just explain a bit
like how this thing will work on these scenarios. Sure, that's what the
rigs method is for here. As you notice, I didn't say anything about
actions because you do not have actions in the signal store. Uh. And
this is actually great for me. I like and reg store. I actually
didn't like component store. If anyone has worked with component store. I mean
it's nice, but I didn't like it didn't have actions, it was not
events driven. So for example, with one action I could make a decision,
three I could make something. I could say, all this action triggers
these lots of stuff and so on, which, to an extent, I
still can get with methods. But methods are to me like a bit more
imperative. Like instead of saying what would I do with the JRX stories,
I would say, you know, for example, this component has loaded dispatch
events action that this component is loaded and I don't care who handles it.
However, and in the store, I would say, oh, if this
component is loaded, this is an effect I need to fetche these days,
and that in this case, I have to be a bit more imperative.
I need to write a function that says I don't know a load data for
this component. For example, it's a function that I'm gonna call okay,
and it will It is going to belong only in one store. So if
I want to search data in two different stores, I need to call two
different two different methods. Again, of course, what I can do is
create just one signal or a big signal store and have different methods imported and
just converge in one place into one store. I could do that. That's
also an approach. Not not bad, not a big fan myself, but
you could do that, or you would have to call several methods, which
I don't like. So your question about effects, why I'm saying all of
this stuff, is that effects now don't exist as effects that were in NJRX
store. An NJRX store effect was just separate entity, just separate thing that
could like a reducer react to actions and work with observables. Right, It
was like a reducer for observable sort of thing. Here, we don't really
have it, but what we have is rix method. So instead, so
for usual methods, for example, if we look a look at my example.
For instance, here I have a mark as completed method. This is
a conventional method that just takes an idea of a to do item, finds
it, changed it to completely true right, and patches it back on the
state. So it is a simple synchronous method. But I also have a
load to do this method. Load to do this now here is doing urge
stuff. It's doing a synchronous stuff. It loads data and what it does
it used this function called RICS method. And this is a really cool function
because the RICS method essentially creates a function itself, is a higher order function
that works asynchronously, and its argument is the whatever observable you want it to
execute. Okay. So the cool thing here is that you no longer need
to do like switch mad like what you do would do with the endoric effects.
It would say actions type I don't know off type. Let's say load
to do items which map or marriage map, and then I would say go
to do service blah blah blah, load and so on and in the end
map to another action, which LOKs fine for me. It's not bad.
Where ARIS method is actually simpler. You could just use the pipe function,
not the pipe operator. There is a pipe function in the RGS package,
not RGS slush operators, just RHS and the pipe function. What it does
it creates a higher order observable if you pass operators to it. So essentially
what you say is just execute this operator, and inside I would say,
okay, switch map to this HTP call or whatever. And they also actually
added, well, this one existed previously. It is a custom RGS operators
from jr X called type response so you don't need to subscribe or map to
an action. You could do type response and inside you can provide callbacks for
error completion right, and a finalized callback which would work when regardless when it
is done, regardless of whether there's been an error or not. Okay,
So in my example, what it does is that the next call back it
catches the state with the to doos from the back end. The to do
least error does a console error or whatever. However we want to handle the
error and finalize turns the loading bully into false because we either completed the call
successfully or there was an error, so we no longer need to display a
spinner or whatever. So Rix's method is essentially what replaces effects. We no
longer really have effects here. We have methods that do acing stuff with observables,
but in the end of the day they still you know, have to
push it to the signal store via patch state. So yeah, that's about
it. Our arg method is the replacement for effects here. That's the bottom
line. Yeah, So here I want more questions like so this with with
methods will be figgered on instances of the store, or how will you tiger
to supple the in your example load to do How will you tigre that?
Yeah, that's a good question. Either I call it on the instance of
the store, So what would I do. Let's say I made the to
do store and now I have a to do this component. Okay, I
can provide the store on the to do component or wherever I could provide it
in the root. I can provide it in some pots or whatever. Now
I inject the store, I have the resonance of the store. The store
now has all the properties that I define as signals, so I can say
to do store dot let's say loading and show spinner or not in the tumplate.
And it also can pains the methods that I define there. So for
example, I can write an engine on a nat method and there I can
call a load to doce and just select the signals and use the signals in
the template. But there are also cool things. There's also a function called
with hooks, so I can define two life cycle hooks for the store,
an on inat method and an on destroy method. And that's really cool because
now I don't even need to define a life cycle method in the component because
the store itself as well. If the to do story is initialized and the
todos are actually coming from the backhand. Why wait for the component? I
mean, there can be scenarios where I would want to wait for some properties.
But let's say the core element of this story is the to do.
The to doos will arrive from the back end anyway, so I can just
put that logic in the store itself and say with who function only need please
you know, load the to this list and touch state and whatever essentially.
Again, in my example, I also use that I define the only method
and just call the load to do reactive method that I defined in the with
methods function. And that's really cool because you have like different functions with callbacks,
but each function in its callback can use something that was defined in the
other callback because you always get the state as an argument to your callbacks there,
and you can just call the store sorry, you can just call are
the items on the store state properties, or you can call some methods to
execute stuff. So you have two scenaris. You are to call the method
there, which is useful when you are updating something. For example, in
the component, I have a button or checkbox rather next to each to the
item, and when I click on it. It just to do store dot
mark as completeed to do that idea as an argument. So yeah, that's
about it. You have to call it or you can use hooks to call
it prematurely or after the destruction of the state. Yeah, pretty cool.
Like this will reduce a lot of boilerplate. Absolutely, just right now,
from the top of my head, imagine having some data coming from web sockets.
So what you could essentially do on the initialization of your store you can
say, okay, establish a socket connection, and please every time that this
socket is emitting something, punch the state with whatever message it's sent. And
then in the undestroyed hook you could just say, okay, if you destroy
it, then let's disconnect the okay, okay. And now in the component
you have zero idea that this is a web focus or whatever in the company,
you'll just say, okay, I have some messages notifications. I'll just
slay them. That's it. Some other things that I saw that are posted
news in this version seventeen are that they are deprecating or actually they're not officially
deprecating, but they're putting it into maintenance mode, which is AnGR X data.
And I thought that was interesting because there's something that I've used extensively in
the past. So that was like, A I must say that I was
a bit afraid when I saw that. I was like, oh shit,
I'm gonna have to migrate a lot of what I have. And I wonder
if you because I haven't seen them suggesting a direct alternative to it, Like,
sure, they're migrating to a more signal based approach, but this wouldn't
really work for what jr x data was supposed to do, which is to
already provide you a default store created based on like basic crude operations to a
particular API. So that's that's gotta be our xgs because we're doing asynchronous work.
So I wonder what would be the recommended approach for that, like for
anyone wanting to create a facade between their their data stores and API resources for
example. That's a that's a good question, but I want to highlight something
before before I answer it. Uh, I alway isn't migrating anywhere. I
like both danger store and component store, and the signal store will continue to
be maintained, will continue to be updated. So if essentially the only thing
that we got here, like I wouldn't really connect putting JRX data into maintenance
with signals. I think this was a big thing that was coming all along,
and it stands from one thing that I'm not going to say something opinionated
and I want to make with This is just my opinion. I don't claim
to be completely right on this, but I don't think we really need facades
for NJRX. Of course, there's been lots of articles from lots of people
that I respect, and I think their opinion is very valid, But I,
you know, respectfully disagree for me, like you have facades, they
would create facades, they would write the selectors there, and in the component
they will inject the facade and so on. I don't agree that is necessary
because for me and JRX. For for example, if you takes most the
most basic things like danger x store, for me, it is already a
facade, uh for instance, it acts as a facot with the fact that
it has effects that are essentially the couples from your components flow like you don't
call effects directly in your in your components. Essentially, you have a facade
called the store and actually just gives you two methods. You select the data
and you dispatch actions, and when you dispatch an action, you really have
no idea from the component perspective which selected properties would change. Okay, you
dispatch an action, which is essentially just an event if you're doing it correctly.
Lots of people would do like imperative actions, like we would say load
data, load these blah blah blah. In reality, what you need to
do is you need to to create events like your component loaded. Okay,
you dispatch an action that says, I don't know, use a our component
loading. That's it. That's what you tell all the world. You say,
I'm a component, I'm here, I was loaded, please whatever.
I also need these data. I select this data, and I just patched
this action, so it is already a facade. Angel X data for me
is sort of a facade of a facade. It's useful, I mean I
don't I completely agree that it's useful in the context of like I don't have
to single handedly write out every single crude operation method. That's an understandable thing,
no disagreement there. But in most enterprise applications this is like twenty twenty
five percent of the work. You would still need to define lots of lots
of methods, and in the end of the day, you have to keep
track of your services that work with the you know, the data, right.
Make sure your API is a bit you know works in the world it
is intended. Like imagine having an API that uses a post request to get
some data. I mean that's not unheard of, right. You could have
a very big query and it just doesn't fit as a querry parameter, so
you have to send the body and you need a post request. So those
sorts of problems can come up right with Enjeric's data, and then Garry's data
only solves like twenty percent of the problems, and it was like not really
a problem, but more like boilerplate code. That code still exists, right,
you still wipe out your services. You just sort of make them connected
to the store, and you don't directly access a store. Would rather use
the you know, the facade of the facade, right that you have with
njered data. So it's not usefully it's obviously it's a bad thing, but
it just doesn't I guess warrant like it's too big of a contract, Okay,
And that is what now you're experiencing the right looks like you think,
oh, I have to, you know, refactor this because I have sort
of married my state into these services via Jerry Data, right, and now,
well they're deprecating it at least I think in the forcible future. I
don't think it will be deprecated in version eighty. Okay. They could,
however, deprecate it in twenty for instance. I couldn't say much about it,
but still it would be well ahead of time, so there is time
to refectory. I think it would be relatively is it to refectory to a
conventional store, right? Or you could rewrite it into facades, like write
out the facades yourself so they don't you know you have a facade with the
same method, and then you can start removing the facades one one by one
and you just remove enjoyic data and then you will deal with your facade later.
For there is a strategy, I guess. I don't think it is
that simple because, for example, there's one particular thing that njr x data
handles which is really hard to do manually, like really hard, which is
the error handling. For example, you can have a method in your in
your facade exposed using jr x data. That would be like create one for
example, and this is going to return a promise, And what you can
do is make it so that if the request to the back end fails,
that promise rejects and if you works, the promise resolves with the data.
But it not just results with the data, but it also updates the cash
that you have, so everything that is listening to that cash also updates.
Doing this error trow is much harder without j X data because if you have
like a normal store and you just want to like you want to emit the
error to as an event so that whoever's listening to the error event can answer
to it, but you also want to just strow the error in the method.
That is way harder than it looks. And j REX also does a
lot of internal ID creation to connect the error to the event that trigger it,
and that's kind of hard to do on your own. Yeah, idea
that of course, it's a concern. I think the main contributor to data
being put into maintenance models well like a popularity. Obviously, not a lot
of people are using I don't never used that. I tried it out once
in a pet project and that was about it. Another significant blow to enjeric
data was the introduction of feature stores. Right, so you could combine.
You could bring reducer and you could bring it will automatically generate the selectors,
and now you also create action group. So essentially what it does it says,
you know this, this package provides more freedom, So just enjerk store.
Let's just enhance it. So the real boiler plate stuff like selectors that
just select some property, like you don't need to be a genius, you
know, do that. That store can handle it automatically. Or if you
want to create those of actions that are connected with each other, okay,
here create action groups. You can create lots of actions. And what is
happening now it says, okay, that package was useful, but we're not
going to maintain it because one problem it has it has nowhere else to grow,
Like it cannot you know, predict what other custom methods you want to
have. Right, So now what you can do is if you are let's
say error handling, like you have this approach, right, what you could
do with functional approaches right that we have in the jars. What you could
do is you could have a higher order function that just does that for instance,
you have top response now, right, you can just rap it inside
another function. Your custom top response as will always do the same error handling.
But you could also, let's say, provide an optional argument of another
collback that you want in one specific case with our handling. Okay, so
you can write like five lines of call to fully customize that function. And
the same goes for actions. You have action group. Now you can also
like actions themselves are just functions. When we call create action does to create
an action. What it does creates an action creator which we then need to
call to get the actual action object. Right, what you can do you
can rap that function. We did this approach for example with NJRX store,
but you could do the same with Signal store with phone store. What we
did we create a higher order function. It was called for example specifically for
HTP. It would create free HTP actions. It was called create actions.
It would take a response request model, response model, what we are sending
to the server, what we're expecting from the server, and it would give
us free actions in a topple. Now, the error and success functions actions
had their specific metadata on this object, but I didn't need to define that
metadata. So for example, errors always had something like successfuls on it,
and in the effects, what I would do. I would first get all
actions, I would filter out the ones that are related to HTP with the
metadata I put in the action okay. Then I would perform I would see
if okay, this is an error. In case of error, I would
call some error handler service to handle that error okay, And if it was
success, I would display a message or whatever and so on. So those
are just two effects global effects that worked always. So I never actually wrote
a single line of duplicate error handling code. Instead, I would just would
say catch error return observable of this error action that was automatically created for me.
I didn't need to define anything. Obviously, this is several lines of
code more than not writing any code, but I guess it's less obscure,
like what codes on there. Like the function that creates three error actions is
fairly simple to explain. You could comment it, you could document it,
and then you can document two effects that are handling success in error cases,
and essentially that's it. That's what like about event driven component sorry state management,
which we have with NGR extore, which I like. I like that
I can say Okay, I want to do something on all HTP calls.
Okay, sort of like an interceptor. Now I would have to do an
interceptor. But what if I want to do something on all errors, Like
I don't care every error. I want a red notification message somewhere on the
screen. Okay. I probably I would do some other or handling for some
specific cases, but I always want the red thing that's something done wrong.
Sorry. I can do that easily with effects food, action driven, event
driven state. Managine, I can't do that with ajerics data. I can't
do that with with a signal store. I can't do that because it doesn't
have actions. But the cool thing. Sorry, I'm talking too long on
this question, but we just arrived to logically arrive to the other big thing.
When I say the signal store is extensible, means that you can write
your own functions and use the state and provide it to the signal store creator
function, meaning that actually, if you really want to, you can have
an event driven stuff. You could do a reducer driven stuff in a signal
store. You can do that by writing your own custom function. I have
seen people doing that. I haven't tried it out yet, but it is
possible, okay, because it is extensible and you can wrap pieces of state
into functions and using other stores. Okay, so with signal Store you can
do that. With Jerry's Data, I guess you still have to resort to
the manual stuff when it came to custom things. So the benefit was Again
I'm not trying to say it was a bad package. I didn't like it,
but it was more of the case like, Okay, it will work
if I have a table that is purely crude stuff. But in general,
this is really how world works. It's like fifteen twenty percent of cases,
but more complex cases, interconnected models and so on. That does make sense.
Still, I wish that, for example, all those utilities that you
said everyone's going to have to build, if the people that are built NJRX
data could do that, that would be way better. Of course, but
again I understand that open source community, we can't really just put that pressure
into the maintainers. But it really would be amazing because this migration can be
really frustrating, and not every company is going to have professionals that will be
able to build all those utilities that INJRX data used to provide. Yeah,
I understand like NGRX itself never said they would continue the development of NJRX data.
It was always a project created by other members of the community, not
the official creator and supporter of NJRX. So yeah, that's a good point,
although it was never something that was advertised, so enterprise companies making the
decision to use jr xdata didn't know that the support and continuation of that package
would be different from the rest of the NJRX or packages. You know.
It's kind of like when you put something in the at angler scope, you
expect it to be supported just like every other package in the Angler scope.
So that's the expectation. If you were like an at NJRX dash community,
then okay, you kind of already understand that we're talking about different maintainers.
But it was in the NJRX scope, you know. So that was like
a huge blow to me, and I'm pretty sure that it would be hard
to explain to two clients like that. It was a good decision in hindsight,
I see some developers maybe having some tough conversations with their managers when the
managers realized that the package is going to be discontinued. But yeah, another
thing that I think would be interesting for us to talk about is component store.
Like there is no direct replacement for component store, but at the same
time, like the signal based store can very easily be used to serve the
purposes that the component store was serving. But it is interesting that, like
it's a general purpose store, but also it can be used for the specific
case of just being a component store, whereas in the past we had a
specific solution for local component data, which the component store. So I think
that that was an interesting movement too. It simplifies things because you don't have
to learn the component store and the general store, just learn a regular JRX
stores and then you can apply that in any case you want. But yeah,
it would be cool to see it being applied to just local component data,
just so that people understand how they could use that for newer components that
they're building, and also if they're just going to migrate components that we're using
component store to it, how that would be done. So you guys have
anything to say about this component store thing, well, component store is not
new at all. It's not going to be replaced definitely. I think what
the ngoids does now are right now is they sort of cover the entire market
of ideas. You want the centralized, centralized, event driven state, okay,
use an erroric store. You want class based store with the you know
you want class based store with observables, Okay, you can use a component
store and will be decentralized. Essentially. The store thing can also be decentralized
because you can feature state, laser load feature stores. Right, it's just
one unified store under the hood. In these other cases you have different store
that can work with each other with dependency injection. Right. If you want
fully functional stuff, you can go with signals. You can go with signal
store. The cool fact actually, uh and I saw it in another suite,
I think by Marco from the Jurics team. I saw so that you
actually when you call signal store, it creates a class under the hood because
it's an injectable and you can actually write your signal stores as classes. You
can extend a class from You could say with store with this state, your
class extends this and now you just write conventional methods in your class and hooks
and so on. And it's pretty cool. Actually, if you don't like
this fully functional, nested colvectional but stuff you can just extend the basis of
your store into a class, and then in a class you can write whatever
methods, rix methods and so on and so on and actually really cool,
So you have essentially four approaches. You can do red ducts based event driven,
you can do component based or driven. You can do functional signal driven,
and you can do class based signal driven. And if you are really
keen about it, if you have the time for that, you can actually
do events driven with signals, either by using a select signal on the conventional
store or fully you know, extending the signal store with reduced the res actions
and all. You can do that. It is extensible. So what I
think the movement here is more towards like diversity. You have every need you
have, like you are developing a small application. Okay, you don't really
need a full blown store, selectors features, blah blah blah. You know
signals. You are not very good at direct jests, you don't care about
our jests, and you don't really have many methods talking to pay hand.
Sure, just drop a signal store, a couple or two. They can
work together. You can inject one signal store into another. So essentially still
have one big store if you want to. Okay, if you need something
wrong, those story just injected it and you are up to your work.
You don't need to know a bunch of stuff, care about a bunch of
think about scalability and the fact that you are using these stores. You can
always scale up to JRX store. You can create one centralized store afterwards when
your application grows. And then you could say, ah, okay, I
would just switch these injected stores in my components to the conventional store use like
signal. That's it. You're still getting the same data under the hood from
the component perspective. Nothing has changed. That's the cool thing. You can
have this diverse approaches, pick one which you want, and I guess entiic
data just didn't fit into any one of them. Yeah, I think the
one thing came to your mind that this will also go going to help in
a lot of micafent and development, like past put it to put the put
your signal stores. And then once you finalize and or you have now multiple
macro content and you want to maintain one store for your application, and then
like Karvan you said, you can go with the biggest stored approach and then
microstore approach. I think this also be possible have multiple store with signal store,
like the store will not be related to each other, and you can
you can just share the store in between in between your components. It entirely
like depends on how you provide your story. If you create a story and
provided the route your entre application has, of course you can reduplicate. I
don't think that's a good approach. But again, you could reduplicate the global
store by providing the store in the component. No one really does that,
but theoretically you could. I think it's cool that you can just you know,
say, like what I see myself possibly doing is having an event driven
and JRX store for all the stuff, and then each component has its own
store, its own facade if you will. But it's a signal store that
just injects the big store, takes all it needs from it takes all the
component data change stuff, injects it back into the component. Another component just
has to you know, work with all these things. It's way easier on
the unit testing stuff and the thread that I post also this some unit testing.
It's very very easy to unit test a and JERIC signal store. So
having this sort of interconnection with the big store and small store could work well
in terms of union testing. Right yeah, So yeah, you can have
multiple story or you can just have a big root signal store and a small
local component store, and you can then choose how you work with it.
I would prefer to combine them into one at the component level and then just
use one store and say, I don't know, use a profile component under
the hood that actually uses all these other stores. But I don't know it,
I don't care about it. I just use whatever data I need for
this component, right, and I unit test whatever need I need for this
component. And it's easier to mock. Also, right, you don't need
to mock this entire store. You can mock this small one that only uses
two things from this store, and so on. You can both combined,
recombine and so on. Yeah. Yeah. The segregation of responsor the good
here and the components become super simple in this case. Again, in the
thread and the example component, typescript has literally one line of code. It
just injected store uses it all in the template. It's just a no brainer
to see how it is both good for the readability of the component for the
like all your component logic is its expressed in Every component is expressed uh in
the same pattern by using the signal store approach, so your components kind of
become more uniform. You can adopt this like an approach. Oh, my
components just need to use a signal store for its state every time. It's
a bit more code, but we now know all the components you know,
conform to this. We can easily see that and something again, you can
just use you know, component class based story class based signal store, which
is also I like that. Like overall, I think it was a really
positive addition to and your X. I really like the movement of going signal
based. I think that's definitely going to It's already gonna simplify things for us
that are like ah old Angular developers, but it's going to be even easier
for newcomers into the framework. So I really like, I really like this
movement. And yeah, I actually don't think I have anything else to aggregate
to this discussion. I think we can start wrapping up. The last thing
that I'd like to say is how much I like the functional approach that those
libraries are going for. It's not just syntax. It makes it so much
easier to really reuse parts of the library because you don't have to like create
a base store and then extend it. You know, if you have parts
of it that that you want to reuse in other stores, even if like
you have methods that you want to reuse in other stores, you can just
create a function that returns those those methods and then you call that function during
the store creation, you know, kind of like with custom methods x whatever,
and it's going to give you those methods. So I like how this
is going. I think it's much much much easier to create reusable code.
And yeah, I think developers just need to be cautious not to introduce dependencies
that should not be present. You know. It's that saying copy and paste
is better than the wronger abstraction, So you don't want to create wrong dependencies
among your code base. But other than that, if you have a particular
piece of code that you're repeating among all your stores, then you can just
isolate that into functions and reuse that during the creation of all these stores instead
of isolating in a base class and having to extend it. So I really
like how this is going. Yeah, I think that's mostly for me.
So if you guys don't have it anything else to add that, I think
we can go to one very very very small thing. Just if you're working
with rix method, make sure that all the operators and all the stuff you
import you import from RHGS not RHGS slash operators. It won't work and you
won't know why because there you are not inside and observable. You are actually
creating an observable using the pipe function not the pipe method. Was a very
big pain point for me just doing these small applications like why is this not
working? Literally? What I what is in the you know, official blog
post example? Why is it not working? Oh wait, maybe I need
to use the map function rather than a map operator that goes into the pipe
method of some observable. So yeah, be careful with that, because I
think it's customary for us to import that stop from RGS slash operators. But
those are different. Those are functions intended as higher order functions for existing observables
rather than just functions that we turn observables themselves. Yeah. I think if
someone left before this and that doing the court and hit my day is doing
again. Come to the episode and see after fifty fifteen minutes to give you
the solution. Okay, let's let's get to your promos then, So mine's
going to be quick, just the default. I'm going to promote onvoids,
so it's you and vo i d dot com uh, and we provide remote
software and design services on a performance basis, so clients only pay after the
tests are delivered and approved, which removes every risk that you may have by
hiring an outsourcing agency. Also, Unvoid engineers and designers working US time zones,
so you also don't have communication issues of like trying to talk to your
development team and having to do that at midnight because to then that would be
like ten am or something like that. So these are the kind of things
that Onvoid has solved for you while still having an interesting price point. So
if you're interested in either outsourcing your project or augmenting your staff, be sure
to check out unavoid dot com and contact us if you're interested in that.
So, yeah, this is gonna be my promo for today, Arman.
How about you I show if finally enough the publication just dropped something for me
to promote today, So the last one, I you know, notify our
listeners that I have a book in early access about modern Angular. Certainly not
ANGI X, but modern Angular. My new book is all about the recent
latest school features that we have in Angular. So it is an early access.
The last week three chapters were published and today two more arrived. And
actually one of the chapters is kind of touching on the points that we're discussing
today. So one chapter is about the different you know, small cool things
that we have like host directives and the optimized the image you know, input
transformations, required inputs, that sort of stuff. And the fifth chapter that
brow today is about our xges urges into road package custom operators that we can
do, how we combine it with the inject functions and so on. Oh
yeah, let me also put the link to the book. It's an early
access meaning meaning you can buy it with a discount, you can try it
out. Oh well, the website is down, but whatever I will put
I will put the link here, hopefully to results soon enough. So yeah,
if you if you choose to read the book, hopefully you enjoy it
and it is useful to it. Feel free to comment on the live forum
about the book. It's still a bit of a work in progress or polishing
it out, so and yeah, more content to drop soon, all right.
Yeah, feel free to send that any lengths that you you'd like people
to see in the comments section, because that's going to be sent to everyone
that is in that's watching the live stream. All right. I'm just mentioning
that because you said in the chat that is private to just this. All
right, how about you service? Yeah, I think it's simple for me
as well. I would like to promote my YouTube channel. It's fun of
Heuristic, So please guys go ahead and past that, uh and let me
know what you want to see more like some people are seeing me do some
and react videos. Yeah, it depends on how many more goes there,
so please go and check fun of puristics. All right. Okay, I
think that's awful today for today, Thanks everyone, and I'll see you in
the next one.