0

i am upgrading my angular 11.0.2 ngx-admin dashboard project to Angular 15.2.9

during package update i got following error

   Error: node_modules/ng-particles/lib/ng-particles.component.d.ts:18:89 - error TS2344: Type '{ options: { alias: "options"; required: false; }; url: { alias: "url"; required: false; }; id: { alias: "id"; required: false; }; particlesInit: { alias: "particlesInit"; required: false; }; }' does not satisfy the constraint '{ [key: string]: string; }'.
  Property '"options"' is incompatible with index signature.
    Type '{ alias: "options"; required: false; }' is not assignable to type 'string'.

18     static ɵcmp: i0.ɵɵComponentDeclaration<NgParticlesComponent, "ng-particles", never, { "options": { "alias": "options"; "required": false; }; "url": { "alias": "url"; "required": false; }; "id": { "alias": "id"; "required": false; }; "particlesInit": { "alias": "particlesInit"; "required": false; }; }, { "particlesLoaded": "particlesLoaded"; }, never, never, false, never>;
                                                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Error: src/app/auth/login/login.component.html:6:9 - error NG8002: Can't bind to 'options' since it isn't a known property of 'ng-particles'.
1. If 'options' is an Angular directive, then add 'CommonModule' to the '@NgModule.imports' of this component.
2. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

6         [options]="particlesOptions"
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  src/app/auth/login/login.component.ts:16:16
    16   templateUrl: "./login.component.html",
                      ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent

this is how i configured ng-particles in my project

... respective imports

@Component({
  selector: "ngx-login",
  templateUrl: "./login.component.html",
  styleUrls: ["./login.component.scss"],
})
export class LoginComponent extends NbLoginComponent implements OnInit {
  loading = false;

  constructor(
    protected service: NbAuthService,
    @Inject(NB_AUTH_OPTIONS) protected options = {},
    protected cd: ChangeDetectorRef,
    protected router: Router,
    private authService: AuthService,
    public toastrService: NbToastrService
  ) {
    super(service, options, cd, router);
  }

