首页 > 解决方案 > NullInjectorError:没有函数()的提供者{}!

问题描述

这是我在没有 CLI 和调试的情况下在 Angular 7 项目中设置自定义 AOT 多个小时后的最后手段,我得到了

Uncaught Error: StaticInjectorError(Platform: core)[function(){}]: 
  NullInjectorError: No provider for function(){}!
    at t.get (injector.ts:43)
    at injector.ts:346
    at Xa (injector.ts:288)
    at t.get (injector.ts:168)
    at Cp (application_ref.ts:41)
    at t.bootstrapModule (application_ref.ts:262)
    at Object.<anonymous> (main-aot.ts:14)
    at n (bootstrap:19)
    at bootstrap:83
    at bootstrap:83

这是我的 app.module.ts

import { AppComponent } from './app.component';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { InlineSVGModule } from 'ng-inline-svg';
import { APP_BASE_HREF } from '@angular/common';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { FeatureRoutingModule } from './app-routing.module';
/**
 * Core
 */
import { HeaderComponent } from './core/header/header.component';
import { AppSettingsComponent } from './core/header/app-settings/app-settings.component';
import { SidebarComponent } from './core/sidebar/sidebar.component';
import { PreloaderComponent } from './core/preloader/preloader.component';
import { TranslationLoader } from './services/translation.service';
/**
 * Shared
 */
import { PopupsDirective } from './shared/popups/popups.directive';
/**
 * Component
 */
import { StructureComponent } from './component/structure/structure.component';
import { OverviewComponent } from './component/overview/overview.component';
import { MainContentComponent } from './component/main-content/main-content.component';
import { NavigationStripeComponent } from './component/main-content/navigation-stripe/navigation-stripe.component';
import { TestDirective } from './component/tooltip/serviceCalls.directive';
import { TooltipService } from './component/tooltip/tooltip.service';
import { TooltipComponent } from './component/tooltip/tooltip.component';

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslationLoader(http);
}

@NgModule({
  // rendering in browser environment
  imports: [
    BrowserModule,
    FeatureRoutingModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: (HttpLoaderFactory),
        deps: [HttpClient]
      }
    }),
    InlineSVGModule.forRoot(),
    HttpClientModule
  ],
  // register services at root level
  providers: [
    TooltipService,
    { provide: APP_BASE_HREF, useValue: `${window['_app_base']}/` || '/' }
  ],
  // components declarations
  declarations: [
    AppComponent,
    HeaderComponent,
    AppSettingsComponent,
    SidebarComponent,
    PreloaderComponent,
    StructureComponent,
    OverviewComponent,
    MainContentComponent,
    TestDirective,
    TooltipComponent,
    PreloaderComponent,
    PopupsDirective,
    NavigationStripeComponent
  ],
  // bootstrap component
  bootstrap: [AppComponent]
})
export class AppModule {
}

这是我的组件

import { Component, OnInit } from '@angular/core';
import { AppService } from './services/app.service';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'kpi-main',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  theme: string;
  sidebarPref: object = {};
  stickyHeader: string = '';
  user: object = {};

  constructor (private appService: AppService, private translate: TranslateService) {
    // this language will be used as a fallback when a translation isn't found in the current language
    translate.setDefaultLang('en');
     // the lang to use, if the lang isn't available, it will use the current loader to get them
    translate.use('en');
  }

  ngOnInit(): void {
    this.appService.getLayoutPreferences().subscribe(layout => {
      this.theme = layout.theme.value;
      this.sidebarPref = layout.sidebar_small;
      this.stickyHeader = layout.stickyHeader.visible;
      this.user = layout.sidebar_small.user;
    });
  }
}

我的服务是

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Response } from '@angular/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AppService {
  theme: string = '';

  constructor (private http: HttpClient) { }

  setSidebarPref(obj: object): Observable<any> {
    return this.http.put('../api/v1.0/users/me/preferences', { 'batch' : obj }, { withCredentials: true } );
  }

  getUserImage(): Observable<any> {
    return this.http.get('../api/v1.0/users/me/image', { responseType: 'blob', withCredentials: true });
  }

  getLayoutPreferences(): Observable<any> {
    return this.http.get('../api/v1.0/properties/layout', { withCredentials: true });
  }

  handleError(error: Response) {
    console.log(error);
    return Observable.throw(error.json().error || 'Server error');
  }
}

我的应用程序上的代码我收到了您在问题顶部的链接中看到的 Null-injector 异常。并且仅在生产模式下运行时才会引发此错误(我已禁用 UglifyJsPlugin 以获得更好的错误消息,但仍不清楚出了什么问题)

有人可以告诉我为了成功进行服务配置,我的文件中缺少什么吗?

PS:如果您需要其他文件来检查,请告诉我。

更新 经过一番搜索,我发现问题出在我的 main-aot.ts 文件中,并且是 ngfactory 的创建方式。那是我的新起点,这是文件

import 'core-js/es7/reflect';
import 'zone.js/dist/zone';

import { platformBrowser } from '@angular/platform-browser';
import { AppModule } from './app/app.module';

/**
 * Enable production mode. Disable Angular's development mode, which turns off assertions and other
 * checks within the framework.
 */
import { enableProdMode } from '@angular/core';

// enable production mode and thus disable debugging information
enableProdMode();

platformBrowser().bootstrapModule(<any>AppModule)
  .catch(err => console.error(err));

标签: angulartypescriptdependency-injection

解决方案


在您的TranslateModule导入中,您传递的是括号(可能是一个函数)而不是一个类loader.useFactory

TranslateModule.forRoot({
  loader: {
    provide: TranslateLoader,
    // useFactory: (HttpLoaderFactory), <- Here
    useFactory: HttpLoaderFactory,
    deps: [HttpClient]
  }
}),
// ...

推荐阅读