Standalone Components

Angular v14 Features

  • Typed Forms
  • Standalone Components
  • Page Title Strategy
  • Protected variables
  • Extended developer diagnostics
  • More built-in improvements
  • inject API
  • etc.

pankajparkar

Pankaj P. Parkar

Sr. Technology Consultant, Virtusa

  • MS MVP

  • Angular GDE

  • Stackoverflow Topuser

About Me!

pankajparkar

SCAM

Single Component Angular Module

@Component(...)
export Class AutocompleteComponent {
  ...
}
@NgModule({
  imports: [
    CommonModule,
    ...
  ],
  declarations: [
    AutocompleteComponent
  ],
  exports: [AutocompleteComponent],
})
export Class AutocompleteModule {
  ...
}

Standalone Components 

(developer preview)

  • Rigid step towards Optional NgModule now
  • The component can be defined without NgModule
ng generate component standalone --standalone
@Component({
  selector: 'app-standalone',
  standalone: true,
  imports: [CommonModule], // <-- all imports goes here
  templateUrl: './standalone.component.html',
  styleUrls: ['./standalone.component.scss']
})
export class StandaloneComponent implements OnInit {
  ...
}

pankajparkar

How angular application bootstrap?

.

.

.

Root

Component

// app.module.ts
@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  bootstrap: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    ...
  ],
  providers: [],
})
export class AppModule { }
// main.ts
platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

C

P

S

D

M

Standalone Components 

ctd.


@NgModule({
  declarations: [AppComponent],
  bootstrap:    [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
  ],
  providers: [],
})
export class AppModule { }

Bootstrap app without AppModule using `bootstrapApplication`

@Component({
  selector: 'app-root',
  standalone: true, // <- add standalone
  imports: [], // <- and imports array
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
}
bootstrapApplication(
  AppComponent, 
  {
    providers: [
      importProvidersFrom([
        BrowserModule,
        AppRoutingModule,
        BrowserAnimationsModule,
      ])
    ]
  }
)
const routes = [
  {
    path: 'standalone',
    component: StandaloneComponent,
  },
  ...
];

Routing

pankajparkar

Routing Lazy Load

const routes = [
  {
    path: 'standalone-lazy',
    loadComponent: () => import('./components/standalone-lazy.component')
    	.then(s => s.StandaloneLazyComponent),
  },
]

pankajparkar

Standalone Components 

ctd.

const routes = [{
  path: 'standalone-childrens',
  loadComponent: () => import('./components/standalone-childrens.component')
    .then(s => s.StandaloneChildrenComponent),
  children: [
    {
      path: 'child-firstchild',
      component: import('./components/standalone-first-child.component')
      .then(s => s.FirstChildComponent)
    },
    {
      path: 'child-firstchild',
      component: import('./components/standalone-first-child.component')
      .then(s => s.FirstChildComponent)
    },
  ]
}]
Lazy Standalone Component and its children routes

pankajparkar

importProvidersFrom

Collects providers from all NgModules and standalone components, including transitively imported ones.

importProvidersFrom([
  BrowserModule,
  RouterModule.forRoot(routes),
  BrowserAnimationsModule,
  HttpClientModule,
]),

pankajparkar

Angular Elements with Standalone Component

bootstrapApplication(AppComponent)
  .then((ref) => {
    const wc = createCustomElement(
      HelloComponent, {
        injector: ref['injector'],
      }
    );
  });

pankajparkar

Angular Elements with Standalone Component

// get a hand on the environment injector
const envInjector = await createRootEnvironment();

// create a constructor of a custom element
const NgElementCtor = createCustomElement(TestStandaloneCmp, {
  injector: envInjector
});

// register in a browser
customElements.define('test-standalone-cmp', NgElementCtor);

Ref - https://github.com/angular/angular/pull/46475

Future

pankajparkar

EnvironmentInjector

and ENVIRONMENT_INITIALIZER

{
  provide: ENVIRONMENT_INITIALIZER,
  useValue: (fooService: FooService) => {
    fooService.initialize();
  },
  deps: [FooService]
},

pankajparkar

Demo - https://github.com/pankajparkar/standalone-components-angular

pankajparkar

Q & A

pankajparkar

pankajparkar

pankajparkar

References

  • https://blog.angular.io/angular-v14-is-now-available-391a6db736af

  • https://netbasal.com/handling-page-titles-in-angular-40b53823af4a

  • https://blog.angular.io/angular-extended-diagnostics-53e2fa19ece9

  • https://marmicode.io/blog/angular-inject-and-injection-functions

  • https://nartc.me/blog/inheritance-angular-inject

  • https://netbasal.com/getting-to-know-the-environment-initializer-injection-token-in-angular-9622cb824f57

  • https://github.com/angular/angular/pull/46475

pankajparkar

Standalone Component

By Pankaj Parkar

Standalone Component

Angular Standalone Components

  • 308