Watch the whole Angular Mistakes Playlist here on UA-cam 😊 - ua-cam.com/video/3oq-gnDzz9k/v-deo.html Looking to learn Angular? Check out my courses, from beginner to advanced - angular-university.io
Thanks for such a cool content. Keep doing it! My question is : will you teach or show how to make applications ssr and examples of deploying it on several platforms like Firebase,Aws ets. Thanks!
Thank you, it's awesome to hear that. 😊 I might do a video sometime on how to deploy to Google Cloud Run or Google Cloud functions, but it's not high on my list of content to do.
Great video :) What happens in example 2 when the error is thrown? Can the component catch that and show the user an error message? Also, would you consider using .pipe(take(1)) to make 100% sure that api calls are are called once then automatically cleaned up?
Thank you I'm glad you enjoyed it 😊The component can add any error handling logic needed and rethrow. In this example, I just added catchError to show where the error handling logic would go, but I didn't implement any specific error handling other that logging. Yes, I talk about that method at the end in the conclusion, use take(1) also works to make sure the long-lived observable completes. I use that all the time for Firestore queries. 👍
Truly admire how you utilize resolvers to prevent memory leaks. I do have a question, though. Given your use of Angular httpClient for API calls, doesn't it automatically handle subscription cleanup once the HTTP request is completed?
Yes, I do mention that in the end of the video, the HTTP client does complete or error it's Observables, so those Observables don't create memory leaks. That is one of the common mistakes actually, 😉 people are unsubscribing from these observables manually when it's not needed.
@@AngularUniversityYeah. Although many developers adopt certain best practices, often they do so without fully understanding the rationale behind them or whether they are truly necessary. Could you please generate some content explaining the reasoning behind commonly adopted best practices? That would be helpful.
@@udithamax7 That's a good idea, I will think about a video like that. The problem is, what is a good practice in one case might not apply in another, that's a bit the overall theme of the mistakes series. It's easy for people to take what is presented as a best practice and apply it blindly everywhere independently of the context.
Thank you, it's awesome to hear that 😊 Yes there is, via the Chrome Dev Tools Memory tab. But as mentioned in the video, the main thing is not to worry about it unnecessarily, most of the times is not an actual problem. 👍
What if in solution 3 you would subscribe inside the service and you would have a component dedicated store service? Do you follow this practice or you prefer to susbscribe in the component? Thanks for these awesome series of videos!!
Thank you, I'm glad to hear you enjoy the videos 😊 If you subscribe manually inside a service, the issue would be similar unless the observable completes. So the same principles apply 👍
The reason I typically not using resolvers is that they will delay the whole page from start showing. The thing you are resolving is often just a part of the page but the user wont be able to interact with anything else until the resolver is finished
@@teolag so the component will only be initiated once the requests are done (then the router will route)? so using resolvers it's not possible to use loading skeletons for the page/component?
@@carolruoyep, that's right. When using resolvers the component is not loaded until all of them complete. You could do a workaround to show a loader listening to the router events, from some higher level component. I've used the resolvers solution in some projects, but not anymore due to the lack of reactivity you get. I think it's better to accept that we manage async content and make your app as reactive as possible. Now I only use resolvers for data which is not loaded asynchronously, so very rarely.
Not to be pedantic but we tend to say 'memory leak' when the real issue is most often better described as a 'resource leak' or 'behavioral leak' where some process is ongoing that's no longer needed. This is likely going to put pressure on your network card or CPU just as much as your RAM, or possibly even undesirable application behavior
Like a process that keeps running in the background that we forgot to shut down, right? In this case I was referring to discarded components that accidentally don't get garbage collected. 👍
@AngularUniversity yeah you definitely hit on that point, I'm just trying to unlearn the habit myself of referring to them as a memory leak since i feel it misses the mark, and I guess I'm just projecting a bit 🤣
@@AngularUniversity thanks for the response! There’s quite a few places on my team where we could use them which would be better or a nice alternative to our current approach.
You can use for example a solution based on an HTTP Interceptor, here is a guide on how to do it 👍 - blog.angular-university.io/angular-loading-indicator/
@AngularUniversity Thanks so much for your content i really appreciate I was about to create a custom loading behaviour depending on which component is using it and I find the #2 solution is quite clear and nice to use but I don't know how to do it with custom loading behaviour!
Hello, your examples are mostly for get http call, why do you not talk much about post for example, this will help people make solid decisions wholesomely
Yes no problem. 😊👍 You can even create multiple resolvers per component, to fetch different types of data. You can also take the same resolver and reuse it in several different components as well. 👍
@@PlerbyMcFlerb it doesn't make any sense to use catchError operator for side-effects and return absolutely the same error, there is tap for that - tap({error: err => console.error(err)}).
the 2nd solution is way too complex and I dont really get the point of it. you're talking about simplifying things in other mistakes, like "dont overuse rxjs" and now you come up with this "stupidly complex" resolver solution.. wtf, be consistent. not to mention that the behavior of the app is totally different, because the page wont load until the data is resolved..
The advantage of the resolver is that it's a plain Angular feature. The behavior is not exactly the same, but the end result is the same, the data gets to the component except no Observables are needed. For the vast majority of situations, this should be enough, even if the loading behavior is slightly different. The main point of showing that solution was, try to think outside the box. There are other solutions on the framework that don't even need Observables. So avoid the problem instead of fixing it.
Watch the whole Angular Mistakes Playlist here on UA-cam 😊 - ua-cam.com/video/3oq-gnDzz9k/v-deo.html Looking to learn Angular? Check out my courses, from beginner to advanced - angular-university.io
Clear, precise and informative video. Way to go!
Thank you so much. Stay tuned for more videos!
Love your explanation! I've been watching (and subscribed) for Angular University for a long time and can assure you made huge progress in your work.
Wow. Thank you for you kind words. Stay tuned and enjoy the videos!
Very interesting way with resolver! Love Your recent content, keep it up 😊 I believe your channel will gain many subs from people learning angular 17!
Thank you so much 😀
Thanks for such a cool content. Keep doing it!
My question is : will you teach or show how to make applications ssr and examples of deploying it on several platforms like Firebase,Aws ets.
Thanks!
Thank you, it's awesome to hear that. 😊 I might do a video sometime on how to deploy to Google Cloud Run or Google Cloud functions, but it's not high on my list of content to do.
Great video :) What happens in example 2 when the error is thrown? Can the component catch that and show the user an error message?
Also, would you consider using .pipe(take(1)) to make 100% sure that api calls are are called once then automatically cleaned up?
Thank you I'm glad you enjoyed it 😊The component can add any error handling logic needed and rethrow. In this example, I just added catchError to show where the error handling logic would go, but I didn't implement any specific error handling other that logging. Yes, I talk about that method at the end in the conclusion, use take(1) also works to make sure the long-lived observable completes. I use that all the time for Firestore queries. 👍
Truly admire how you utilize resolvers to prevent memory leaks.
I do have a question, though. Given your use of Angular httpClient for API calls, doesn't it automatically handle subscription cleanup once the HTTP request is completed?
Yes, I do mention that in the end of the video, the HTTP client does complete or error it's Observables, so those Observables don't create memory leaks. That is one of the common mistakes actually, 😉 people are unsubscribing from these observables manually when it's not needed.
@@AngularUniversityYeah. Although many developers adopt certain best practices, often they do so without fully understanding the rationale behind them or whether they are truly necessary. Could you please generate some content explaining the reasoning behind commonly adopted best practices? That would be helpful.
@@udithamax7 That's a good idea, I will think about a video like that. The problem is, what is a good practice in one case might not apply in another, that's a bit the overall theme of the mistakes series. It's easy for people to take what is presented as a best practice and apply it blindly everywhere independently of the context.
Nice one with the resolver!
Sometimes we just have to think outside of the box. Instead of solving the problem, how can I avoid it in the first place? 😉
This is such a valuable content. Thank you.
Thank you, you're welcome. 😊
Thanks, I like your series. Very useful and well explained
By the way, is there a possibility to detect memory leaks via dev tools in chrome?
Thank you, it's awesome to hear that 😊 Yes there is, via the Chrome Dev Tools Memory tab. But as mentioned in the video, the main thing is not to worry about it unnecessarily, most of the times is not an actual problem. 👍
What if in solution 3 you would subscribe inside the service and you would have a component dedicated store service? Do you follow this practice or you prefer to susbscribe in the component? Thanks for these awesome series of videos!!
Thank you, I'm glad to hear you enjoy the videos 😊 If you subscribe manually inside a service, the issue would be similar unless the observable completes. So the same principles apply 👍
Mistake 0: not using strict nulls in tsconfig ;)
Yes 🤣
what is the downside of solution 2? looks way better than the others
I don't think there is any downside, it's my preferred solution too as it's the simplest. We just solve the problem by avoiding it altogether. 👍
The reason I typically not using resolvers is that they will delay the whole page from start showing. The thing you are resolving is often just a part of the page but the user wont be able to interact with anything else until the resolver is finished
@@teolag so the component will only be initiated once the requests are done (then the router will route)? so using resolvers it's not possible to use loading skeletons for the page/component?
@@carolruoyep, that's right. When using resolvers the component is not loaded until all of them complete. You could do a workaround to show a loader listening to the router events, from some higher level component.
I've used the resolvers solution in some projects, but not anymore due to the lack of reactivity you get. I think it's better to accept that we manage async content and make your app as reactive as possible. Now I only use resolvers for data which is not loaded asynchronously, so very rarely.
A great series
Thank you 😊
Not to be pedantic but we tend to say 'memory leak' when the real issue is most often better described as a 'resource leak' or 'behavioral leak' where some process is ongoing that's no longer needed. This is likely going to put pressure on your network card or CPU just as much as your RAM, or possibly even undesirable application behavior
Like a process that keeps running in the background that we forgot to shut down, right? In this case I was referring to discarded components that accidentally don't get garbage collected. 👍
@AngularUniversity yeah you definitely hit on that point, I'm just trying to unlearn the habit myself of referring to them as a memory leak since i feel it misses the mark, and I guess I'm just projecting a bit 🤣
Wait I thought resolvers were depreciated? Am I wrong on this?
Resolvers are not deprecated, they just have now a new way of writing them which are functional resolvers, instead of class-based. 👍
@@AngularUniversity thanks for the response! There’s quite a few places on my team where we could use them which would be better or a nice alternative to our current approach.
I thought subscription from observables from the http client didn't need unsubscribing since they complete immediately
That is correct, I mention that in the video at the end. 👍
@@AngularUniversity oh sorry must have missed it
takeUntilDestroyed is still not production ready. It's in developer preview mode.
Correct, but still it's pretty usable. Developer preview just means that they reserve the right to tweak the API if needed. 👍
What about handling loading indicator in solution #2
How to do it in case of resolver?
You can use for example a solution based on an HTTP Interceptor, here is a guide on how to do it 👍 - blog.angular-university.io/angular-loading-indicator/
@AngularUniversity
Thanks so much for your content i really appreciate
I was about to create a custom loading behaviour depending on which component is using it and I find the #2 solution is quite clear and nice to use but I don't know how to do it with custom loading behaviour!
Hello, your examples are mostly for get http call, why do you not talk much about post for example, this will help people make solid decisions wholesomely
I show a chain of data modification operations using Observavles on video 2 of this series 👍
I can create same number of resolver as number of component?
Yes no problem. 😊👍 You can even create multiple resolvers per component, to fetch different types of data. You can also take the same resolver and reuse it in several different components as well. 👍
it's wrong usage of catchError operator
catchError((error) => {
catch.error(error);
throw error;
})
Thank you, but can you explain further what you mean with catch.error(error)? I never saw that syntax 😊
@@AngularUniversity I wanted to write `console.error(error)`
Assuming that the goal was to log an error to console and then still emit from the error channel then this would work completely fine.
@@PlerbyMcFlerb it doesn't make any sense to use catchError operator for side-effects and return absolutely the same error, there is tap for that - tap({error: err => console.error(err)}).
the 2nd solution is way too complex and I dont really get the point of it. you're talking about simplifying things in other mistakes, like "dont overuse rxjs" and now you come up with this "stupidly complex" resolver solution.. wtf, be consistent.
not to mention that the behavior of the app is totally different, because the page wont load until the data is resolved..
The advantage of the resolver is that it's a plain Angular feature. The behavior is not exactly the same, but the end result is the same, the data gets to the component except no Observables are needed. For the vast majority of situations, this should be enough, even if the loading behavior is slightly different. The main point of showing that solution was, try to think outside the box. There are other solutions on the framework that don't even need Observables. So avoid the problem instead of fixing it.