Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot instantiate cyclic dependency! HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule CoreModule

I am using the following dependencies:

package.json:

{
  "name": "myApp",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve --base-href /myapp/",
    "build": "ng build",
    "build-stage": "ng build --environment=stage --aot --prod --vendor-chunk=false --common-chunk=false",
    "build-prod": "ng build --environment=prod --aot --prod --vendor-chunk=false --common-chunk=false",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.2.4",
    "@angular/common": "^4.2.4",
    "@angular/compiler": "^4.2.4",
    "@angular/core": "^4.2.4",
    "@angular/forms": "^4.2.4",
    "@angular/http": "^4.2.4",
    "@angular/platform-browser": "^4.2.4",
    "@angular/platform-browser-dynamic": "^4.2.4",
    "@angular/router": "^4.2.4",
    "@ngx-translate/core": "^7.2.2",
    "@ngx-translate/http-loader": "^1.1.0",
    "bootstrap": "^3.3.7",
    "core-js": "^2.4.1",
    "jquery": "^3.2.1",
    "qrcode": "^1.0.0",
    "rxjs": "^5.4.2",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "1.4.2",
    "@angular/compiler-cli": "^4.2.4",
    "@angular/language-service": "^4.2.4",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "~3.1.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.3.2",
    "typescript": "~2.3.3"
  }
}

cross-domain.service.ts:

import { Injectable, NgZone } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import { environment } from '../../environments/environment';
import { ArticlePreview } from './article.model';

import { TranslateService } from '@ngx-translate/core';

@Injectable()
export class CrossDomainService {
  globalSelectors = new Subject<GlobalSelectors>();
  globalLanguage = new BehaviorSubject<string>('en');
  initialArticlePath: string;
  initialGlobalSelectors: GlobalSelectors;
  private socket;

  constructor(private zone: NgZone,private translateService: TranslateService) {
    translateService.setDefaultLang('en');
  }

  public init() {
    if (this.inIframe) {
      const self = this;
      this.socket = new window['easyXDM'].Socket({
        onMessage(_response) {
          try {
            const response = JSON.parse(_response);
            self.zone.run(() => {
              switch (response.type) {
                case 'tileActionQuery': {
                  if (response.data.action && response.data.action === 'goToArticle') {
                    self.initialArticlePath = response.data.path;
                  }
                  break;
                }
                case 'setGlobalSelectors': {
                  self.initialGlobalSelectors = response.data;
                  self.globalSelectors.next(response.data);
                  break;
                }
                case 'tileInfo': {
                  self.globalLanguage.next(response.data.tileLanguage); 
                  self.translateService.use(response.data.tileLanguage);                
                  break;
                }
              }
            });
          } catch (e) {}
        },
        remote: environment.dashboardSiteUrl
      });
    }
  }          

  private get inIframe () {
    try {
      return window.self !== window.top;
    } catch (e) {
      return true;
    }
  }
}

export interface GlobalSelectors {
  client?: any[];
  jurisdiction?: any[];
  process?: any[];
  year?: any[];
}

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { AnalyticsService, CoreModule, CrossDomainService } from './core';
import { TileModule } from './tile/tile.module';


@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    AppRoutingModule,
    TileModule,
    CoreModule
  ],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: onModuleInit,
      multi: true,
      deps: [CrossDomainService, AnalyticsService]
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

export function onModuleInit(crossDomainService: CrossDomainService, analyticsService: AnalyticsService) {
  return () => {
    crossDomainService.init();
    analyticsService.init();
    return new Promise((resolve) => resolve(true));
  };
}

core.module.ts:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HTTP_INTERCEPTORS, HttpClientModule ,HttpClient } from '@angular/common/http';

import { HttpRequestInterceptor } from './http-request.interceptor';
import { ArticleService } from './article.service';
import { CrossDomainService } from './cross-domain.service';
import { AnalyticsService } from './analytics.service';

import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

export function translateHttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http);
}

@NgModule({
  imports: [
    CommonModule,
    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: translateHttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ],
  providers: [
    ArticleService,
    CrossDomainService,
    AnalyticsService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: HttpRequestInterceptor,
      multi: true
    }
  ]
})
export class CoreModule {}

http-request.interceptor.ts:

import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { CrossDomainService } from './cross-domain.service';


@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {

  language: string = 'en';

  constructor(private crossDomainService: CrossDomainService) {
    crossDomainService.globalLanguage.subscribe((language) => {
      this.language = language;
    });
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const request = req.headers.has('Accept-Language') ?
      req :      
      req.clone({ setHeaders: { 'Accept-Language': this.language } });

    return next.handle(request);
  }
}

on compiling the project I am getting an error:

ERROR in Error: Provider parse errors:
Cannot instantiate cyclic dependency! HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule CoreModule in C:/temp/myApp/src/app/core/core.module.ts@-1:-1
    at NgModuleProviderAnalyzer.parse (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:11699:19)    at NgModuleCompiler.compile (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:18548:36)
    at AotCompiler._compileModule (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:24004:32)
    at C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:23916:66    at Array.forEach (<anonymous>)
    at AotCompiler._compileImplFile (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:23916:19)
    at C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:23829:87
    at Array.map (<anonymous>)
    at AotCompiler.emitAllImpls (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:23829:52)
    at CodeGenerator.emit (C:\temp\myApp\node_modules\@angular\compiler-cli\src\codegen.js:42:46)
    at C:\temp\myApp\node_modules\@angular\compiler-cli\src\codegen.js:33:61
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

Can anyone help me to fix this issue?

like image 655
santosh kumar patro Avatar asked Aug 02 '18 18:08

santosh kumar patro


People also ask

What is cyclic dependency in angular?

A cyclic dependency exists when a dependency of a service directly or indirectly depends on the service itself. For example, if UserService depends on EmployeeService, which also depends on UserService. Angular will have to instantiate EmployeeService to create UserService, which depends on UserService, itself. Debugging the error link

Can I inject httpclient directly into an interceptor?

Previously, an interceptor attempting to inject HttpClient directly would receive a circular dependency error, as HttpClient was constructed via a factory which injected the interceptor instances. Users want to inject HttpClient into interceptors to make supporting requests (ex: to retrieve an authentication token).

What are http interceptors and how to use them in angular?

What Are Http Interceptors And How to Use Them In Angular? Use cases where we can make use of Interceptors in Angular. We have faced multiple scenarios where we might want to globally capture or change every request or response, like append a user’s token or handle errors from the response and we can achieve this using Http Interceptor.

What is httpclient error in angular?

The error may come in either the client-side (browser) or it may be an error from the server-side when the request fails due to any reason. You can learn more about the internal implementation of interceptors in Insider’s guide into interceptors and HttpClient mechanics in Angular.


1 Answers

Try not setting CrossDomainService in constructor but getting in the intercept function

@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {


  constructor(private injector: Injector) {

  }    
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
   // try to call the service here.
    language: string = 'en';
    const lanaguageInj= this.injector.get(CrossDomainService);
    const globalLanguage= auth.globalLanguage.subscribe((language) => {
      this.language = language;
    });

    const request = req.headers.has('Accept-Language') ?
      req :      
      req.clone({ setHeaders: { 'Accept-Language': this.language } });

    return next.handle(request);
  }
}
like image 186
Chellappan வ Avatar answered Oct 17 '22 06:10

Chellappan வ