628 votes

Pas de fournisseur pour HttpClient

Après la mise à jour d'angular 4.4 vers 5.0 et après avoir mis à jour tous les HttpModule et Http vers HttpClientModule, j'ai commencé à obtenir cette erreur.

J'ai également ajouté HttpModule à nouveau pour être sûr que ce n'est pas dû à une dépendance, mais cela ne résout pas le problème.

Dans le module de l'application, tout est correctement configuré.

    import { HttpModule } from '@angular/http';
    import { HttpClientModule, HttpClient } from '@angular/common/http';
    .
    .
    .
    @NgModule({
        imports: [
            BrowserModule,
            HttpClientModule,
            HttpModule,
            BrowserAnimationsModule,
            FormsModule,
            AppRoutingModule,
    .
    .
    .

Je ne sais pas d'où vient cette erreur, ou je n'ai aucune idée de la façon de la supprimer. J'ai aussi un message d'avertissement (que je mets aussi ci-dessous) qui est peut-être lié.

    Error: StaticInjectorError[HttpClient]: 
      StaticInjectorError[HttpClient]: 
        NullInjectorError: No provider for HttpClient!
        at _NullInjector.get (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:5665)
        at resolveToken (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:5953)
        at tryResolveToken (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:5895)
        at StaticInjector.get (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:5766)
        at resolveToken (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:5953)
        at tryResolveToken (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:5895)
        at StaticInjector.get (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:5766)
        at resolveNgModuleDep (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:15328)
        at _createClass (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:15373)
        at _createProviderInstance$1 (vendor.js?v=mekBM8IVBK72-MIZOVSTJizGi_TD_xK3uhPOCRlEHwg:15339)

Message d'avertissement :

    ./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.
    Use equal casing. Compare these module identifiers:
    * D:\XXX\node_modules\@angular\Common\esm5\http.js
        Used by 21 module(s), i. e.
        D:\XXX\node_modules\awesome-typescript-loader\dist\entry.js?silent=true!D:\XXX\node_modules\angular2-template-loader\index.js!D:\XXX\ClientApp\app\services\notification-endpoint.service.ts
    * D:\XXX\node_modules\@angular\common\esm5\http.js
        Used by 1 module(s), i. e.
        D:\XXX\node_modules\awesome-typescript-loader\dist\entry.js?silent=true!D:\XXX\node_modules\angular2-template-loader\index.js!D:\XXX\ClientApp\app\app.module.ts
     @ ./node_modules/@angular/Common/esm5/http.js
     @ ./ClientApp/app/services/notification-endpoint.service.ts
     @ ./ClientApp/app/app.module.ts
     @ ./ClientApp/boot.browser.ts
     @ multi event-source-polyfill webpack-hot-middleware/client?path=__webpack_hmr&dynamicPublicPath=true ./ClientApp/boot.browser.ts

Comportement actuel

StaticInjectorError[HttpClient]: StaticInjectorError[HttpClient]: NullInjectorError: No provider for HttpClient!

Environnement

Angular version: 5.0.0 and 5.0.1 (also 5.1 beta)

Browser:
- all

For Tooling issues:
- Node version: 8.5.0
- Platform:  windows

    {
      "name": "X",
      "version": "1.0.0",
      "description": "X",
      "author": {
        "name": "X X",
        "email": "XX",
        "url": "X"
      },
      "homepage": "X",
      "dependencies": {
        "@angular/animations": "^5.1.0-beta.0",
        "@angular/common": "^5.1.0-beta.0",
        "@angular/compiler": "^5.1.0-beta.0",
        "@angular/compiler-cli": "^5.1.0-beta.0",
        "@angular/core": "^5.1.0-beta.0",
        "@angular/forms": "^5.1.0-beta.0",
        "@angular/http": "^5.1.0-beta.0",
        "@angular/platform-browser": "^5.1.0-beta.0",
        "@angular/platform-browser-dynamic": "^5.1.0-beta.0",
        "@angular/platform-server": "^5.1.0-beta.0",
        "@angular/router": "^5.1.0-beta.0",
        "@ngtools/webpack": "^1.8.0",
        "@ngx-translate/core": "^8.0.0",
        "@ngx-translate/http-loader": "^2.0.0",
        "@swimlane/ngx-datatable": "^11.0.3",
        "@types/jquery": "^3.2.16",
        "@types/webpack-env": "^1.13.2",
        "angular2-template-loader": "^0.6.2",
        "aspnet-webpack": "^2.0.1",
        "awesome-typescript-loader": "^3.3.0",
        "bootstrap": "^3.3.7",
        "bootstrap-datepicker": "^1.7.1",
        "bootstrap-select": "^1.12.4",
        "bootstrap-toggle": "^2.2.2",
        "bootstrap-vertical-tabs": "^1.2.2",
        "chart.js": "^2.7.1",
        "core-js": "^2.5.1",
        "css": "^2.2.1",
        "css-loader": "^0.28.7",
        "event-source-polyfill": "^0.0.11",
        "expose-loader": "^0.7.3",
        "extract-text-webpack-plugin": "^3.0.2",
        "file-loader": "^1.1.5",
        "font-awesome": "^4.7.0",
        "html-loader": "^0.5.1",
        "jquery": "^3.2.1",
        "json-loader": "^0.5.7",
        "ng2-charts": "^1.6.0",
        "ng2-toasty": "^4.0.3",
        "ngx-bootstrap": "^2.0.0-beta.8",
        "node-sass": "^4.6.0",
        "popper.js": "^1.12.6",
        "raw-loader": "^0.5.1",
        "rxjs": "^5.5.2",
        "sass-loader": "^6.0.6",
        "style-loader": "^0.19.0",
        "to-string-loader": "^1.1.5",
        "typescript": "^2.6.1",
        "url-loader": "^0.6.2",
        "web-animations-js": "^2.3.1",
        "webpack": "^3.8.1",
        "webpack-hot-middleware": "^2.20.0",
        "webpack-merge": "^4.1.1",
        "zone.js": "^0.8.18"
      },
      "devDependencies": {
        "@types/chai": "^4.0.4",
        "@types/jasmine": "^2.6.3",
        "chai": "^4.1.2",
        "jasmine-core": "^2.8.0",
        "karma": "^1.7.1",
        "karma-chai": "^0.1.0",
        "karma-chrome-launcher": "^2.2.0",
        "karma-cli": "^1.0.1",
        "karma-jasmine": "^1.1.0",
        "karma-jasmine-html-reporter": "^0.2.2",
        "karma-webpack": "^2.0.5"
      },
      "scripts": {
        "dev-build": "node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js",
        "test": "karma start ClientApp/test/karma.conf.js"
      }
    }

webpack.config.js

    const path = require('path');
    const webpack = require('webpack');
    const merge = require('webpack-merge');
    const AotPlugin = require('@ngtools/webpack').AotPlugin;
    const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;

    module.exports = (env) => {
        // Configuration in common to both client-side and server-side bundles
        const isDevBuild = !(env && env.prod);
        const sharedConfig = {
            stats: { modules: false },
            context: __dirname,
            resolve: { extensions: ['.js', '.ts'] },
            output: {
                filename: '[name].js',
                publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
            },
            module: {
                rules: [
                    { test: /\.ts$/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] : '@ngtools/webpack' },
                    { test: /\.html$/, use: 'html-loader?minimize=false' },
                    { test: /\.css$/, use: ['to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize'] },
                    { test: /\.scss$/, use: ['to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize', 'sass-loader'] },
                    { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
                ]
            },
            plugins: [new CheckerPlugin()]
        };

        // Configuration for client-side bundle suitable for running in browsers
        const clientBundleOutputDir = './wwwroot/dist';
        const clientBundleConfig = merge(sharedConfig, {
            entry: { 'main-client': './ClientApp/boot.browser.ts' },
            output: { path: path.join(__dirname, clientBundleOutputDir) },
            plugins: [
                new webpack.DllReferencePlugin({
                    context: __dirname,
                    manifest: require('./wwwroot/dist/vendor-manifest.json')
                })
            ].concat(isDevBuild ? [
                // Plugins that apply in development builds only
                new webpack.SourceMapDevToolPlugin({
                    filename: '[file].map', // Remove this line if you prefer inline source maps
                    moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
                })
            ] : [
                    // Plugins that apply in production builds only
                    new webpack.optimize.UglifyJsPlugin(),
                    new AotPlugin({
                        tsConfigPath: './tsconfig.json',
                        entryModule: path.join(__dirname, 'ClientApp/app/app.module#AppModule')
                    })
                ])
        });

        return [clientBundleConfig];
    };

webpack.config.vendor.js

    const path = require('path');
    const webpack = require('webpack');
    const ExtractTextPlugin = require('extract-text-webpack-plugin');
    const merge = require('webpack-merge');
    const treeShakableModules = [
        '@angular/animations',
        '@angular/common',
        '@angular/compiler',
        '@angular/core',
        '@angular/forms',
        '@angular/http',
        '@angular/platform-browser',
        '@angular/platform-browser-dynamic',
        '@angular/router',
        'zone.js',
    ];
    const nonTreeShakableModules = [
        'bootstrap',
        'core-js/client/shim',
        'web-animations-js',
        'event-source-polyfill',
        'jquery',
        '@swimlane/ngx-datatable/release/assets/icons.css',
        'ng2-toasty',
        'ng2-toasty/bundles/style-bootstrap.css',
        'ng2-charts',
        'ngx-bootstrap/modal',
        'ngx-bootstrap/tooltip',
        'ngx-bootstrap/popover',
        'ngx-bootstrap/dropdown',
        'ngx-bootstrap/carousel',
        'bootstrap-vertical-tabs/bootstrap.vertical-tabs.css',
        'bootstrap-toggle/css/bootstrap-toggle.css',
        'bootstrap-toggle/js/bootstrap-toggle.js',
        'bootstrap-select/dist/css/bootstrap-select.css',
        'bootstrap-select/dist/js/bootstrap-select.js',
        'bootstrap-datepicker/dist/css/bootstrap-datepicker3.css',
        'font-awesome/css/font-awesome.css'
    ];
    const allModules = treeShakableModules.concat(nonTreeShakableModules);

    module.exports = (env) => {
        const extractCSS = new ExtractTextPlugin('vendor.css');
        const isDevBuild = !(env && env.prod);
        const sharedConfig = {
            stats: { modules: false },
            resolve: { extensions: ['.js'] },
            module: {
                rules: [
                    { test: /\.(gif|png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' }
                ]
            },
            output: {
                publicPath: 'dist/',
                filename: '[name].js',
                library: '[name]_[hash]'
            },
            plugins: [
                new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
                new webpack.ContextReplacementPlugin(/\@angular\b.*\b(bundles|linker)/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/11580
                new webpack.ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)@angular/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/14898
                new webpack.IgnorePlugin(/^vertx$/) // Workaround for https://github.com/stefanpenner/es6-promise/issues/100
            ]
        };

        const clientBundleConfig = merge(sharedConfig, {
            entry: {
                // To keep development builds fast, include all vendor dependencies in the vendor bundle.
                // But for production builds, leave the tree-shakable ones out so the AOT compiler can produce a smaller bundle.
                vendor: isDevBuild ? allModules : nonTreeShakableModules
            },
            output: { path: path.join(__dirname, 'wwwroot', 'dist') },
            module: {
                rules: [
                    { test: /\.css(\?|$)/, use: extractCSS.extract({ use: isDevBuild ? 'css-loader' : 'css-loader?minimize' }) }
                ]
            },
            plugins: [
                extractCSS,
                new webpack.DllPlugin({
                    path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
                    name: '[name]_[hash]'
                })
            ].concat(isDevBuild ? [] : [
                new webpack.optimize.UglifyJsPlugin()
            ])
        });

        return [clientBundleConfig];
    }

1125voto

Manish Points 2189

Pour résoudre ce problème HttpClient est le mécanisme d'Angular pour communiquer avec un serveur distant via HTTP.

Pour faire HttpClient disponible partout dans l'application,

  1. ouvrir la racine AppModule ,

  2. d'importer le HttpClientModule de @angular/common/http ,

  3. l'ajouter à la @NgModule.imports le tableau.

Ajoutez ce qui suit à app.module.ts :

import { HttpClientModule } from '@angular/common/http'; 

Après cela, ajoutez dans la section d'importation comme imports:[HttpClientModule, ]

202voto

kmp Points 1181

Vous n'avez pas fourni de fournisseurs dans votre module :

<strike>import { HttpModule } from '@angular/http';</strike>
import { HttpClientModule, HttpClient } from '@angular/common/http';

@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule,
    BrowserAnimationsModule,
    FormsModule,
    AppRoutingModule
  ],
  providers: [ HttpClientModule, ... ]
  // ...
})
export class MyModule { /* ... */ }

Utilisation de HttpClient dans les tests

Vous devrez ajouter le HttpClientTestingModule à la configuration de TestBed lors de l'exécution de ng test et j'obtiens l'erreur "No provider for HttpClient" :

// Http testing module and mocking controller
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

// Other imports
import { TestBed } from '@angular/core/testing';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';

describe('HttpClient testing', () => {
  let httpClient: HttpClient;
  let httpTestingController: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ HttpClientTestingModule ]
    });

    // Inject the http service and test controller for each test
    httpClient = TestBed.get(HttpClient);
    httpTestingController = TestBed.get(HttpTestingController);
  });

  it('works', () => {
  });
});

