Search code examples
servicedependency-injectionmoduleangular6

Angular 6 Shared Modules and Sharing Services


I'm having an issue with my Angular 6 app that I'm breaking up into smaller modules. Originally everything was imported into AppModule, and it worked just fine, but it was a giant file and testing was overly complicated.

The issue I'm having is basically creating a shared-module for a few commonly used services across the app. ng build runs fine so it seems to build alright, but when I serve the app I get the error that "ConfigService.foo()" is not a function! I'm obviously doing something wrong to group shared services into a shared module.

Here's some code:

SharedModule

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable, OnInit, NgModule } from '@angular/core';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import * as $ from 'jquery';

import { PipeModule } from './pipes/pipes.module';
import { ConfigService } from "./config.service";

@NgModule({
    imports: [
      PipeModule
    ],
    declarations: [
    ],
    exports: [
      PipeModule
    ],
    providers: [
      ConfigService
    ]
})

export class SharedModule {
  static forRoot() {
     return {
       ngModule: SharedModule,
       providers: [
         ConfigService, {
           provide: ConfigService,
           useValue: ConfigService
         },
       ],
     };
  }
}

ConfigService

import {Injectable} from "@angular/core";
import {HttpClient, HttpHeaders, HttpParams, HttpResponse} from "@angular/common/http";
import {HttpObserve} from "@angular/common/http/src/client";

import {Observable, Subject, Observer, BehaviorSubject, throwError} from 'rxjs';
import {Config} from '../shared/config';
import { map, catchError} from 'rxjs/operators';
import * as _ from 'lodash';

@Injectable()
export class ConfigService {

  constructor(private httpClient: HttpClient, private config: Config) {
    this.config = new Config();
  }

  ngOnInit() {  }

  foo() {
    console.log("Hack the planet!!! (confgurably)");
  }

}

AppModule

import { BrowserModule } from '@angular/platform-browser';
import {APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, NgModule, PipeTransform} from '@angular/core';
import {HttpClient, HttpClientModule} from "@angular/common/http";
import {AppRoutingModule} from './app-routing.module';
import {FormsModule} from "@angular/forms";

import { AppComponent } from './app.component';
import { BannerComponent } from './banner/banner.component';
import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component';
import { SearchComponent } from './search/search.component';

import { SharedModule }        from './shared/shared.module';


@NgModule({
  declarations: [
    AppComponent,
    BannerComponent,
    BreadcrumbComponent,
    SearchComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    AppRoutingModule,
    SharedModule.forRoot()
  ],
  providers: [
    HttpClient
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

What am I doing wrong with my Shared-Module and injectable services? For reference, I'm using Angularv6.


Solution

  • I just figured it out.

    It turns out, when providing your own services in a module, you don't use

    { provide: ConfigService, useValue: ConfigService },
    

    Instead, you simply list the services under providers in your exported module, like this:

    export class SharedModule {
      static forRoot() {
         return {
           ngModule: SharedModule,
           providers: [
             ConfigService
           ],
         };
      }
    }
    

    Cheers!