Search code examples
angulardependency-injectioncompiler-errorscircular-dependencyproduction

ng build works but not with --prod


My > ng serve or > ng build command doesn't produce any error and the application runs. but when I run > ng build --prod, it throws the below error. I tried to find a lot on the internet and tried many things like

  • reordering the imports
  • tried forwardRef
  • find circular dependencies
  • etc..

but still, the error persists.

C:\wamp\www\ngapp>ng build --prod
 10% building modules 3/3 modules 0 activeWarning: Can't resolve all parameters for LoginService in C:/wamp/www/ngapp/sr
c/app/abstract/login.service.ts: ([object Object], ?). This will become an error in Angular v6.x
Warning: Can't resolve all parameters for UserService in C:/wamp/www/ngapp/src/app/abstract/user.service.ts: ([object Ob
ject], ?). This will become an error in Angular v6.x

Date: 2018-06-30T06:40:13.988Z
Hash: 72312a1071e597367666
Time: 10125ms
chunk {scripts} scripts.385b291e179030219400.js (scripts) 136 kB  [rendered]
chunk {0} runtime.a66f828dca56eeb90e02.js (runtime) 1.05 kB [entry] [rendered]
chunk {1} styles.14764545cc77d1b25789.css (styles) 159 kB [initial] [rendered]
chunk {2} polyfills.207dcc605630215505f5.js (polyfills) 130 bytes [initial] [rendered]
chunk {3} main.f58b96bf9bf614ca37d4.js (main) 128 bytes [initial] [rendered]

ERROR in : Can't resolve all parameters for UserService in C:/wamp/www/ngapp/src/app/abstract/user.service.ts: ([object
Object], ?).

login.service.ts

import { Injectable, forwardRef, Inject } from '@angular/core';
//import { Http } from '@angular/http';
import { HttpClient } from '@angular/common/http';
import { catchError, map, retry } from 'rxjs/operators';
import { throwError } from 'rxjs';
import { NotFoundError } from '../errors/notfound-error';
import { Unauthorized } from '../errors/unauthorized-error';
import { AppError } from '../errors/app-error';
import * as GLOBAL from 'globals';


interface Credentials {
  username: string,
  password: string
}

@Injectable({
  providedIn: 'root'  
})

export abstract class LoginService {
  

  // readonly USER_NOT_FOUND = 404;
  // readonly UNAUTHENTICATED = 401;
 
  private http: HttpClient;

  constructor(@Inject(forwardRef(() => HttpClient)) http:HttpClient, private url: string) {    
    this.http = http;
  }

  check(credential: Credentials, url?) {
    url = url ? url : this.url;

    return this.http.post(url, credential)
      .pipe(
        //map((response) => { console.log(response.json()); return response.json() }),
        map((response) => { return response }),
        retry(0),
        catchError((error: Response) => { return this.handleError(error) })
      );
  }

  isUserExists(user: {username: string}, url?){
    
    url = url ? url : this.url;

    return this.http.post(url, user)//, {observe: 'response'})
      .pipe(
        map(response => { return response;}),
        catchError( error => this.handleError(error))
      )
  }

  private handleError(error: any) {    
    //console.log("handleError: ", error);
    if (error.status as number === GLOBAL.USER_NOT_FOUND) {      
      return throwError(new NotFoundError(error));
    }
    else if (error.status as number === GLOBAL.UNAUTHENTICATED) {      
      let e = new Unauthorized(error);      
      return throwError(e);
    }
    else {      
      return throwError(new AppError(error));
    }
  }
}

auth.service.ts extends LoginService

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { LoginService } from '../abstract/login.service';
//import { Http } from '@angular/http';

@Injectable({
  providedIn: 'root'
})

export class AuthService extends LoginService {  
  
  constructor(http: HttpClient) { 
    super(http, "http://demo1601932.mockable.io/login-invalid");  
  }