61voto

Vivek kushwaha Points 486

Vous obtenez une erreur pour HttpClient, il vous manque donc HttpClientModule pour cela.

vous devez l'importer dans le fichier app.module.ts comme ceci -

import { HttpClientModule } from '@angular/common/http';

et le mentionner dans le décorateur NgModule comme ceci -

@NgModule({
...
imports:[ HttpClientModule ]
...
})

si cela ne fonctionne pas, essayez de supprimer les cookies du navigateur et essayez de redémarrer votre serveur. J'espère que cela pourra fonctionner, j'ai eu la même erreur.

34voto

Abhilash Ranjan Points 38

J'ai eu le même problème. Après avoir navigué et lutté avec le problème, j'ai trouvé la solution suivante

import { HttpModule } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';

imports: [
  HttpModule,
  HttpClientModule
]

Importation HttpModule et HttpClientModule dans app.module.ts et ajouter dans les importations comme mentionné ci-dessus.

28voto

Ravishankar Points 111

J'étais également confronté à un problème similaire et j'ai effectué les modifications suivantes, qui ont fonctionné pour moi.

Dans app.modules.ts

import {HttpClientModule} from '@angular/common/http' 

et dans la classe de service correspondante

import { HttpClient } from '@angular/common/http'

devrait ressembler à ce qui suit

constructor(private http: HttpClient, private xyz: xyzService) {}

Dans le fichier de test

import { HttpClientTestingModule } from '@angular/common/http/testing'

  beforeEach(() => TestBed.configureTestingModule({
    imports: [HttpClientTestingModule]
  }));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X