Hey, Welcome to Adventures in Angler, the podcast where we keep you updated
on all things Angular related. This show is produced by two companies, Stop
and Devs and Onvoid. Top and Devs is where we create top and deves
so get top and pay and recognition while working on interesting problems and making meaningful
community contributions. An Onvoid which provides remote design and software development services on a
performance basis, so clients only pay when the tests are delivered and approved.
In today's episode, we will talk about migrating to the new Angular features.
That means all the tooling, all the new features, and the caveats of
how to migrate your current cod base to the latest version. Is it really
that hard or is it a smooth transition. My name is Lucas Baganini.
I'm the founder of Onvoid and you're hosting a podcast. Joining me in today's
episode is Charles Maxwood, Hey, everybody, and Armand Vardanian. Hello.
Everyone. That's too bad for another one, okay, so let's get into
it. Armen again, you are are experts on the subject. You have
been researching a lot about the new features on Anglar seventeen. So let's start
with the biggest concern that people have. Is it hard to migrate to Angler
seventeen or is it a smooth transition? Oh yeah, that's really the most
important question. And you know, I would be very happy to say that,
you know, it's sorts super easy, But I don't like creating Yeah
we're done. Oh no, I don't want to create illusions. Of course,
it's it's a hard one to crack. And there's a bunch of stuff.
Like it's not one thing that you can you know, just do overnight
or maybe you just cannot allocate like some fixed amount of time and say Okay,
I'm gonna upgrade and I'm gonna have all the latest features and so on,
because it involves a bunch of stuff. What I would definitely say from
the good parts is that the Angular Core team did their absolute best to provide
the best possible experience when transitioning to these new tools. We have a bunch
of schematics, we will talk about them. You can run and get lots
of things automated for us. There are a bunch of resources, there are
a bunch of approaches that one can adopt. And of course I know lots
of the personal frustrated now because you know, most of the Angular folks are
stuck around Angular twelve to fourteen, and even the guys who have like Angular
fifteen or sixteen, they actually have the latest version but are not using all
the latest features because those features also require a lot of manual work and a
lot of testing. So yeah, it's a step steep place to approach,
but with the tooling we have, and if you doube the right approaches,
it's definitely possible. So it's not that hard, but you still need to
be careful. So yeah, we're gonna talk about that, and let's talk
about in which versions it becomes hard. Because I recently upgraded many projects from
sixteen to seventeen and that was pretty easy. But again it was sixteen from
seventeen. It was just one version of date. But when would it really
be a problem if we're like on version ten twelve. Yeah, well,
upgrading itself isn't Usually the problem. Upgrading is the beginning of the problem.
Like, you can upgrade to version seventeen right now if you are not too
far behind. But if you upgrade to version seventeen, well you will have
all the stuff that has been improved under the hood, like better optimization,
if you have SSR, like you will have better support for SSR and so
on, but you would still need to change a bunch of code if you
want to adopt the new approaches to writing code. So if you use well,
one thing we need to address is that in Angular version sixteen, the
Angular Compretibility Compiler, the NGCC, has been removed, So upgrading from twelve
to seventeen could be even like impossible. If you're using dependencies that are not
supporting iv well, you shouldn't. You shouldn't really use those libraries because if
in version sixteen and seventeen they're not supporting IVY and they are like such dependencies
aren't properly maintained, so it would be best to avoid. But if a
project is already married to such a dependency, yeah, you're going to have
a real big problem upgrading to Angular sixteen and beyond. Let's say you don't
have that problem. Let's say it's okay, you can upgrade to Angular seventeen
from whatever version. There's a bunch of stuff going on. If you didn't
have standalone components, you would want to have stand alone components, and that
itself is like a very huge migration. You migrate your component code, you
migrate your configurations. You migrate like a bunch of stuff, and it entirely
depends on how your project was built. So then you would want, for
example, the image directive. If there in images, you'll be like,
oh, okay, sure, let's use the engine optimized director. But that
also involves a bunch of stuff. You need to configure something, you need
to import the directive, you need to put the directive. By the way,
the image directive has been backwarded to version thirteen, so if you are
on like twelve and you want it, you can go just to fourteen.
You don't need to upgrade to like version fifteen to get the image director.
And then there is the new control flow syntax. Well, it is not
stable yet. I mean you could skip that for now, but there are
all the tools available to do the transition right now, or even if you
like, if you do that in six months when it becomes stable eventually in
version eighteen, this discussion that we have now will still be relevant because maybe
some syntax thing will change, but the overall stuff will be the same,
and the overall upgrade and migration process will be the same, so it's not
a version problem. But of course the newer version you have the easier,
at least the initial staffs will be I mean, as you said, from
sixteen to seventeen, upgrade like should be payless. That makes sense. So
I'm just going to jump in and see if i can restate some of this.
So as far as backward compatibility goes, you can upgrade it and it'll
keep working. Right your your website's not going to crash, it's not going
to throw a bunch of ugly airs, it's not going to do anything you
don't expect. What we're talking about is, hey, there's a bunch of
great stuff in the newer versions that you probably want to take advantage of to
make your development faster, to make your app runs more smoothly, to you
know, to get better performance and things like that. Absolutely, yeah,
yeah, that's the case. So so you talked a little bit about some
of these things. It's like, well, you may want to upgrade,
like you said, you may want standalone components. So so what does that
process look like? Because I've I kind of dabble an angular and so I
don't actually know what that process looks like. Right. I may have written
some standalone components at some point. I may have written some old their components
at some point, and I've never had a push from one to the other.
Yeah, so standalone, Yeah, that's a good place to start because
it's an older change. We got standalone in version fourteen and in version fifteen
it is stable, so we had a lot of time to try to upgrade.
So the great thing about standalone is that fully interoperates with modules. So
what one can do is sort of do the migration iteratively, okay, like
incremental steps. You do one component, then you do another component. You
remove one engine module, then you remove another. Then at the end of
the day, just remove the root module. You configure using the functional API
is the new APIs, and then you are done. Of course that's a
manual approach, okay, which is reasonable, especially if you have like a
huge project. Then yeah, maybe you can change one thing another thing,
change the tests, and in the end they be sure that nothing broke.
Okay, but yeah, that takes a lot of time. For a project
that is like less risky. You can easily use the schematic that the Angular
team provides. So they give you this schematic which goes as far as I
remember, it was like engine generates at angular slash standalone something like that.
Well, the exact amount is irrelevant, but you have this command that you
can run on your project inside your say project route, and then full scam
through your files and find engine modules and fund components and make components stand alone.
And the beautiful thing about the schematic is that it actually works in free
steps, so you have to run it three times. First time, it
will mark your components as stand alone. So what it will do it will
go find all the component the creators and put standalone through there. And because
the component is now stand alone, it cannot be declared in an engine module,
but it can be imported into an engine module. And then it will
go to the engine model where it is declared and just remove the declaration and
put it inside the import statement. Okay, okay, And that way you
get the situation that, ah sure, now this component is using. It
imports the stuff itself, so it will add the inforce that this component is
using from the engine model and it will turn it into stand alone. So
now you have a bunch of standalone components, but your application architecture is engine
model based. Okay. The second time you run the command it will actually
go around and update the imports for those components that are now stand alone,
so now they only fully import not the module, but they import like other
standalone components from our project. And finally, you can run the command the
third time and will just because after these two commands, your engine modules are
essentially obsolete. You don't really need them because everything is declared around standalone.
And then you can just run the command the first time and will remove the
engine modules that are now useless okay, and will create the maints file and
the app convict tis file that we have now with new Angular projects, put
the dependencies there and so on. And yeah, you can put a flag
that will start using the standalone APIs. For example, if you're using router
module, it will remove it and put the provide router and so on.
It's not ideal, it's not ideal because sometimes it will miss something, especially
if you have like circular dependencies and so on. I will mention about that.
Also a good thing if you have a large project, you can actually
run this command in a subdirector, so instead of instantly moving your entire up,
you can for example, if you have a module based architecture, you
can pick one feature module I don't know, user's module. Okay, let's
convert this to standalone. Converted round the tests I don't know, check it
manually. If you think everything is good, you can move to another module,
and then so on and so on until you left with just root module,
which you can even move just manually. And there are also modules that
for example, they use for root and they dynamically provide something and not for
example, not every third party library that uses that structure has been fully migrated
to stand alone. So one option is to also use import providers from.
That was actually really important for the migration of many of the projects that we
had. So if you're using dynamic providers, I think that actually also works
with regular modules, right armen, Like if you just want to yeah,
so if you just want to migrate, like you don't want to really get
rid of the engine modules right now, but you want to at least migrate
the bootstrap file to use the new standalone bootstrap and to use the application can
figure isolated from the rest. You can do that by using this function called
import provisors from. So this function is important from Angular Core and it allows
you to pass all the modules as arguments to it, and then it's just
going to provide them as you were already doing with your regular app module in
the past. That's a really good catch. I actually kind of forgot about
the providers from function. Engine models are not gone, they're not deprecated.
There are no official plans on deprecating. I mean maybe eventually, we don't
know, but right now it's not on the road map. So the Angular
team is creed that Engie models are here. If you want to use standalone,
no problem. Inside Angular there's a bunch of stuff that is still engine
model based, form controls forms module, reactive forms module, they're still there.
You have to import the modules to be able to use by the way
I actually investigate it. And you know what's the reason behind that. Like
all the other stuff is stand alone now, right, you have Engie class,
engine switch blah blah blah. All that is stand alone. But the
you know, the engine module, sorry, the engine model, form control
and so on directives, they are not stand alone. And the thing is
that actually, like when you put engine model or you know, there's a
directive called engine model, right, but actually it's not just one directive.
It's actually a family of directives because engine model model for a radio button is
completely different from an engine model for let's say I don't know select HTML element
or usual input. So actually, under the hood they are multiple engine model
directives. One match is already about one matches for inputs and so on,
and if you want to use them, you need to import the entire thing,
so you are able to put engine model on whatever native HTML form elements
you want. That's why, for now and for the foreseeable future, dozen
engine modules will place there. I mean, I would bet that in the
future, engine models will be sort of marketed, not as like application backbone
or a way to create architecture, but rather a way to group related components,
maybe even standalone components, so that if you know that these things are
always used in conjunction, okay, you can group them in a module and
maybe import them altogether. I'm not sure about it. It's just speculation,
but you know, the way this is going, it is one possibility.
I think that that makes a ton of sense, like doing the standalone migration
first, and you're right, Like, the only reason why I haven't felt
that much of the pain to migrate was because I was already I had already
migrated those things before, so you're right. And one thing that didn't worked
out super well to me though, was the new control flow syntax and running
the migration on NX like it just it wasn't so straightforward to run the migration
using NX because I had to like the regular Engie command wouldn't work, so
I would have to use it through NX and pass some other parameters to it.
And then there was also like a two particular components that weren't properly migrated,
Like yes they were at first, but if I rented again it would
it would actually generate some issues because like I had stuff inside my engine switch,
and I can't have things inside Angie switch anymore. You can only have
things inside inside switch cases and the default case, but you can't just have
things lying around inside the switch block. So that was actually a problem that
I had with the migration. But other than that, which was something that
I was able to migrate manually, everything else was pretty straightforward. That's actually
an interesting point I thought about it, the having some content other than cases.
Although I have tried out the schematic on a let's say, usual project,
not with an X, it worked wonderfully for me. Actually it worked
only on the templates, which kind of makes sense because you know, if
you remove the imports that might possibly break something. But actually someone on Twitter
corrected me that there's actually flag that you can put and the command will also
just remove the imports for NGS switch and so on. What was interesting for
me, like one important point is that with the new syntax, the track
modifier is required for for loops. Right, so with the Engie four you
could skip like the track by function. You shouldn't, but most of the
people skip that anyway. With the new syntax, it requires that you put
the tracker, like in React when it requires to put the key when we're
mapping over an array, and the same now is true for Angular, which
is a good development. I welcome it, but it's a bit tricky with
the migration because when you do the migration, obviously lots of cases you will
not have a track by function, and what it will do it will put
like if you have let's say eng four lead item of items, it will
change it to four items of items and then track items. So essentially it's
just a USEFULS modifier because it only it tracks the exact reference to the object,
which could obviously change without meaning a change that must result in re render,
right, and that is okay in the sense that nothing will break.
Actually your app will continue working as usual. But you should probably jump on
the opportunity and provide something more meaningful to the track modifier, like maybe ide
or whatever you are using to differentiate between objects in a collection. Right,
Yeah, that's that's one point. And another point is that the switch switch
case syntax. Now the switch each case matching happens on strict equality. Okay,
actually engine switch works with loose equality. I don't know why. I'm
not sure, and I believe you could modify that with some injection token,
but that's like really obscure knowledge at this point. So if you change,
there is a small possibility if your code relied on loose equality for matching cases,
which again it shouldn't have probably, but you have such a case,
it's gonna be it probably will introduce a bug into your switch case. So
I would suggest I mean migrating if statements the engine. If directed, that's
just a piece of cake, like no problem. But with switch and four
loops you should probably be a bit more careful. But in general, it's
more of a mechanical thing. It's easier to do than a stund long migration.
I think ASTANDLE involves a bunch of interconnected stuff, and you know four
loop is a four loop, it's in one place. Actually, I noticed
that I tested it with different tricks to see how it would work the migration.
And actually, if you, for example, put an ANGI IF statement
on an engine container, the engine container is not like an element itself,
right, It's just a placeholder where you could put like, for example,
engine right. Uh, it will actually just remove the ang container. It
will just wrap the elements inside, wrap in the if statement and be done
with it. And that's really cool because with the ang if you you always
needed either a one current elements that will also everything inside, or you were
forced to use engine containers. Now you can just write an if statement and
the schemetic does that. It will remove engine container and put the IF in
itstead, so that that's really cool. I think I agree like just having
those automated migrations makes our lives so much easier, and it also makes it
so much easier to defend angler because there's always a friend that is gonna say,
oh, you're using Angler, they release a new version. Ha,
Like, you're gonna have a bad time because in the very reacts. So
now we can just say yeah, man, like we don't really have that
problem anymore. They're not gonna believe us anyways, because most of them don't
even try it. But but we know that we actually have a good excuse
to tell them, Hey, no, actually it's much easier to upgrade nowadays.
Yeah, I would say it's totally worth it. I imagine how many
new projects start with Angular and you have already all of these awesome features.
Oh, we're gonna do signals next? How to migrate to signals because there's
no schematic for that. That is a very good point, and I don't
think we're gonna have right just to make it clear to the audience, like
it's not something that is being done and you just have to wait. Oh,
I don't think it's something that is even like theoretically possible, because how
would you figure out if something needs to be a signal or not? I
mean one approach would be to go through the template, see what stuff is
a signal, is a binding and just like convert those properties to signals,
which I guess I mean, it could be done, but it could be
problematic too. Like if it's a bulliant property, okay, we can do
that easily. We could go and say, okay, whenever we say,
let's say you have loading property which is a bullion. Now you want to
turn it signal, Well, no problem. You just instead of saying like
loading equals true, you could say loading equals signal true. And whenever you
assign something to the loading property, you say loading equals false for example.
Instead of that, you could just do loading dot set true. Okay,
that's a simple case. But okay, how about an array. You can
have an array of a signal a signal of an array. I mean,
that's a perfectly reasonable use case. And now you have a bunch of let's
say array dot push statements. How do you go on about converting that?
Do you use the I mean, that's a bunch of stuff that you need
to consider, and I'm not really sure you could like deterministically convert all of
them. It's gonna involve manual labor, Okay, and again you don't probably
you don't need all of your properties to be signals, so it really depends.
But there are manual approaches that you can adopt. That would probably result
in a pretty smooth transition, because again, signals, they're just you know,
reactive freematives. You can use them, you cannot use them. You
can use both signals and like usual properties, so you can just do it.
Let's say, you know, I noticed that I use this word a
lot in the last year incrementally one amazing place to start. If you have
behavior subjects in your angular code, you know, you just don't ditch them
and use a signal because essentially a behavior subject and the signal are the same
thing. At the end of the day. Of course, behavior subject you
could pipe and add operators to it, but in most cases you're using something
like map or tap, so either a side effect or you know, transformation
into another observable. So well, for the first one you can use an
effect. For side effects also you just you can just take the same collback,
put it into an effect statement and be done with it. And for
maps you can use you know, computer properties. So conversion of a behavior
subject to signal in ninety five percent of the case is going to be very
smooth. Okay, So yeah, you could just hunt for behavior subjects in
your code and just turn them into signals. If you have ordinary subjects or
observable as well, no problem. Wrap them in a two signal like use
RXG, just interrop convert them to signal. Now your templates are not using
the acing pipe. It's an overall improvement. And again you can go on
about like the simple properties that are reactive. Again, if you have like
a loading Bullian property, it's fairly easy to manually convert into signal. Not
a big deal at all, will not break anything. Just keep in mind
that you know you've got to have problems with objects. So you can start
with primitive properties, extreme Bullians on and then the final part you can move
on to modifying race making them into signals of a race. So yeah,
that's the am project I would adopt, because there's never gonna be a schematic
for me. I don't think so, Carman, How do you feel about
signals versus behavior subjects in context where where it's not just a component. For
example, I have some utilities that I reuse in many of my projects,
and a lot of them rely heavily on our XS to do some to do
some logic, For example, I have something that does I'm trying to remember
the name that I gave to it. I think it's like thrashold controllers something
like that. It's a It's a utility that I created so that I could
run a bunch of jobs in parallel, but also make sure that I could
limit the amount that was running at the same time. So it's basically a
queue, but it allows jobs to be parallelized up to a certain amount.
Right, So I built that, and I used rxgs and behavior subjects to
listen to the changes in how many jobs are active and how many jobs are
completed, etc. So, as you can see, it's not a very
angular specific thing. It's a piece of code that I can even reuse in
a back end environment, in an environment that has nothing to do with angular
whatsoever. But I was wondering if for such scenarios there would be something simpler
than a behavior subject. But I also understand that I can't use a signal
because I wanted to work other environments. So what I'm actually asking is,
is there like a non angular specific version of a signal that I can use
in such cases? Well, you mentioned parallelizing tasks, so it's gonna be
asynchronous, right, good, So there is no version of signals in existence
right now that could do that. The whole stick of the signals is that
they're synchronous. They almost completely synchronous. Computed properties and proper signals they are
synchronous, and effects they are asynchronous kind of like in reality. Yeah,
they are asynchronous, though they work in in the different fashion that you would
expect. So essentially almost all the stuff that revolves around signals is asynchronous.
My go to approach is to see if the logic that I'm trying to incorporate,
like when we say reactive, often people think that that that's a synchronous,
but that that's not really the case. You could have reactive code that
synchronous. Reactive is essentially just notifying somewhere that something happened. You can do
that synchronous, right, you will you have an array of callbacks and you
just call one of the callbacks and now all the consumers are notified. But
there hasn't been an a sync tick. Right, So, if if I
have something that is reactive, I would just use signals reactive but not asynchronous.
If I have something like a stream of events, then then I'm gonna
have asynchronicity, right, acinc code then I'm gonna use RHS because I cannot
possibly use signals for that because signals are synchronous. How am I, for
example, how I'm gonna check that there are let's say, these many parallel
tasks going on. If the update to one test triggers all the you know,
computer, the properties and so not, that won't be really feasible.
And it should not because signals are reactive states and RGS is now reserved for
asynchronous event. So you have streams of events, not state, and you
have reactive state not events. That's that's that's the whole let's say upgrade for
us. And actually there is another like angular problem with that, like what
people will do. They would say, okay, let's use RHS, for
example in services for all the stuff going on like event pas, whatever.
And then we'll say, but okay, in the component, I want to
use the signal version of this. I want to derive some state from these
events and use it as a signal in a component, which is completely well
the use case. And what they will do they will like call to signal
in the service. Now you've got yourself a problem because to signal immediately subscribes
to the observable, and maybe that observable just waits to be subscribed, so
it doesn't work. It's a cold observable. Now you subscribe to it,
so it's now a hot observable. More So, even if the component where
you are using it gets destroyed, well bad luck. You called to signal
in the service. And if the service is provided in the root injector,
well it's gonna leave. That subscription is gonna leave until the end of the
entire application. So what you need to do is either just used to signal
function in the in the component, or if you want more like even more
granular control, you probably should, I don't know, add some method on
your service that like that's a real approach that people are using. Now you
call it the connect method, and you call connect method whenever you need it
in the component. Like you have something in the service, you say connect
and now all the signals are connected to the observable. Only after that it
will begin to work and then it will be destroyed. In engine destroy you
get at the logic inside that specific function. Okay, you cannot do acing
stuff with signals like bottom line. Yeah, that's a that's a very good
point. You're right, my question entirelie didn't make didn't make sense after I
did, it did because I mean, it's perfectly natural, especially if you
when you when you talk about like your example was really good because you're talking
about a set of things that are working asynchronous, so you have essentially a
state. It's not even a question about what events those other let's say tasks
would emit at some point. It's a question of how you can keep track
of them and so on. You could do that part with signals, but
the very moment you connect to the actual streams, you can no longer really
use signals for that. That's the problem. You could use it for a
state if you have reactive state, did you have a list of events?
Well, but luck, I mean you could derive like today, I did
a small thing for upcoming training of mine. So it's a clock. Okay,
it's a clock that displays the current time, and I want to do
that with the signal. So what I do I use urgually as interval mapped
to the current date. Okay, then used two signal. Now I have
a signal of the current date, which constantly every second it gets updated.
But it's a stage. Now it's a date that changed depending on I don't
know whatever doesn't matter. Maybe I'm getting the current day time via a website
from a or whatever. For that reason. Now I have a signal.
Now I can just do a computing property, and now I have myself beautiful
formative time that I can display in the HTML. We should realize that the
main point of signals, outside of you know, cold and so on,
is to aid we change detection is to be as granular as possible and as
simple to like they could do it with dark just two because R is also
not fastible changes. Right, gave a subject, as we mentioned, but
they wanted something really simple, and you can just drop the signal of this.
Okay, set value, read value. Okay, I'm done, because
under the hood it does call I don't know, marked component dirty. You
might have seen in Angerer seventeen they have like really silently introduced this thing called
local change detection. So, if you're not familiar with signals, if your
component and all these ancestors are on push, which is often the case with
lots of projects, like people like to mark their components on push, now
in that component, if a signal is changed, only that component is change
detected. No, not No parents are marked as dirty if they are also
on Push, which is actually a very very significant development because up until this
point, your best case optimization was to run change detection only on components ancestor
instead of all of the components in the project. Now you can just say,
okay, change to take this one component and you don't have to do
much, just use signals and push change detection strategy on Push. Yeah,
that's the main reason for signals. Signals are magic. They're really cool.
They are they are. They still have problems that they need to work out,
but well, the API is stables, so we're okay using them other
than effect is not stable yet. But you know, you shouldn't probably use
effects that much anyway, like ninety nine percent scenarios, you don't really need
an effect. Yep. Okay. Do you think there's any other major saying
that we should cover on the subject of today's episode in terms of migrations to
the lads? So yeah, one last thing, Yeah, one last thing
that is of course SSR. Now, well, I think we did the
last episode on SSR in general, and we mentioned that SSR now its own
package inside Angular, so you don't have like Angler universe or support, and
now you just have angular slash SSRU. And the cool thing about it is
also supposed that the anged schematic. So if you have a project that is
not a SSR, you can add a SSR using the NGAD angular slash as
a SR command and we'll do a bunch of stuff to generate a server ts
file a if I remember correctly, a main dot server ts file. Those
are actually different. You have one server ts file which has the like a
no GS server conflict, and you have a main server ts file that is
an angular conflict for the and it will add all all the stuff that you
need to a clan side, the hydration and so on and so on.
So in general, it's a simple schematic. So it's it's probably the easiest
outside of the things that we're talking about, because as a starry itself,
the schematic migration is pretty straightforward. You don't change the actual code. I
will talk about it now. You don't need to change the actual code in
nineteen nine percent of scenarios, So yeah, it makes sense to run a
schematic. Then you're gonna have some bugs, and those bugs you will have
only in the scenario where you are actually updating the dome using like the browser
APIs. If you're doing something like documents dot let's say a penschild or whatever.
For those cases you should use the renderer, and for the cases where
you really need to access the dome, you should use the new functions that
we have the after render and after next render, which ensure that some functionality
runs on the client side. But again on top of my head, you
usually discover those bugs like immediately because you open a page and it cannot render,
because you only have those problems if you are calling those functions and life
cycle hooks, Like if you have a method that does some dom manipulation when
the user clicks something, well, the user clicking something is already in the
browser. You don't have a problem there. You don't need to wrap it
in after next render or whatever. You only have problem when you do dom
manipulation and the constructor all saying engine need and Joe after you need and some
because those life cycle methods will be called on the server. Okay, while
server is rendering there, it will call engine need because engine need maybe fetching
data or whatever tool you know render the component. In those cases, it
means that if you have a problem like that, you open that page,
you immediately see an error. You see that, oh what is document?
What is window? I don't know, and instant immediate giveaway that Okay,
that's the problem, and the solution is also easy to take that code,
put it inside after the next vendor, it will work in again nineteen nine
percent of scenarios. Maybe you have something super complex, which could be In
that case you probably would put more leg work. But in general, I
think the transition to SSR, if you want to do it on a fairly
large project, you take a day or two in general, because again you're
not changing the actual code. Your component codes are temperament, they will stay
the same. You will just change very granular pieces which might not even exist
in your project if you're just doing you know more bigger concern for libraries,
that is, but not for you know, enterprise application. So cool,
that was a lot, Yeah, yeah, but I agree, I agree,
And for as you mentioned, for everyone that wants to die to dive
deeper into SSR. The last episode was just about that, So you can
check it out whatever you're you're listening to the show, and we go way
deeper on SSR in the last episode, so you're gonna really know if you
should do it, how you should do it, the caveats, pros,
cons et cetera. So all that that good stuff is there, and yeah,
I think we can we can start wrapping up from here. Yeah,
let's let's do our promos verse. And actually let's start with Arman because I
heard he has something interesting. Oh, I have a long promotion. So
for a long time, I guess the last six seven months, I've been
actually writing a book about Angular, writing a book for the mining publication,
maybe some about listeners about the publications. Fairly fairly popular, lots of amazing
books stay ab out there. The book is called Modern Angular, and so
it's exactly what we have been discussing in the last I guess ten to fifteen
episodes. All the stuff that is new and shining in the latest Angular versions,
so standalone components, inject function, signal, signal signals are is just
interoperability, all the small stuff SSR, unique testing, template syntax, deffert
loading, everything, everything that you know about Angular starting from versions. I
would say fourteen everything that is new is in this book. Now that's how
I know all these migration schematics Yeah, when you are writing a chapter about
you know, say stand alone, you've got to tell people how to migrate.
The book is structured in that way. So in the book we are
sort of coding along an enterprise project with real life problems to solve, and
we are using all the latest features, and each chapter, outside of just
developing that part of the application, also has how to migrate section. So,
for example, for standalone components, we build some standalone components in the
project, we connect them, we provide routing, we provide basedloading, and
so on and so on, and in the final part we have Okay,
now we have a pro existing project. How do we approach this? What
are the caveats, what are the problems I'm an encounter, how the schematic
works, what if I want to do it manually? And essentially this works
for almost all the chapters because all the new stuff we're going to talk about
how to migrate to it. So each chapter has its own sub sections on
migration. The book is now in early access. The first three chapters are
now available. Actually it happened today yea twenty ninth of November. Actually you
forgot about it, and they just got an email that oh, you know
your book is live. So the first three chapters, the covering, standalone
components, and the inject function pretty interesting functionality. You know those chapters are
live. I think I put the links to the book in the chat yet,
so let's have it in the absolute description. Would love to see any
feedback, would love to see comments. There's a live book forum, so
if you have any questions, if any comments, I will be active on
the forum too, trying to address all the stuff coming in from the readers.
Hopefully anyone who want to try the book out. I hope you enjoy
it. I've put a lot of work and a lot of love in it.
That was really amazing experience. Yeah, looking forward for the other chapters
to come around. Awesome. Yeah, congrats man, I know you've been
working on it for a very long time. I'm actually gonna send this here.
Would it be okay to send it in the comments section so that everyone
that is that may be watching us from streaming on YouTube linked eta and yeah,
all right, the link is there. And that also make sure that
we're not gonna forget to included in the in the show notes, because now
it's already in the comments. Actually, Arman I think there's I actually sent
the the broken link. I'm so sorry. Let me let me send another
one with the correct one. Yeah, I was gonna just yeah, I
included an open word at the end that I broke the link. Sorry,
Okay, nice? Correct? All right again, huge congrats to you,
and really for all of you that are looking to improve your best practices and
angular and just update yourself on the framework. I highly encourage checking out Arman's
book and just the fact that you can read the first chapters for free for
now, Like, this is such a big opportunity for people to experiment before
buying it, so like, don't waste this opportunity. This is kind of
having an open house. So yeah, definitely definitely check it out because this
is going to be one of the best chances for you to try out the
content before you make a decision to buy it or not. Yep, Chuck,
how about you. So I am right on the verge of launching a
couple of memberships on top end depvs, and I think the one that is
most relevant to this. So I'm doing a React membership, but I'm also
doing a jobvascript membership, and we're going to have weekly or most well,
it'll be at least three times a month we'll have a meetup and we'll just
we'll be on a zoom call, and the calls are going to kind of
rotate between three different things. One of them is going to be a Q
and a RIGHT, so I'll have some of my expert friends show up,
or I'll just answer your questions myself, or however that works. We're else
going to have an expert show up for one of the calls every month and
talk to us about some aspect of JavaScript or web development or something like that.
Right. Incidentally, the other membership I'm launching is the Ruby membership,
and so the same idea rights. The last one's going to be kind of
a get to know you kind of meet up, and then I'm also going
to be having once a month more of a career soft skills meetup that is
part of all the memberships, and so that's what I'm launching. It will
also include a screencast series. I plan on putting out a couple of videos
every week, UH demonstrating some aspect of JavaScript or web or tooling or something.
So if you go to JavaScript Geniuses dot com, UH, you'll be
able to sign up. I just bought the domain the other day and I'm
getting it all pointed to the right place. You can come see what it's
about and come sign up. So, uh yeah, if you're interested in
participating in that, then definitely check it out. You can come see all
the meetups and when they're scheduled and all that stuff. You can just go
to top endev dot com slash calendar you can see all that stuff too.
But yeah, that's that's the big launch. That's the big thing that I'm
working on right now. Nice, nice, huge. Well I'm still the
same, So my promise are going to be if you're interested in staff fugmentation
or software old sourcing. On void U n v o i D dot com
offers for performance based software development services, so the clients only pay when tests
are delivered and approved, which currently is the safest way for you to outsource
or augment your stuff. Also, they work on US time zones, so
they are a near shore software development agencies. They're not off it's offshore or
offshore. I think it's offshore off shore, yes, thank you, thank
you. Yeah. The time zones are not crazy. So if you end
up choosing to work with onvoid you're gonna know for sure that you and the
engineers are going to be available at the same time, which is really important
for most companies looking to collaborate. And yet I think this is all for
today. I don't have anything else to contribute to I think this was very
in depth and yeah, again, Harman Chuck, thank you so much for
joining. It's always good to have more roll on the show. Yeah,
max out everybody, Thanks everyone, Thanks everyone, and I'll see you in
the next one. H