DEV Community

Aleksandra Janecka
Aleksandra Janecka

Posted on

Days 8-10: Standalone components and home view

In the previous blog post I was talking about how I've set up my project and about creating login and create account pages. Now it's time to move into main part of the application and also to start thinking a bit about project structure!

Day 8 - Home view

Day 8 was quite simple. It was Sunday, so I had more time to code and I spent it on creating the layout for the home view for my application. And here is the effect!
Home view

For the most part is was going pretty smoothly. I just ran into one problem, I spent way too much time trying to solve (and eventually giving up...) Namely, trying to change the fill color of SVGs... I still have no idea, why is it not working... If you have some suggestions, I'd be glad to hear!

SVG hover problem

The icon here also should change the color on hover as the text does...

Days 9-10 - Project structure

On days 9 to 10 it was time to start thinking about project structure! I wasn't coding too much these days, but some conceptual work is needed sometimes as well! First my idea was to split an app into modules - the old fashioned way 😉

But then I learned that I've had this misconception about standalone components, that they are mostly good as a substitute for shared module. It turns out, it is actually recommended to build whole applications using them nowadays! So that's what I decided to do! But first... what the hell are standalone components?

Standalone components

Standalone components are a relatively new feature introduced in Angular 15. They offer a simplified way of building applications, because they are not a part of any module, and also, when used in another standalone components, they don't need to be imported! You can use them just like that! But they can also be imported into a module, so you can slowly transition into this new style without having to refactor the whole application.

So what are the advantages of standalone components? The main one is that you don't introduce unnecessary dependencies, by importing whole modules, when you only need bunch of components from them, which in turn reduces the bundle size, thus making your application run faster!

So how do I make an standalone component? It's very easy! You just add standalone: true to it's declaration :) Also you need to import into a component all the components that you are using in it. So now the declaration looks like this:

@Component({
    selector: 'app-navbar',
    templateUrl: './navbar.component.html',
    styleUrls: ['./navbar.component.scss'],
    standalone: true,
    imports: [ToggleButtonsComponent],
})
export class NavbarComponent {
Enter fullscreen mode Exit fullscreen mode

Migrating an application to standalone components

So do I have to go through the whole application now, and manually change the declarations of all components? No! There is a tool for that!
You just need to tun this command thrice: ng generate @angular/core:standalone

Wait.. why thrice? Is it some kind of weird spell? No, it's because the migration is split into parts, and each time you need to select another option :) These are the options, you get when you run this command:
Available options

Step 1: Convert all components, directives and pipes to standalone

This step is doing something similar to what I have shown in the code block above. It turns all the components into standalone versions and adds necessary imports to them!

Step 2: Remove unnecessary NgModule classes

This step did nothing when I ran this in my application. That's because I only have AppModule which is my root module, and AppRoutingModule which is my main routing module. But if I had any other modules in my app, they should in theory be removed. But this step often doesn't remove all the modules, and some manual work may still be needed.

Step 3: Bootstrap the application using standalone APIs

This step removes the root module of your application and instead invokes bootstrapApplication function in your main.ts. That function is responsible for bootstrapping your routing, singleton services etc. It looks like this:

bootstrapApplication(AppComponent, {
    providers: [
        importProvidersFrom(BrowserModule, AppRoutingModule, ReactiveFormsModule, AngularSvgIconModule.forRoot()),
        provideHttpClient(withInterceptorsFromDi())
    ]
})
  .catch(err => console.error(err));
Enter fullscreen mode Exit fullscreen mode

??? Profit?

Not yet in my case! One pesky module is still standing strong! And it is routing module.

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}
Enter fullscreen mode Exit fullscreen mode

Let's just get rid of it, export routes, and rename the file to something like routes.ts. So the content of this file looks something like this now:

export const routes: Routes = [
  { path: '', redirectTo: '/sign-in', pathMatch: 'full' },
  {
    path: 'sign-in',
    title: 'Sign in',
    component: LoginComponent,
    pathMatch: 'full',
  },
  {
    path: 'sign-up',
    title: 'Sign up',
    component: SignUpComponent,
    pathMatch: 'full',
  },
  {
    path: 'dashboard',
    title: 'Dashboard',
    component: DashboardComponent,
    pathMatch: 'full',
    canActivate: [authGuard],
  },
];
Enter fullscreen mode Exit fullscreen mode

Now we can change the way we provide it in our bootstapApplication function:

bootstrapApplication(AppComponent, {
    providers: [
        importProvidersFrom(BrowserModule, ReactiveFormsModule, AngularSvgIconModule.forRoot()),
        provideHttpClient(withInterceptorsFromDi()),
        provideRouter(routes)
    ]
})
Enter fullscreen mode Exit fullscreen mode

And that's it! The application is working fine, and we don't have a single module in it! Well, instead of the ones from Angular and external libraries 😉

Conclusion

For the past two days I haven't done much coding, but I still learned a lot. And now I can play more with this new style of application and play around with concepts like lazy loading. In the following days I'll probably get back to coding to cool off a bit, but I still have some concepts like this to explore, so from time to time I will be sharing these effects of my exploration. Until next time!

Top comments (0)