Mastering Angular 8: five things that are good to know to save your time.
Angular has some edge cases that can sometimes waste your time if you're not familiar with the details.
I've been working with Angular for the last 3 years and here are some interesting things that I've learned that will save your time. We're going to talk about:
How HTTPInterceptors work with feature modules
Query params are lost on angular router redirect
::ng-deep span - avoid encapsulation for specific elements (on an example of search words highlighting)
Http with no subscribe
Reload component on same URL navigation
Let's dig in.
You can view the runnable demo here in Stackblitz and review the code in this Github repo.
Once upon a time, I had a mentoring session on codementor.io where we integrated some separate Angular application to work as a feature module of the main project app. Code was copied to the project features folder it was added a lazy-loaded module and added to the main app routing config.
app.routing.ts looked like this:
At the end directory structure looks very similar to the code in our demo project:
From a first glance - it should work like a charm. And actually it does.
Except for one small thing.
Main app component, as well as feature module component, perform some HTTP calls with standard Angular
HttpClientModule and specific token-interceptor appends Authorization header to all outgoing network requests.
But somehow feature module network requests were not handled by a token-interceptor of the main app.
Well, I will not torment you with intrigue. The problem was that during independent development of feature - individual
HTTPClientModule was added to imports array of
feature.module.ts. And it made Angular create another instance of
HttpModule with an empty custom interceptors list.
How to avoid it? Just comment out
HTTPClientModule in all other Angular modules except the main app module. (
Now, the feature module looks like this:
Knowing that peculiarity allows you to implement specific
HTTPInterceptors for particular feature modules. All you have to do is to add
HTTPClientModule to specific Angular feature module and define
HTTP_INTERCEPTORS provider in the same module as well. Now in your feature module only its own interceptors will be used while all other application modules will use the root app module interceptor.
Let's check how it works:
Sometimes we have to specify query params for our Angular SPA. In that case, our application URL may look like:
It should work well. But very often Angular routing config uses redirectTo directive to lead request to a specific home component:
And we expect that Angular will change URL to: http://yourdomain.com/home?search=text&page=3
But practically Angular changes it to: http://yourdomain.com/home.
Query parameters are lost. HomeComponent will not be able to get them
How to deal with it?
There are three ways:
The simplest. Just use the direct HomeComponent route URL with all params:
Redirect is not happening in this case, so queryParams will not be lost.
The hardest. Listen to all route events and in case of redirect just copy query params and restore/assign them for /home page.
And one more nice solution - query params are not lost if we just remove '/' sign in route path, like this:
Which method is best for you? Leave your choice in comments.
#3. ::ng-deep span - avoid encapsulation for specific elements (on an example of search words highlighting)
Ok, say you have a task make search text to be highlighted in specific paragraph.
How would you do that? The easiest way - just save the original text. And on each search just replace text we are looking for with
And to highlight it in a
component.scss file we put the rule:
You run it but...it doesn't work:
What is your gut feeling why it doesn't work? My first thought was that somehow our CSS rule was not included in a final bundle. So I decided to search for it and this is what I've found:
Angular applies CSS encapsulation for all component css rules. That's why our element is not highlighted. How to fix it? Just use ::ng-deep prefix to tell Angular that this specific rule should not be modified:
Now if we check our search with highlighting - it will work good:
If you monitoring the Angular community on Twitter then you may notice that template-driven development is becoming a new trend.
Good examples of that approach are:
Let's apply this approach to quite a routine task when our Angular component does some network request inside ngOnInit hook. Very often code for that looks like this: