Search code examples
javascriptangulartypescriptsvgng-circle-progress

Getting the NPM ng-circle-progress Component to work in Angular 16?


Trying to get the NG Circle Progress component to work in Angular 16.

This is the Stackblitz.

This is the template configuration.

  <circle-progress name="A" [options]="optionsA" [renderOnClick]="false" class="copy"
  (click)="copyOptions($event, optionsA)"></circle-progress>

And this are the component options in main.ts.

  optionsA = {
    percent: 85,
    radius: 60,
    showBackground: false,
    outerStrokeWidth: 10,
    innerStrokeWidth: 5,
    subtitleFormat: false, // clear subtitleFormat coming from other options, because Angular does not assign if variable is undefined.
    startFromZero: false,
  };

And the module configuration is specified according to the README.md.

@Component({
  selector: 'my-app',
  standalone: true,
  imports: [
    CommonModule,
    NgCircleProgressModule.forRoot({
      radius: 100,
      outerStrokeWidth: 16,
      innerStrokeWidth: 8,
      outerStrokeColor: '#78C000',
      innerStrokeColor: '#C7E596',
      animationDuration: 300,
    }),
  ],

The module configuration produces the following error.

Type 'ModuleWithProviders<NgCircleProgressModule>' is not assignable to type 'readonly any[] | Type<any>'.(2322)
(alias) class NgCircleProgressModule
import NgCircleProgressModule

Thoughts?


Solution

  • XXModule.forRoot() methods return providers, this call belongs into the provider part of the component configuration.

    Also you'll need to keep the import.

    So it should look like following:

    @Component({
      selector: 'my-app',
      standalone: true,
      imports: [CommonModule, NgCircleProgressModule],
      providers: [
        (NgCircleProgressModule.forRoot({
          radius: 100,
          outerStrokeWidth: 16,
          innerStrokeWidth: 8,
          outerStrokeColor: '#78C000',
          innerStrokeColor: '#C7E596',
          animationDuration: 300,
        }) as ModuleWithProviders<NgCircleProgressModule>).providers!,
      ],
      template: `
      <circle-progress name="A" [options]="optionsA" [renderOnClick]="false" class="copy"
      (click)="copyOptions($event, optionsA)"></circle-progress>
    `,
    })
    

    In addition, the circle-progress component's options are typed as CircleProgressOptions instead of CircleProgressOptionsInterface and this implementation is more strict, therefore optionsA needs to have all the properties of CircleProgressOptions. They can be added like this:

      optionsA: CircleProgressOptions = {
        ...this.options,
        percent: 85,
        radius: 60,
        showBackground: false,
        outerStrokeWidth: 10,
        innerStrokeWidth: 5,
        subtitleFormat: false, // clear subtitleFormat coming from other options, because Angular does not assign if variable is undefined.
        startFromZero: false,
      };
    

    Here's a working implementation..