I faced with next error and cannot understand how to resolve it.
Can't resolve all parameters for AuthenticationService: ([object Object], ?, [object Object])
I've checked almost every topic here and have tried multiple ways to resolve it but still can't beat it already second day.
I have tried to inject first authService in appService like this but getting same error
@Inject(forwardRef(() => AuthenticationService)) public authService: AuthenticationService
I have checked all DI and order of imports inside services and it seems to me everything is correct
So I appreciate if somebody could help me deal with it.
Angular 4.0.0
AuthService
import { Injectable } from '@angular/core';
import {Http, Headers, Response} from '@angular/http';
import 'rxjs/add/operator/toPromise';
import {Observable} from 'rxjs/Rx';
import {AppServices} from "../../app.services";
import {Router} from "@angular/router";
@Injectable()
export class AuthenticationService {
public token: any;
constructor(
private http: Http,
private appService: AppServices,
private router: Router
) {
this.token = localStorage.getItem('token');
}
login(username: string, password: string): Observable<boolean> {
let headers = new Headers();
let body = null;
headers.append("Authorization",("Basic " + btoa(username + ':' + password)));
return this.http.post(this.appService.api + '/login', body, {headers: headers})
.map((response: Response) => {
let token = response.json() && response.json().token;
if (token) {
this.token = token;
localStorage.setItem('Conform_token', token);
return true;
} else {
return false;
}
});
}
logout(): void {
this.token = null;
localStorage.removeItem('Conform_token');
this.router.navigate(['/login']);
}
}
App Services
import {Injectable} from '@angular/core';
import {Headers, Http, RequestOptions} from '@angular/http';
import {Router} from "@angular/router";
import {AuthenticationService} from "./auth/auth.service";
import 'rxjs/add/operator/toPromise';
import {Observable} from 'rxjs/Rx';
@Injectable()
export class AppServices {
api = '//endpoint/';
public options: any;
constructor(
private http: Http,
private router: Router,
public authService: AuthenticationService // doesn't work
// @Inject(forwardRef(() => AuthenticationService)) public authService: AuthenticationService // doesn't work either
) {
let head = new Headers({
'Authorization': 'Bearer ' + this.authService.token,
"Content-Type": "application/json; charset=utf8"
});
this.options = new RequestOptions({headers: head});
}
// ====================
// data services
// ====================
getData(): Promise<any> {
return this.http
.get(this.api + "/data", this.options)
.toPromise()
.then(response => response.json() as Array<Object>)
.catch((err)=>{this.handleError(err);})
}
App Module
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {BaseRequestOptions, HttpModule} from '@angular/http';
import { MaterialModule} from '@angular/material';
import {FlexLayoutModule} from "@angular/flex-layout";
import 'hammerjs';
import { routing, appRoutingProviders } from './app.routing';
import { AppServices } from './app.services';
import {AuthGuard} from "./auth/auth.guard";
import {AuthenticationService} from "./auth/auth.service";
import {AppComponent} from './app.component';
import {AuthComponent} from './auth/auth.component';
import {NotFoundComponent} from './404/not-found.component';
import { HomeComponent } from './home/home.component';
@NgModule({
declarations: [
AppComponent,
AuthComponent,
NotFoundComponent,
HomeComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
HttpModule,
routing,
MaterialModule,
FlexLayoutModule
],
providers: [AppServices, AuthGuard, AuthenticationService],
bootstrap: [AppComponent]
})
export class AppModule { }
You have a circular dependency between AppServices
and AuthenticationService
- that's not possible with constructor injection like Angular uses.
To work around you can use
export class AuthenticationService {
public token: any;
appService: AppServices;
constructor(
private http: Http,
// private appService: AppServices,
injector:Injector;
private router: Router
) {
setTimeout(() => this.appService = injector.get(AppServices));
this.token = localStorage.getItem('token');
}
See also DI with cyclic dependency with custom HTTP and ConfigService
To avoid setTimeout
you can also set AuthenticationService.appService
from the constructor of AppService
(or the other way around)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With