Нет провайдера для HttpClient
Проблема: Ошибка при обновлении Angular с 4.4 до 5.0
Я обновил свой проект с Angular 4.4 до 5.0 и заменил все вхождения HttpModule
и Http
на HttpClientModule
. После этого начал получать следующую ошибку:
Я также добавил HttpModule
в проект снова, чтобы убедиться, что это не связано с зависимостями, но это не решило проблему.
В файле app.module.ts
у меня всё настроено корректно:
import { HttpModule } from '@angular/http';
import { HttpClientModule, HttpClient } from '@angular/common/http';
.
.
.
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
HttpModule,
BrowserAnimationsModule,
FormsModule,
AppRoutingModule,
.
.
.
],
.
.
.
})
Я не понимаю, откуда берётся эта ошибка и не знаю, как её исправить. У меня также есть предупреждение, которое, возможно, связано с этой проблемой:
Error: StaticInjectorError[HttpClient]:
StaticInjectorError[HttpClient]:
NullInjectorError: No provider for HttpClient!
at _NullInjector.get (...)
Предупреждение:
./node_modules/@angular/Common/esm5/http.js
There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
...
Текущая ошибка:
StaticInjectorError[HttpClient]: StaticInjectorError[HttpClient]: NullInjectorError: No provider for HttpClient!
Сведения о версии:
- Angular версии: 5.0.0 и 5.0.1 (также 5.1 beta)
- Браузеры: все
- Node версия: 8.5.0
- Платформа: Windows
package.json:
{
"dependencies": {
"@angular/common": "^5.1.0-beta.0",
...
"@angular/http": "^5.1.0-beta.0",
...
}
}
Конфигурация Webpack:
У меня две конфигурации Webpack: webpack.config.js
и webpack.config.vendor.js
. Не вижу, что там могло бы повлиять на возникновение данной проблемы.
Если у кого-то есть идеи по поводу того, как исправить ситуацию, буду признателен за помощь!
5 ответ(ов)
Чтобы решить эту проблему, HttpClient
является механизмом Angular для общения с удалённым сервером через HTTP.
Чтобы сделать HttpClient
доступным везде в приложении, выполните следующие шаги:
Откройте корневой модуль
AppModule
.Импортируйте
HttpClientModule
из@angular/common/http
:import { HttpClientModule } from '@angular/common/http';
Добавьте его в массив
@NgModule.imports
:imports: [HttpClientModule,]
Теперь HttpClient
будет доступен для использования в вашем приложении.
Вы не предоставили провайдеры в вашем модуле. В коде, который вы представили, используется HttpClientModule
, но он должен быть в массиве providers
, как это показано ниже. Однако, на самом деле, HttpClientModule
не нужно добавлять в providers
, так как он уже является модулем, который предоставляет HttpClient
:
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
BrowserAnimationsModule,
FormsModule,
AppRoutingModule
],
// Уберите HttpClientModule из массива providers
providers: [ /* Ваши сервисы */ ]
// ...
})
export class MyModule { /* ... */ }
Использование HttpClient в тестах
Если вы получаете ошибку "No provider for HttpClient" при запуске ng test
, вам нужно добавить HttpClientTestingModule
в конфигурацию TestBed
:
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { HttpClient } from '@angular/common/http';
describe('Тестирование HttpClient', () => {
let httpClient: HttpClient;
let httpTestingController: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ HttpClientTestingModule ]
});
// Внедряем http сервис и тестовый контроллер для каждого теста
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
});
it('работает', () => {
// Ваш тест
});
});
Убедитесь, что вы добавили HttpClientTestingModule
в imports
, чтобы избежать ошибок при тестировании.
С недавними изменениями в Angular (Angular 17) больше нет файла app.module. Теперь вам нужно обновить конфигурацию в файле app.config и добавить provideHttpClient(). Вот пример кода:
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
import { provideRouter, withHashLocation } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withHashLocation()),
provideHttpClient()
]
};
Если вам нужно добавить интерсептор для аутентификации, вы можете сделать это следующим образом:
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideRouter, withHashLocation } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes, withHashLocation()),
provideHttpClient(withInterceptors([authenticationInterceptor]))
]
};
Интерсептор можно объявить так:
import { HttpHandlerFn, HttpInterceptorFn, HttpRequest } from "@angular/common/http";
export const authenticationInterceptor: HttpInterceptorFn = (req: HttpRequest<unknown>, next: HttpHandlerFn) => {
const modifiedReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${sessionStorage.getItem('token')}`),
});
return next(modifiedReq);
};
Таким образом, вы можете настроить использование HTTP-клиента и настроить интерсепторы в новом формате конфигурации приложения в Angular 17.
Вы получаете ошибку для HttpClient, потому что не хватает модуля HttpClientModule.
Вам следует импортировать его в файл app.module.ts следующим образом:
import { HttpClientModule } from '@angular/common/http';
И укажите его в декораторе NgModule следующим образом:
@NgModule({
...
imports: [ HttpClientModule ]
...
})
Если это не поможет, попробуйте очистить куки браузера и перезапустить сервер. Надеюсь, это сработает, у меня была такая же проблема.
Чтобы использовать HttpClient
в вашем приложении Angular, просто добавьте HttpClientModule
в массив imports
файла app.module.ts
.
Пример кода:
...
import { HttpClientModule } from '@angular/common/http'; // добавьте эту строку
@NgModule({
declarations: [
AppComponent,
HeaderComponent
],
imports: [
BrowserModule,
HttpClientModule, // добавьте эту строку
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
После этого вы сможете использовать HttpClient
в вашем проекте через внедрение зависимостей в конструктор:
import { HttpClient } from '@angular/common/http';
export class Services {
constructor(private http: HttpClient) {}
}
Теперь вы готовы использовать HttpClient
для работы с HTTP-запросами в вашем приложении!
Как выбрать элемент в шаблоне компонента?
Как явно задать новое свойство у `window` в TypeScript?
Angular: условный класс с *ngClass
Возможно ли использование функций с строгой типизацией в качестве параметров в TypeScript?
Как запустить файлы TypeScript из командной строки?