-1

I am new to Angular and refer to the below questions, but there isn't any solution for my case.

I am getting the below error while routing and navigating.

  NullInjectorError: No provider for MatDialogRef!
NullInjectorError: R3InjectorError(UserModule)[MatDialogRef -> MatDialogRef -> MatDialogRef -> MatDialogRef]:
  NullInjectorError: No provider for MatDialogRef!
    at NullInjector.get (core.js:1013:1)
    at R3Injector.get (core.js:11130:1)
    at R3Injector.get (core.js:11130:1)
    at R3Injector.get (core.js:11130:1)
    at NgModuleRef$1.get (core.js:24252:1)
    at R3Injector.get (core.js:11130:1)
    at NgModuleRef$1.get (core.js:24252:1)
    at Object.get (core.js:23956:1)
    at getOrCreateInjectable (core.js:4169:1)
    at Module.ɵɵdirectiveInject (core.js:14660:1)
    at resolvePromise (zone-evergreen.js:798:1)
    at resolvePromise (zone-evergreen.js:750:1)
    at zone-evergreen.js:860:1
    at ZoneDelegate.invokeTask (zone-evergreen.js:399:1)
    at Object.onInvokeTask (core.js:27483:1)
    at ZoneDelegate.invokeTask (zone-evergreen.js:398:1)
    at Zone.runTask (zone-evergreen.js:167:1)
    at drainMicroTaskQueue (zone-evergreen.js:569:1)
    at invokeTask (zone-evergreen.js:484:1)
    at ZoneTask.invoke (zone-evergreen.js:469:1)

File app.routing.module.ts

import { NgModule } from "@angular/core";
import { Routes, RouterModule, PreloadAllModules } from "@angular/router";
import { LocationStrategy, HashLocationStrategy } from "@angular/common";
import { AuthGuard } from "./guard/auth.guard";
import { RouterDeactivateService } from "./services/router-deactivate.service";
import { ChangePasswordComponent } from './user/change-password/change-password.component';
/*Main Routing module wise with security check, we have written security check
under DI [AuthGuard], if user is log in then they may move from one module to another module.
*/

export const APP_ROUTES: Routes = [
  {
    path: "",
    children: [
      { path: "", loadChildren: () => import('./user/user.module').then(m => m.UserModule) },
      {
        path: "customer",
        canActivate: [AuthGuard],
        loadChildren: () => import('./customer/customer.module').then(m => m.CustomerModule)
      },
      {
        path: "report",
        canActivate: [AuthGuard],
        loadChildren: () => import('./report/report.module').then(m => m.ReportModule)
      },
      {
        path: "policy",
        canActivate: [AuthGuard],
        canDeactivate: [RouterDeactivateService],
        loadChildren: () => import('./policy/policy.module').then(m => m.PolicyModule)
      },
      {
        path: "claim",
        canActivate: [AuthGuard],
        loadChildren: () => import('./claim/claim.module').then(m => m.ClaimModule)
      },
      {
        path: "mainClaim",
        canActivate: [AuthGuard],
        loadChildren: () => import('./mainClaim/mainClaim.module').then(m => m.MainClaimModule)
      },
      {
        path: "admin",
        canActivate: [AuthGuard],
        loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
      },
      {
        path: "general-report",
        canActivate: [AuthGuard],
        loadChildren:
          () => import('./general-module/general-module.module').then(m => m.GeneralModuleModule)
      },
      {
        path: "products",
        canActivate: [AuthGuard],
        loadChildren: () => import('./products/products.module').then(m => m.ProductsModule)
      }
    ]
  }
];

@NgModule({
  imports: [
    RouterModule.forRoot(APP_ROUTES, {
      enableTracing: false,
      preloadingStrategy: PreloadAllModules
    })
  ],
  exports: [RouterModule],
  providers: [{ provide: LocationStrategy, useClass: HashLocationStrategy }]
})
export class AppRoutingModule {}

File app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app.routing.module';
import { AuthGuard } from './guard/auth.guard';
import { RouterDeactivateService } from './services/router-deactivate.service';
import { DataSharingService } from './shared/services/dataSharing.service';
import { HttpClientModule } from '@angular/common/http';
import { AuthheaderService } from './shared/services/auth-header.service';
import { UploadDocumentService } from './claim/upload-document/upload-document.service';
import { ToastrModule } from 'ngx-toastr';