  id = "tsparticles";
  particlesOptions = {
    autoPlay: true,
    background: {
      color: {
        value: "rgb(33 150 243 / 50%)",
      },
      image: "",
      position: "50% 50%",
      repeat: "no-repeat",
      size: "cover",
      opacity: 1,
    },
    backgroundMask: {
      composite: "destination-out",
      cover: {
        color: {
          value: "#fff",
        },
        opacity: 1,
      },
      enable: false,
    },
    fullScreen: {
      enable: true,
      zIndex: 1,
    },
    detectRetina: true,
    duration: 0,
    fpsLimit: 60,
    interactivity: {
      detectsOn: "canvas",
      events: {
        onClick: {
          enable: false,
          mode: "push",
        },
        onDiv: {
          selectors: [],
          enable: false,
          mode: [],
          type: "circle",
        },
        onHover: {
          enable: false,
          mode: "bubble",
          parallax: {
            enable: false,
            force: 2,
            smooth: 10,
          },
        },
        resize: true,
      },
      modes: {
        attract: {
          distance: 200,
          duration: 0.8,
          easing: "ease-out-quad",
          factor: 1,
          maxSpeed: 10,
          speed: 1,
        },
        bounce: {
          distance: 100,
        },
        bubble: {
          distance: 200,
          duration: 2,
          opacity: 0.8,
          color: {
            value: "#1b1e34",
          },
          size: 20,
        },
        connect: {
          distance: 80,
          links: {
            opacity: 0.5,
          },
          radius: 60,
        },
        grab: {
          distance: 200,
          links: {
            blink: false,
            consent: false,
            opacity: 1,
          },
        },
        light: {
          area: {
            gradient: {
              start: {
                value: "#ffffff",
              },
              stop: {
                value: "#000000",
              },
            },
            radius: 1000,
          },
          shadow: {
            color: {
              value: "#000000",
            },
            length: 2000,
          },
        },
        push: {
          default: true,
          groups: [],
          quantity: 4,
        },
        remove: {
          quantity: 2,
        },
        repulse: {
          distance: 200,
          duration: 0.4,
          factor: 100,
          speed: 1,
          maxSpeed: 50,
          easing: "ease-out-quad",
        },
        slow: {
          factor: 3,
          radius: 200,
        },
        trail: {
          delay: 1,
          pauseOnStop: false,
          quantity: 1,
        },
      },
    },
    manualParticles: [],
    motion: {
      disable: false,
      reduce: {
        factor: 4,
        value: true,
      },
    },
    particles: {
      bounce: {
        horizontal: {
          random: {
            enable: false,
            minimumValue: 0.1,
          },
          value: 1,
        },
        vertical: {
          random: {
            enable: false,
            minimumValue: 0.1,
          },
          value: 1,
        },
      },
      collisions: {
        bounce: {
          horizontal: {
            random: {
              enable: false,
              minimumValue: 0.1,
            },
            value: 1,
          },
          vertical: {
            random: {
              enable: false,
              minimumValue: 0.1,
            },
            value: 1,
          },
        },
        enable: false,
        mode: "bounce",
        overlap: {
          enable: true,
          retries: 0,
        },
      },
      color: {
        value: "#223d7e",
        //  "value": "#1b1e34",
        animation: {
          h: {
            count: 0,
            enable: false,
            offset: 0,
            speed: 1,
            sync: true,
          },
          s: {
            count: 0,
            enable: false,
            offset: 0,
            speed: 1,
            sync: true,
          },
          l: {
            count: 0,
            enable: false,
            offset: 0,
            speed: 1,
            sync: true,
          },
        },
      },
      destroy: {
        mode: "none",
        split: {
          count: 1,
          factor: {
            random: {
              enable: false,
              minimumValue: 0,
            },
            value: 3,
          },
          rate: {
            random: {
              enable: false,
              minimumValue: 0,
            },
            value: {
              min: 4,
              max: 9,
            },
          },
          sizeOffset: true,
        },
      },
      groups: {},
      life: {
        count: 0,
        delay: {
          random: {
            enable: false,
            minimumValue: 0,
          },
          value: 0,
          sync: false,
        }, import { HttpErrorResponse } from "@angular/common/http";
import { ChangeDetectorRef, Component, Inject, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import {
  NbAuthService,
  NbLoginComponent,
  NB_AUTH_OPTIONS,
} from "@nebular/auth";
import { NbToastrService } from "@nebular/theme";
import { AuthService } from "../auth.service";
import { Container, Main } from "tsparticles-engine";
// import type { Container, Main } from 'tsparticles';

        duration: {
          random: {
            enable: false,
            minimumValue: 0.0001,
          },
          value: 0,
          sync: false,
        },
      },
      links: {
        blink: false,
        color: {
          value: "#ffffff",
        },
        consent: false,
        distance: 200,
        enable: false,
        frequency: 1,
        opacity: 1,
        shadow: {
          blur: 5,
          color: {
            value: "#00ff00",
          },
          enable: false,
        },
        triangles: {
          enable: false,
          frequency: 1,
        },
        width: 2,
        warp: false,
      },
      move: {
        angle: {
          offset: 0,
          value: 90,
        },
        attract: {
          distance: 200,
          enable: false,
          rotate: {
            x: 600,
            y: 1200,
          },
        },
        decay: 0,
        distance: {},
        direction: "none",
        drift: 0,
        enable: true,
        gravity: {
          acceleration: 9.81,
          enable: false,
          inverse: false,
          maxSpeed: 50,
        },
        path: {
          clamp: true,
          delay: {
            random: {
              enable: false, import { HttpErrorResponse } from "@angular/common/http";
import { ChangeDetectorRef, Component, Inject, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import {
  NbAuthService,
  NbLoginComponent,
  NB_AUTH_OPTIONS,
} from "@nebular/auth";
import { NbToastrService } from "@nebular/theme";
import { AuthService } from "../auth.service";
import { Container, Main } from "tsparticles-engine";
// import type { Container, Main } from 'tsparticles';

              minimumValue: 0,
            },
            value: 0,
          },
          enable: false,
        },
        outModes: {
          default: "out",
          bottom: "out",
          left: "out",
          right: "out",
          top: "out",
        },
        random: false,
        size: false,
        speed: 4,
        straight: false,
        trail: {
          enable: false,
          length: 10,
          fillColor: {
            value: "#000000",
          },
        },
        vibrate: false,
        warp: false,
      },
      number: {
        density: {
          enable: true,
          area: 800,
          factor: 1000,
        },
        limit: 0,
        value: 16,
      },
      opacity: {
        random: {
          enable: true,
          minimumValue: 0.3,
        },
        value: {
          min: 0.3,
          max: 0.5,
        },
        animation: {
          count: 0,
          enable: false,
          speed: 1,
          sync: false,
          destroy: "none",
          minimumValue: 0.1,
          startValue: "random",
        },
      },
      orbit: {
        animation: {
          count: 0,
          enable: false,
          speed: 1,
          sync: false,
        },
        enable: false,
        opacity: 1,
        rotation: {
          random: {
            enable: false,
            minimumValue: 0,
          },
          value: 45,
        },
        width: 1,
      },
      reduceDuplicates: false,
      repulse: {
        random: {
          enable: false,
          minimumValue: 0,
        },
        value: 0,
        enabled: false,
        distance: 1,
        duration: 1,
        factor: 1,
        speed: 1,
      },
      roll: {
        darken: {
          enable: false,
          value: 0,
        },
        enable: false,
        enlighten: {
          enable: false,
          value: 0,
        },
        speed: 25,
      },
      rotate: {
        random: {
          enable: false,
          minimumValue: 0,
        },
        value: 0,
        animation: {
          enable: false,
          speed: 0,
          sync: false,
        },
        direction: "clockwise",
        path: false,
      },
      shadow: {
        blur: 0,
        color: {
          value: "#000000",
        },
        enable: false,
        offset: {
          x: 0,
          y: 0,
        },
      },
      shape: {
        options: {
          polygon: {
            sides: 5,
          },
          star: {
            sides: 5,
          },
        },
        type: "polygon",
      },
      size: {
        random: {
          enable: true,
          minimumValue: 40,
        },
        value: {
          min: 40,
          max: 60,
        },
        animation: {
          count: 0,
          enable: false,
          speed: 1,
          sync: false,
          destroy: "none",
          minimumValue: 40,
          startValue: "random",
        },
      },
      stroke: {
        width: 0,
      },
      tilt: {
        random: {
          enable: false,
          minimumValue: 0,
        },
        value: 0,
        animation: {
          enable: false,
          speed: 0,
          sync: false,
        },
        direction: "clockwise",
        enable: false,
      },
      twinkle: {
        lines: {
          enable: false,
          frequency: 0.05,
          opacity: 1,
        },
        particles: {
          enable: false,
          frequency: 0.05,
          opacity: 1,
        },
      },
      wobble: {
        distance: 5,
        enable: false,
        speed: 50,
      },
      zIndex: {
        random: {
          enable: false,
          minimumValue: 0,
        },
        value: 0,
        opacityRate: 1,
        sizeRate: 1,
        velocityRate: 1,
      },
    },
    pauseOnBlur: true,
    pauseOnOutsideViewport: true,
    responsive: [],
    themes: [],
  };

  public particlesLoaded(container: Container): void {}
  particlesInit(main: Main): void {
    // Starting from 1.19.0 you can add custom presets or shape here, using the current tsParticles instance (main)
  }
  get authForm() {
    return this.authService.form;
  }

  get formControl() {
    return this.authForm.controls;
  }

  ngOnInit(): void {}

  onSubmitHandler(): void {
    this.loading = true;

    if (this.authForm.invalid) {
      return;
    }

    this.authService.login(this.authForm.value).subscribe(
      (data) => {
        localStorage.setItem("userId", JSON.stringify(data.userId));
        if (data.isPasswordChangedFirstTimeLogin === false) {
          this.loading = false;

          this.router.navigateByUrl("/auth/first-time-password-change");
        } else {
          window.location.reload();
          localStorage.setItem("auth", JSON.stringify(data));
          this.loading = false;

          this.router.navigateByUrl("/dashboard");
        }
      },
      (err: HttpErrorResponse) => {
        if (err.status === 401) {
          this.loading = false;
          this.toastrService.show("Email or password invalid", "Unauthorized", {
            status: "danger",
          });
        }
      }
    );
  }
}
<div class="login-page-container" id="login-page-container">
  <div class="row">
    <div class="col-sm-12 col-md-5 col-lg-5">
      <ng-particles
        [id]="id"
        [options]="particlesOptions"
        (particlesLoaded)="particlesLoaded($event)"
        (particlesInit)="particlesInit($event)"
      ></ng-particles>
    </div>
    <div class="col-sm-12 col-md-7 col-lg-7 login-form">
      <div class="login-container justify-content-center">
        <h1 id="title" class="title">Login</h1>
        <!-- <p class="sub-title">Hello! Log in with your email.</p> -->

        <nb-alert
          *ngIf="showMessages.error && errors?.length && !submitted"
          outline="danger"
          role="alert"
        >
          <p class="alert-title"><b>Oh snap!</b></p>
          <ul class="alert-message-list">
            <li *ngFor="let error of errors" class="alert-message">
              {{ error }}
            </li>
          </ul>
        </nb-alert>

        <nb-alert
          *ngIf="showMessages.success && messages?.length && !submitted"
          outline="success"
          role="alert"
        >
          <p class="alert-title"><b>Hooray!</b></p>
          <ul class="alert-message-list">
            <li *ngFor="let message of messages" class="alert-message">
              {{ message }}
            </li>
          </ul>
        </nb-alert>
       
        <form
          (ngSubmit)="onSubmitHandler()"
          [formGroup]="authForm"
          aria-labelledby="title"
        >
          <div class="form-control-group email-group">
            <label for="email" class="label email-label">Email</label>
            <input
              type="text"
              nbInput
              fullWidth
              id="email"
              placeholder=""
              formControlName="email"
            />
            <ng-container
              *ngIf="
                formControl.email.invalid &&
                (formControl.email.dirty || formControl.email.touched)
              "
            >
              <p
                *ngIf="formControl.email.errors.required"
                class="text-danger mt-2"
              >
                Email field is required
              </p>
              <p
                *ngIf="formControl.email.errors.email"
                class="text-danger mt-2"
              >
                Invalid email
              </p>
            </ng-container>
          </div>

          <div class="form-control-group password-group">
            <label for="password" class="password-label label">Password</label>
            <input
              type="password"
              nbInput
              fullWidth
              id="password"
              placeholder=""
              formControlName="password"
            />
            <ng-container
              *ngIf="
                formControl.password.invalid &&
                (formControl.password.dirty || formControl.password.touched)
              "
            >
              <p
                *ngIf="formControl.password.errors.required"
                class="text-danger mt-2"
              >
                Password field is required
              </p>
            </ng-container>
          </div>
          <div class="row remember-forgot">
            <div class="left-reg col remember-me">         
                <nb-checkbox >Remember me</nb-checkbox>   
              </div>
      
            <div class="right-reg col forgot-pw">Forget Password</div>
          </div>

          <button
            nbButton
            fullWidth 
            status="success"
            [disabled]="!authForm.valid"
            [class.btn-pulse]="submitted"
          >
            Log In
          </button>
        </form>
      </div>
    </div>
  </div>
</div>
<div *ngIf="loading" id="global-spinner" class="spinner">
  <div class="blob blob-0"></div>
  <div class="blob blob-1"></div>
</div> 

earlier we install ng-particles version is ^2.13.4 that time there is no issue occurred

during migration we upgradde to ^3.12.0

even i downgrade the ng-particle version to ^3.9.3 same issue is occurred even replace ng-particle options with document's options as well

package.json

{
...

"dependencies": {
    "@akveo/ng2-completer": "^9.0.1",
    "@angular/animations": "^15.2.9",
    "@angular/cdk": "15.2.9",
    "@angular/common": "^15.2.9",
    "@angular/compiler": "^15.2.9",
    "@angular/core": "^15.2.9",
    "@angular/forms": "^15.2.9",
    "@angular/platform-browser": "^15.2.9",
    "@angular/platform-browser-dynamic": "^15.2.9",
    "@angular/router": "^15.2.9",
    "@nebular/auth": "^9.0.3",
    "@nebular/eva-icons": "^9.0.3",
    "@nebular/security": "^9.0.3",
    "@nebular/theme": "^9.0.3",
    "@yr/monotone-cubic-spline": "^1.0.3",
    "core-js": "^3.32.1",
    "eva-icons": "^1.1.3",
    "intl": "1.2.5",
    "jwt-decode": "^3.1.2",
    "lodash-es": "^4.17.21",
    "luxon": "^3.4.2",
    "nebular-icons": "1.1.0",
    "ng-particles": "^3.9.3",
    "normalize.css": "8.0.1",
    "rxjs": "7.4.0",
    "rxjs-compat": "6.6.7",
    "sass": "^1.66.1",
    "sass-loader": "^13.3.2",
    "style-loader": "^3.3.3",
    "tslib": "^2.6.2",
    "tsparticles-engine": "^2.12.0",
    "zone.js": "~0.13.0",
... rest of dependencies
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^15.2.9",
    "@angular/cli": "^15.2.9",
    "@angular/compiler-cli": "^15.2.9",
    "@angular/language-service": "15.2.9",
    "@compodoc/compodoc": "^1.1.16",
    "@fortawesome/fontawesome-free": "^6.4.2",
    "@types/jasminewd2": "^2.0.10",
    "@types/lodash-es": "^4.17.4",
    "@types/node": "^20.5.7",
    "stylelint": "15.10.3",
    "ts-node": "10.9.1",
    "typescript": "4.9.5",
.. rest of dependencies
  }
}

angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "ngx-admin-demo": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "preserveSymlinks": true,
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "tsConfig": "src/tsconfig.app.json",
            "polyfills": "src/polyfills.ts",
            "assets": [
              "src/assets",
              "src/favicon.ico",
              "src/favicon.png"
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.css",
              "node_modules/typeface-exo/index.css",
              "node_modules/roboto-fontface/css/roboto/roboto-fontface.css",
              "node_modules/@fortawesome/fontawesome-free/css/all.css",
              "node_modules/nebular-icons/scss/nebular-icons.scss",
              "src/app/@theme/styles/styles.scss"
            ],
            "scripts": [
              "node_modules/apexcharts/dist/apexcharts.min.js"
            ],
            "allowedCommonJsDependencies": [
              "lodash",
              "zrender/lib/svg/svg",
              "zrender/lib/vml/vml"
            ],
            "vendorChunk": true,
            "extractLicenses": false,
            "buildOptimizer": false,
            "sourceMap": true,
            "optimization": false,
            "namedChunks": true
          },
          "configurations": {
            "prod": {
              ..configurations,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            },
            "staging": {
               ..configurations,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.stg.ts"
                }
              ]
            }
          },
          "defaultConfiguration": ""
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "ngx-admin-demo:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "ngx-admin-demo:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "ngx-admin-demo:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.css",
              "node_modules/typeface-exo/index.css",
              "node_modules/roboto-fontface/css/roboto/roboto-fontface.css",
              "node_modules/font-awesome/scss/font-awesome.scss",
              "node_modules/nebular-icons/scss/nebular-icons.scss",
              "src/app/@theme/styles/styles.scss"
            ],
           ..configurations
          }
        }
      }
    },
   ..configurations

}

please help me to sort out this issue

AG Mohamed
  • 71
  • 1
  • 9

0 Answers0