Component features with Angular Ivy

Are you excited about component features? Which use cases would be sweet? Let me know right here.

2 Likes

With the version "~9.1.1", of @angular/core the property factory of ɔComponentDef is readonly. What does this mean for the examples now?

1 Like

Hi Lukas, welcome to the inDepth.dev Community.

As we discussed, it is only a TypeScript readonly property, so we can still override it.

// with-username.feature.ts
import {
  ɔComponentDef as ComponentDef,
  ɔɔdirectiveInject as directiveInject,
} from '@angular/core';
import { select, Store } from '@ngrx/store';

export function withUsername(componentDef: ComponentDef<any>): void {
  const { factory, type } = componentDef;

  // This is how to replace the readonly component factory
  (componentDef as any).factory = () => {
    const component = factory(type);
    const store = directiveInject(Store);
    component.username$ = store.pipe(select('username'));

    return component;
  };
}

It was made readonly by PR#34683.

You told me that the Promise.resolve hack doesn’t work anymore, that a few seconds passes by, before the factory property is assigned. Maybe our componentFeatures decorator needs to hook into the application initialize or bootstrap lifecycle.

Hi @LayZee! Thank you for the article!

How about the testing of this feature? Because I faced with the issue that ɔcmp and ɔdir properties are undefined when I run the tests?

function FeaturesDecorator(features: IFeature[]) {
      return <T>(componentType: Type<T>) => {
        const def = componentType as ɔDirectiveType<T> & ɔComponentType<T>;

        if (def.ɔcmp) { // empty for tests, but works for app
          return ComponentFeatures(def, features, def.ɔfac);
        }
        if (def.ɔdir) {  // empty for tests, but works for app
          return DirectiveFeatures(def, features, def.ɔfac);
        }
      };
    }
1 Like

Which version of Angular? AOT became the default compilation mode for tests in Angular version 9.

Angular: 10.0.3

When I’ve added Promise.resolve() - works as expected, but without - É”cmp and É”dir properties are undefined

That’s what I found at runtime back when I initially started experimenting with them. There is a change coming that might change this.

It just landed in Angular 10.1.

1 Like

Great! Thanks, I’ll try it after upgrade.