@NgModule({
  declarations: [
    AppComponent

  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutingModule,
    HttpClientModule,
    ToastrModule.forRoot({
      positionClass: 'toast-bottom-right'
    })
  ],
  providers: [
    AuthGuard,
    RouterDeactivateService,
    DataSharingService,
    AuthheaderService,
    UploadDocumentService
  ],
  bootstrap: [
    AppComponent
  ]
})
export class AppModule { }

File user.routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from "./login/login.component";
import { ChangePasswordComponent } from './change-password/change-password.component';
import { ForgotPasswordComponent } from './forgot-password/forgot-password.component';

const USER_ROUTES: Routes = [
  { path: '', component: LoginComponent },
  { path: 'changePassword', component: ChangePasswordComponent },
  { path: 'forgotPassword', component: ChangePasswordComponent },
  ];

@NgModule({
    imports: [RouterModule.forChild(USER_ROUTES)],
    exports: [RouterModule]
})

export class UserRoutingModule { }
export const routingComponent = [ChangePasswordComponent, ForgotPasswordComponent, LoginComponent]

File user.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from "@angular/router";
import { HttpClientModule } from '@angular/common/http';
import { UserRoutingModule, routingComponent } from "./user.routing.module";
import { NgxSpinnerModule } from 'ngx-spinner';
import { MatDialogModule } from "@angular/material/dialog";
import { MatPasswordStrengthModule } from '@angular-material-extensions/password-strength';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatSelectModule } from '@angular/material/select';
import { MatCardModule } from '@angular/material/card';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { FlexLayoutModule } from '@angular/flex-layout';

import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { LoginService } from "./user.service";
@NgModule({
  imports: [
    CommonModule,
    RouterModule,
    UserRoutingModule,
    HttpClientModule,
    MatButtonModule,
    MatCheckboxModule,
    MatCardModule,
    MatFormFieldModule,
    MatSelectModule,
    MatInputModule,
    MatIconModule,
    FormsModule,
    MatProgressSpinnerModule,
    ReactiveFormsModule,
    NgxSpinnerModule,
    MatDialogModule,
    FlexLayoutModule,
    MatPasswordStrengthModule
  ],
  entryComponents: [
    routingComponent
  ],
  declarations: [
    routingComponent
  ],
  providers: [
    LoginService
  ]
})
export class UserModule { }

File package.json

{
  "name": "<xyz>",
  "version": "0.0.0",
  "license": "<xqw>",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "10.2.1",
    "@angular/cdk": "^10.2.6",
    "@angular/common": "10.2.1",
    "@angular/compiler": "10.2.1",
    "@angular/core": "10.2.1",
    "@angular/flex-layout": "^10.0.0-beta.32",
    "@angular/forms": "10.2.1",
    "@angular/material": "^10.2.6",
    "@angular/platform-browser": "10.2.1",
    "@angular/platform-browser-dynamic": "10.2.1",
    "@angular/router": "10.2.1",
    "@ngui/datetime-picker": "^0.16.2",
    "@angular-material-extensions/password-strength": "^7.0.0",
    "angular7-csv": "^0.2.12",
    "classlist.js": "^1.1.20150312",
    "core-js": "^2.6.11",
    "hammerjs": "^2.0.8",
    "less": "^3.12.2",
    "moment": "^2.29.1",
    "ng-pick-datetime": "^7.0.0",
    "ng2-eonasdan-datetimepicker": "^0.1.4",
    "ngx-date-time-picker": "^1.1.6",
    "ngx-order-pipe": "^2.1.1",
    "ngx-pagination": "^5.0.0",
    "ngx-spinner": "^10.0.1",
    "ngx-uploader-directive": "^1.2.5",
    "rxjs": "^6.6.3",
    "scss": "^0.2.4",
    "tslib": "^2.0.0",
    "web-animations-js": "^2.3.2",
    "zone.js": "^0.10.3",
    "ngx-toastr": "^13.2.1"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1002.0",
    "@angular/cli": "10.2.0",
    "@angular/compiler-cli": "10.2.1",
    "@angular/language-service": "10.2.1",
    "@types/jasmine": "~3.6.0",
    "@types/jasminewd2": "~2.0.8",
    "@types/node": "^12.19.3",
    "codelyzer": "^5.1.2",
    "https-proxy-agent": "^5.0.0",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.0.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "node-sass": "^4.14.1",
    "protractor": "~7.0.0",
    "ts-node": "~9.0.0",
    "tslint": "~6.1.0",
    "typescript": "4.0.5"
  }
}

