Угловой не может использовать HttpClient во внешней библиотеке

Когда я пытаюсь создать экземпляр службы HttpClient во внешней библиотеке, затем используйте эту библиотеку в приложении с угловым выражением, я получаю ошибки StaticInjectorError:

С угловым 5.0.0:

AppComponent_Host.ngfactory.js? [sm]:1 ERROR Error:
  StaticInjectorError[InjectionToken DocumentToken]:   
  StaticInjectorError[InjectionToken DocumentToken]: 
     NullInjectorError: No provider for InjectionToken DocumentToken!
     at _NullInjector.get (core.js:993)
     at resolveToken (core.js:1281)
     at tryResolveToken (core.js:1223)
     at StaticInjector.get (core.js:1094)
     at resolveToken (core.js:1281)
     at tryResolveToken (core.js:1223)
     at StaticInjector.get (core.js:1094)
     at resolveNgModuleDep (core.js:10878)
     at _createClass (core.js:10919)
     at _createProviderInstance$1 (core.js:10889)

С Угловым 5.2.0-rc.0:

ERROR Error: StaticInjectorError(AppModule)[HttpXsrfTokenExtractor ->
InjectionToken DocumentToken]:    StaticInjectorError(Platform:
core)[HttpXsrfTokenExtractor -> InjectionToken DocumentToken]: 
    NullInjectorError: No provider for InjectionToken DocumentToken!
    at _NullInjector.get (core.js:994)
    at resolveToken (core.js:1292)
    at tryResolveToken (core.js:1234)
    at StaticInjector.get (core.js:1102)
    at resolveToken (core.js:1292)
    at tryResolveToken (core.js:1234)
    at StaticInjector.get (core.js:1102)
    at resolveNgModuleDep (core.js:10836)
    at _createClass (core.js:10877)
    at _createProviderInstance$1 (core.js:10847)

Я воспроизвел это с помощью пустого приложения @angular/cli импортирующего пустое библиотечное семя из стартера с угловой библиотекой, который просто импортирует и пытается использовать HttpClient:

(для краткости сокращены строки импорта)

Приложение: app.module.ts:

@NgModule({
  declarations: [ AppComponent ],
  imports: [ ..., ArithmeticModule.forRoot() ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

Приложение: app.component.ts:

@Component({
  ...
})
export class AppComponent {
  constructor(private sum: SumService) {}
}

Для библиотеки все, что я сделал, это импортировать HttpClientModule в библиотечный модуль, а затем попытаться ввести ее в SumService:

Библиотека: arithmetic.module.ts:

@NgModule({
    imports: [ HttpClientModule ]
})
export class ArithmeticModule {
    public static forRoot(): ModuleWithProviders {
        return {
            ngModule: ArithmeticModule,
            providers: [ SumService ]
        };
    }
}

Библиотека: sum.service.ts:

@Injectable()
export class SumService {
  constructor(private http: HttpClient) {}
  ....
}

Эта настройка вызывает ошибки StaticInjectorError упомянутые в верхней части сообщения.

  • В configup rollup я добавил @angular/common/http ng.common.http @angular/common/http/ng.common.http как внешний/глобальный.
  • Я пробовал это с множеством различных настроек, семенами библиотеки, с rollup и с webpack. Все это приводит к тому же вопросу.

Есть идеи?

Ответ 1

Я столкнулся с подобной проблемой и исправил обновление NgxMaskModule (2.2.2) и добавил NgxMaskModule.forRoot() в модуле import.

Ответ 2

Не уверен, что погода будет работать в вашем случае или нет, но вы можете использовать рефлексию вместо инъекции зависимости в своем sum service для httpclient что-то вроде вашего sum.service.ts

   import {  HttpClient, HttpClientModule } from '@angular/common/http';
   declare let Reflect: any;
 @Injectable()
export class SumService {
   http: HttpClient;
   constructor() {
    var injector = ReflectiveInjector.resolveAndCreate(this.getAnnotations(HttpClientModule)[0].providers);
    this.http = injector.get(HttpClient);
  }
 getAnnotations(typeOrFunc: Type<any>): any[]{
    // Prefer the direct API.
    if ((<any>typeOrFunc).annotations) {
      let annotations = (<any>typeOrFunc).annotations;
      if (typeof annotations === 'function' && annotations.annotations) {
        annotations = annotations.annotations;
      }
      return annotations;
    }

    // API of tsickle for lowering decorators to properties on the class.
    if ((<any>typeOrFunc).decorators) {
      return this.convertTsickleDecoratorIntoMetadata((<any>typeOrFunc).decorators);
    }

    // API for metadata created by invoking the decorators.
    if (Reflect && Reflect.getOwnMetadata) {
      return Reflect.getOwnMetadata('annotations', typeOrFunc);
    }
    return [];
  }
  convertTsickleDecoratorIntoMetadata(decoratorInvocations: any[]): any[] {
    if (!decoratorInvocations) {
      return [];
    }
    return decoratorInvocations.map(decoratorInvocation => {
      const decoratorType = decoratorInvocation.type;
      const annotationCls = decoratorType.annotationCls;
      const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
      return new annotationCls(...annotationArgs);
    });
  }

Ответ 3

Попробуйте импортировать модуль HttpClient в свой app.module.ts.

HttpClientModule будет вашей равноправной зависимостью в этом случае,

поэтому вам нужно импортировать HttpClientModule в основное приложение.

Ответ 4

мы используем HttpClient для перевода модуля. Я использую импорт, как показано ниже;

// translate
HttpClientModule,
TranslateModule.forRoot({
       loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
        }
    }),

Ответ 5

StaticInjectorError

Попробуйте импортировать модуль HttpClient в module.ts и добавить службу к провайдерам.

Ответ 7

То, как вы потребляете sum.service - это просто подмодуль основного модуля, который является вашим app.module.ts. HttpClientModule необходимо будет импортировать в app.module.ts для использования любым субмодулем.

Причина, по которой вы не получите ошибку в AOT, заключается в том, что в этом смысле есть другой инжектор.

В app.module.ts

@NgModule({
  imports: [ HttpClientModule ]
})