  isUserExists(user: {username: string}){
    let url;
    
    if (user.username == "[email protected]")
      url = "http://demo1601932.mockable.io/user-valid";
    else
      url = "http://demo1601932.mockable.io/user-invalid";

    return super.isUserExists(user, url);
  }

  check(user){

    let url;

    if (user.username == "[email protected]" && user.password == "cust1234")
      url = "https://demo1601932.mockable.io/login-valid";
    else
      url = "https://demo1601932.mockable.io/login-invalid";
    
      return super.check(user, url);
  }
}

user.service.ts

import { Injectable, forwardRef, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { catchError, map, retry } from 'rxjs/operators';
import { throwError } from 'rxjs';
import { NotFoundError } from '../errors/notfound-error';
import { Unauthorized } from '../errors/unauthorized-error';
import { AppError } from '../errors/app-error';
import * as GLOBAL from 'globals';

@Injectable({
  providedIn: 'root'
})
export class UserService {

  private http: HttpClient;  

  constructor(@Inject(forwardRef(() => HttpClient)) http:HttpClient, private url: string) {
    this.http = http;    
  }

  getAll(url? : string){
    
    url = url ? url : this.url;
    
    return this.http.get(url).pipe(
      map(response => { return response;}),
      catchError( error => this.handleError(error))
    )
  }

  getUser(uid, url? : string){
    url = url ? url : this.url;

    return this.http.get(url + "/" + uid)
    .pipe(
      retry(2),
      catchError( error => this.handleError(error))
    )
  }

  create(user, url? : string){  
    url = url ? url : this.url;
    
    return this.http.put(url, user).pipe(
      map(response => { return response;}),
      catchError( error => this.handleError(error))
    )
  }

  update(uid, data, url? : string){
    url = url ? url : this.url;

    return this.http.patch(url + '/'+ uid, data, { observe: "response"}).pipe(
      map(response => {
        // console.log('Headers', response.headers.keys());
        // console.log('Body', response.body);
        return response.body;
      }),
      retry(1),
      catchError( error => this.handleError(error))
    )
  }

  private handleError(error: any) {    
    //console.log("handleError: ", error);
    if (error.status as number === GLOBAL.USER_NOT_FOUND) {      
      return throwError(new NotFoundError(error));
    }
    else if (error.status as number === GLOBAL.UNAUTHENTICATED) {      
      let e = new Unauthorized(error);      
      return throwError(e);
    }
    else {      
      return throwError(new AppError(error));
    }
  }
}

customer.service.ts extends UserService

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { UserService } from '../abstract/user.service';

@Injectable({
  providedIn: 'root'
})

export class CustomersService extends UserService {

  constructor(http: HttpClient) {
    super(http, "http://demo1601932.mockable.io/customers/");
  }

  getAll(){
    return super.getAll("http://demo1601932.mockable.io/customers/get");
  }

  get(uid){
    return super.getUser(uid, "http://demo1601932.mockable.io/customer/get");
  }
  
  create(user){
    return super.create(user, "http://demo1601932.mockable.io/customers");
  }

  update(uid, userData){
    return super.update(uid, userData, "http://demo1601932.mockable.io/customers");
  }

  //Admin
  getall4Admin(){
    return super.getAll("https://jsonplaceholder.typicode.com/users");
  }

  get4Admin(uid){
    return super.getUser(uid, "https://jsonplaceholder.typicode.com/users");
  }
}

Solution

  • In UserService, you've marked the Service as @Injectable, which means Angular needs to know how to instantiate it. It has no idea what you want to use for the URL.

    If you don't want to inject UserService directly into constructors, then simply remove:

    @Injectable({
      providedIn: 'root'
    })
    

    from UserService.

    Alternately, if you do want to inject into constructors, then remove the url property from the constructor, and set it using a setter instead, by adding the below code into UserService

    set url(url: string) {
        this.url = url;
    }
    

    And in child class constructor, set it with super.url = "http://demo1601932.mockable.io/customers/"