I am using both this.router.navigate(['changePassword']); or this.router.navigateByUrl('/changePassword');, but none are navigating.

Below is the structure of my code

Structure Image 1

Structure Image 2

Update part of question

Now the injection error is resolved, but I am still not able to navigate to the changePassword component.

Chris Barr
  • 29,851
  • 23
  • 95
  • 135
ankit
  • 2,591
  • 2
  • 29
  • 54

3 Answers3

0

Have you added import { Router} from '@angular/router'; and added this inside the

constructor (private router: Router) {

}

?

The components TypeScript file that you want to navigate into changepassword component.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
zarul
  • 1
  • 1
    I want to navigate from loginComponent to change password component. router available in login component Do i need to add router in change password component? – ankit Jul 21 '23 at 08:37
0

If the Angular child routing works fine when you add the .navigate code in a click handler, but it doesn't work when placed in an API success callback, it's likely due to a timing issue.

When you navigate to a different route using .navigate in an API success callback, Angular might be in the process of updating the view or performing other asynchronous tasks. If the navigation code is triggered within a callback before Angular finishes its current digest cycle, it could lead to unexpected behavior.

To ensure that the navigation code in the API success callback works consistently, you can use Angular's NgZone service. The NgZone service allows you to run code in a specific zone, and it can help avoid issues related to asynchronous execution.

Here's how you can modify your code to use NgZone:

Inject the NgZone service into your component:

import { Component, NgZone } from '@angular/core';

@Component({
  // component configuration
})
export class YourComponent {
  constructor(private ngZone: NgZone) {}

  // Other component methods and properties
}

Use ngZone.run() to run the navigation code within the NgZone:

import { Component, NgZone } from '@angular/core';
import { YourAPIService } from 'path/to/your-api.service';
import { Router } from '@angular/router';

@Component({
  // component configuration
})
export class YourComponent {
  constructor(private ngZone: NgZone, private apiService: YourAPIService, private router: Router) {}

  // Your API call method
  makeAPICall() {
    this.apiService.makeAPIRequest().subscribe(
      (response) => {
        // Your API success callback
        // Run the navigation code within NgZone
        this.ngZone.run(() => {
          this.router.navigate(['/your-child-route']);
        });
      },
      (error) => {
        // Your error handling code
      }
    );
  }
}

By using ngZone.run(), the navigation code will be executed within the Angular zone, ensuring that it's properly handled within the context of the application and the navigation works consistently.

Keep in mind that the NgZone service is a powerful tool to handle asynchronous code within Angular. However, it should be used judiciously and only when necessary, as it can have performance implications if overused. In most cases, Angular's change detection should take care of updating the view appropriately.

Jay Shukla
  • 5,794
  • 8
  • 33
  • 63
  • Welcome back to Stack Overflow, Jay Shukla. It looks like it's been a while since you've posted and may not be aware of the latest policies since your answer appears likely to have been entirely or partially written by AI (e.g., ChatGPT). As a heads-up, [posting of AI-generated content is not permitted on Stack Overflow](//meta.stackoverflow.com/q/421831). If you used an AI tool to assist with any answer, I would encourage you to delete it. We do hope you'll stick around and continue to be a valuable part of our community by posting *your own* quality content. Thanks! – NotTheDr01ds Jul 23 '23 at 17:46
  • **Readers should review this answer carefully and critically, as AI-generated information often contains fundamental errors and misinformation.** If you observe quality issues and/or have reason to believe that this answer was generated by AI, please leave feedback accordingly. – NotTheDr01ds Jul 23 '23 at 17:46
0

You are using Observable which can create an issue in navigating to the component. You can create a new method which finalizes or promises to respond when your subscribe ends successfully. So in the below code, you can use that in your case:

logout() {
    new Promise((resolve, reject) => {
        this.http.delete(this.baseUrl + url, { headers: this.headers() })
            .map((res: IResponse) => {
              var json = res.json();
              json.headers = res.headers;
              return json;
            })
            .subscribe(data => {
              //DO SOMETHING, THEN ----
              resolve(data);
            }, error => reject(error));
    }).then(response => this.router.navigate(['LandingPage']));
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sonu
  • 79
  • 5