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];
    }

17voto

Achintha Isuru Points 63

J'étais confronté au même problème, la chose amusante était que j'avais deux projets ouverts simultanément, j'ai changé les mauvais fichiers app.modules.ts.

D'abord, vérifiez ça.

Après cette modification, ajoutez le code suivant à l'élément app.module.ts fichier

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

après cela, ajoutez les éléments suivants au tableau des importations dans le fichier app.module.ts fichier

  imports: [
    HttpClientModule,....
  ],

Maintenant, ça devrait aller !

13voto

Wasey Raza Points 65

J'étais confronté au même problème, puis dans ma app.module.ts Je mets à jour le fichier de cette façon,

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

et dans le même fichier (app.module.ts) dans mon @NgModule import[]array que j'ai écrit de cette façon,

HttpModule,
HttpClientModule

12voto

Nils Fett Points 151

J'ai eu cette erreur après avoir injecté un service qui utilise HTTPClient dans une classe. La classe était à nouveau utilisée dans le service, ce qui créait une dépendance circulaire. J'ai pu compiler l'application avec des avertissements, mais dans la console du navigateur, l'erreur est apparue.

"Aucun fournisseur pour HttpClient ! (MyService -> HttpClient)"

et ça a cassé l'application.

Ça marche :

import { HttpClient, HttpClientModule, HttpHeaders } from '@angular/common/http';
import { MyClass } from "../classes/my.class";

@Injectable()
export class MyService {
  constructor(
    private http: HttpClient
  ){
    // do something with myClass Instances
  }      
}
.
.
.
export class MenuItem {
  constructor(

  ){}
}

Cela casse l'application

import { HttpClient, HttpClientModule, HttpHeaders } from '@angular/common/http';
import { MyClass } from "../classes/my.class";

@Injectable()
export class MyService {
  constructor(
    private http: HttpClient
  ){
    // do something with myClass Instances
  }      
}
.
.
.
import { MyService } from '../services/my.service';
export class MyClass {
  constructor(
    let injector = ReflectiveInjector.resolveAndCreate([MyService]);
    this.myService = injector.get(MyService);
  ){}
}

Après avoir injecté MyService dans MyClass, j'ai reçu l'avertissement de dépendance circulaire. CLI a quand même compilé avec cet avertissement mais l'application ne fonctionnait plus et l'erreur était donnée dans la console du navigateur. Donc dans mon cas, cela n'avait rien à voir avec @NgModule mais avec les dépendances circulaires. Je recommande de résoudre les avertissements de nommage sensibles à la casse si votre problème existe toujours.

10voto

J'ai trouvé un problème plus mince. Veuillez importer le HttpClientModule dans votre fichier app.module.ts comme suit :

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

import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
],

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

7voto

sumit mehra Points 609

Ajouter HttpModule et HttpClientModule dans les importations et les fournisseurs dans app.module.ts a résolu le problème. importations -> import {HttpModule} from "@angular/http"; import {HttpClientModule} from "@angular/common/http";

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