.NetCore 2 Angular 5-错误:StaticInjectorError(AppModule)[BASE_URL]:

时间:2018-06-19 13:50:22

标签: angular visual-studio-code .net-core

当我尝试导航到WebApi控制器时出现此错误。该错误是我在页面加载后立即得到的,因为代码位于构造函数中。

core.js:1598 ERROR Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[BASE_URL]: 
  StaticInjectorError(Platform: core)[BASE_URL]: 
    NullInjectorError: No provider for BASE_URL!
Error: StaticInjectorError(AppModule)[BASE_URL]: 
  StaticInjectorError(Platform: core)[BASE_URL]: 
    NullInjectorError: No provider for BASE_URL!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:979)
    at resolveToken (core.js:1232)
    at tryResolveToken (core.js:1182)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1077)
    at resolveToken (core.js:1232)
    at tryResolveToken (core.js:1182)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1077)
    at resolveNgModuleDep (core.js:9217)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:9911)
    at resolveDep (core.js:10276)
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:979)
    at resolveToken (core.js:1232)
    at tryResolveToken (core.js:1182)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1077)
    at resolveToken (core.js:1232)
    at tryResolveToken (core.js:1182)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:1077)
    at resolveNgModuleDep (core.js:9217)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:9911)
    at resolveDep (core.js:10276)
    at resolvePromise (zone.js:814)
    at resolvePromise (zone.js:771)
    at zone.js:873
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4053)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)

login.component.ts

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

import { NgForm } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';

import { Candidates } from '/Solutions/Angular/ExamBuddy/Interfaces/Candidate';


@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})


export class LoginComponent  {
  candDetails: Candidates;

  constructor(private http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    var url = baseUrl + '/api/Candidate/ExamDetails/12345';
    this.http.get<Candidates>(url).subscribe(result => { this.candDetails = result; }, error => console.error(error));
  }

这也是我的app.module.ts代码。

app.module.ts

    import { BrowserModule } from '@angular/platform-browser';

    import { NgModule } from '@angular/core';
    import { HttpClientModule } from '@angular/common/http';
    import { FormsModule } from '@angular/forms';
    import { AppComponent } from './app.component';
    import { ExamComponent } from './exam/exam.component';
    import { LoginComponent } from './login/login.component';
    // import { RouterModule } from '@angular/router';
    import { InstructionComponent } from './instruction/instruction.component';
    import { routes } from './app.route';


    @NgModule({
      declarations: [
        AppComponent,
        ExamComponent,
        LoginComponent,
        InstructionComponent,

      ],
      imports: [
        BrowserModule,
        HttpClientModule,
        FormsModule,
        routes 
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

我还具有WebApi控制器,该控制器连接到数据库并以JSON格式获取结果。

3 个答案:

答案 0 :(得分:2)

您要使用插入装饰器BASE_URLLoginComponent中用键@Inject('BASE_URL') baseUrl: string插入字符串值。为此,您需要在AppModule中为BASE_URL提供一个值。但是您没有提供任何提示,这就是错误告诉您的内容:NullInjectorError: No provider for BASE_URL!

在Angular 5中,建议创建InjectionToken例如

import { InjectionToken } from '@angular/core';
export const BASE_URL = new InjectionToken<string>('BASE_URL');

通过在AppModule中定义一个提供程序来提供AppModule中的值:

providers: [  { provide: BASE_URL , useValue: "http://example.com/api" }

然后您可以像下面这样在LoginLogin中使用这个InjectionToken:

constructor(private http: HttpClient, @Inject(BASE_URL) baseUrl: string) {

有关值注入的更多信息,可以在官方文档中找到:https://angular.io/guide/dependency-injection#dependency-injection-tokens

答案 1 :(得分:2)

第一:在 main.ts 中,我有以下代码,它引用了index.html

export function getBaseUrl() {
  return document.getElementsByTagName('base')[0].href;
}

const providers = [
  { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
];

platformBrowserDynamic(providers).bootstrapModule(AppModule)
  .catch(err => console.log(err));

第二:在我们的组件( fetch-data.component.ts )中,我们通过以下方式使用 BASE_URL

export class FetchDataComponent {
    public forecasts: WeatherForecast[];

    constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
        http.get<WeatherForecast[]>(baseUrl + 'api/SampleData/WeatherForecasts').subscribe(result => {
           this.forecasts = result;
        }, error => console.error(error));
    }
}

就是这样。

答案 2 :(得分:0)

就我而言,我尝试启用热模块更换。 HMR的官方说明针对main.ts提供了以下示例:

Update src/main.ts to use the file we just created:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

import { hmrBootstrap } from './hmr';

if (environment.production) {
  enableProdMode();
}

const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule);

if (environment.hmr) {
  if (module[ 'hot' ]) {
    hmrBootstrap(module, bootstrap);
  } else {
    console.error('HMR is not enabled for webpack-dev-server!');
    console.log('Are you using the --hmr flag for ng serve?');
  }
} else {
  bootstrap().catch(err => console.log(err));
}

https://github.com/angular/angular-cli/wiki/stories-configure-hmr

但是,Visual Studio 2017 ASP.Net Core Angular CLI模板包括以下几行:

const providers = [
  { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
];

platformBrowserDynamic(providers).bootstrapModule(AppModule)
  .catch(err => console.log(err));

请注意,providers数组未传递到HMR main.ts示例中。简单的解决方法是将其简单地传递到platformBrowserDynamic中。校正后的行如下所示:

const providers = [
  { provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
];

const bootstrap = () => platformBrowserDynamic(providers).bootstrapModule(AppModule);