3

I have application in Angular and I have only one HttpClientModule, but when I provide HttpClient in constructor like this:

export class UserService {

constructor(private http: HttpClient /** <---- this one is ok, and requests are intercepted */) {
    const i='i'; 
}

but in another module i also have similar constructor

export class TableComponent implements OnInit {

  ...
  ...
  constructor(private http: HttpClient /** <---- this one is not ok, and requests are  not intercepted */) {

  }

My app.module

@NgModule({
  declarations: [AppComponent],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptorRefresh,
      multi: true,
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true,
    },
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    AppRoutingModule,
    MainAppModule,
    TableModule,

Table module contents

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {TableHeaderComponent} from './table-header/table-header.component';
import {TableComponent} from './table/table.component';
import {TablePaginationComponent} from './table-pagination/table-pagination.component';
import {TableFilterComponent} from './table-filter/table-filter.component';

@NgModule({
  declarations: [TableHeaderComponent, TableComponent, TablePaginationComponent, TableFilterComponent],
  imports: [
    CommonModule,
  ],
  exports: [TableHeaderComponent, TableComponent, TablePaginationComponent, TableFilterComponent],
})
export class TableModule {
}

MainAppModule

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {UsersComponent} from './users/users.component';
import {MainAppRoutingModule} from './main-app-routing.module';
import {LayoutComponent} from './layout/layout.component';
import {ThemeModule} from '../../@theme/theme.module';
import {NbCardModule} from '@nebular/theme';
import {Ng2SmartTableModule} from 'ng2-smart-table';
import {TableModule} from '../table/table.module';

@NgModule({
  declarations: [UsersComponent, LayoutComponent],
  imports: [
    CommonModule, MainAppRoutingModule, ThemeModule, NbCardModule, Ng2SmartTableModule, TableModule,
  ],
})
export class MainAppModule {
}

What am I doing wrong?

kvetis
  • 6,682
  • 1
  • 28
  • 48
Viszman
  • 1,378
  • 1
  • 17
  • 47

2 Answers2

2

Only import HttpClientModule once in your app and provide interceptors in the same place.

According to docs:

Because interceptors are (optional) dependencies of the HttpClient service, you must provide them in the same injector (or a parent of the injector) that provides HttpClient. Interceptors provided after DI creates the HttpClient are ignored.

kvetis
  • 6,682
  • 1
  • 28
  • 48
  • But it seems not to be the problem in this case. But still I would check. – kvetis Feb 26 '20 at 08:53
  • obviously when i create function in service in userService file which give me injected HttpClient, everything is ok – Viszman Feb 26 '20 at 08:53
  • @Viszman If `UsersService` is provided in `'root'`, it is provided in the same place as the `HttpClient` and interceptors. Therefore it works in that case. I suspect your other modules, `AppRoutingModule` or `MainAppModule` – kvetis Feb 26 '20 at 08:57
  • 1
    i cleared that project and now everything if working correctly, but i don't know what was not right – Viszman Feb 27 '20 at 06:58
0

I think that your problem is with the service injection.

I will leave an example here so you can compare.

The parent module (AppModule) imports HttpClientModule and the child module

@NgModule({
  declarations: [AppComponent],
  providers: [ChildService],
  imports: [AppRoutingModule, BrowserModule, HttpClientModule, ChildModule],
  bootstrap: [AppComponent]
})
export class AppModule {}

The child module will intercept the http requests, so the service that makes those requests should be injected to this module.

@NgModule({
  declarations: [],
  imports: [],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptorService,
      multi: true
    }
  ]
})
export class ChildModule {}

The service should receive the HttpClient dependency.

@Injectable({
  providedIn: ChildModule
})
export class {
  constructor(private _http: HttpClient) {}
}

And the interceptor should be something like this:

@Injectable()
export class AuthInterceptorService implements HttpInterceptor {
  private token = "";
  constructor(private router: Router, private tokenStore: TokenStoreService) {
    this.token = "fake-token";
  }

  intercept<T>(
    req: HttpRequest<T>,
    next: HttpHandler
  ): Observable<HttpEvent<T>> {
    const authHeader = { Authorization: "Basic " + this.token };
    const authReq = req.clone({ setHeaders: authHeader });
    return next.handle(authReq);
  }
}

I hope this has helped you :)

adrisons
  • 3,443
  • 3
  • 32
  • 48