30
votes

Recently I picked up Angular 5 and I was tasked with creating somewhat of a demo-application.

Ng serve worked perfectly well and even ng build wasn't giving me any problems. I could constantly test if my application was working locally in development, but also on my local tomcat server (using XAMPP).

But when I wanted to use the production build, it went all downhill.

ERROR in : Can't resolve all parameters for DataService in C:/Users/ak/Documents/angular5_project/src/app/services/data.service.ts: (?, [object Object]).

I searched throughout several git repositories and other questions on stackoverflow for this.

At first, I thought I missed something basic.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { NotFoundError } from 'app/common/not-found-error';
import { BadInput } from 'app/common/bad-input';
import { AppError } from 'app/common/app-error';

@Injectable()
export class DataService {

  constructor(private url: string, private http: HttpClient ) {
  }

  getAll() {
    return this.http.get(this.url)
      .catch(this.handleError);
  }

  get(id) {
    return this.http.get(this.url + '/' + id)
    .catch(this.handleError);
  }

  create(resource) {
    //   return Observable.throw(new AppError());
    return this.http.post(this.url, JSON.stringify(resource))
      .catch(this.handleError);
  }

  update(resource) {
    return this.http.put(this.url + '/' + resource.id,
      JSON.stringify(resource))
      .catch(this.handleError);
  }

  delete(id) {
    return this.http.delete(this.url + '/' + id)
      .catch(this.handleError);
  }

  private handleError(error: Response) {
    if (error.status === 404) {
      return Observable.throw(new NotFoundError());
    } else if (error.status === 400) {
      return Observable.throw(new BadInput(error.json()));
    } else {
      return Observable.throw(new AppError(error.json()));
    }
  }

}

But then I disregarded the more obvious choices, like forgetting the @Injectable annotation or forgetting to register the service as such in the app.module.ts

...
import { UserDataService } from 'app/services/user-data.service';
import { DataService } from 'app/services/data.service';
...
 providers: [
    MDBSpinningPreloader,
    AuthGuard,
    AdminAuthGuard,
    AuthService,
    UserDataService,
    DataService,
    EquipmentDataService,
    EquipmentAlarmDataService,
...
  ],

Often, the problem of circular dependencies is mentioned, but from what I have seen, it was never the basic service. I have several services that inherit from the DataService, like a user-service that simply returns a list of all available users from my Spring Backend (Just a set of Dummy Data):

import { Injectable } from '@angular/core';
import { DataService } from 'app/services/data.service';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class UserDataService extends DataService {

  constructor(http: HttpClient) {
    super('http://localhost:8080/users', http);

   }
}

Sadly, I didn't even get any warnings of circular dependency or anything remotely useful I could post here. Which means... nothing. The error message is my only source and I'm at my wit's end.

package.json

{
  "name": "quickstart-angular5",
  "version": "5.0.5",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "build:free": "ngm build -p src/app/typescripts/free --clean && gulp npmFree && gulp startFree && gulp onlyFree",
    "build:pro": "ngm build -p src/app/typescripts/pro --clean && gulp only-pro && gulp startPro",
    "build:all": "npm run build:free && npm run build:pro",
    "aot:build": "ng build --prod --sm=false --aot=true --output-path=dist",
    "pre-commit": "ng lint"
  },
  "private": true,
  "dependencies": {
    "@agm/core": "^1.0.0-beta.2",
    "@angular/animations": "^5.0.0",
    "@angular/common": "^5.0.0",
    "@angular/compiler": "^5.0.0",
    "@angular/core": "^5.0.0",
    "@angular/forms": "^5.0.0",
    "@angular/http": "^5.0.0",
    "@angular/platform-browser": "^5.0.0",
    "@angular/platform-browser-dynamic": "^5.0.0",
    "@angular/router": "^5.0.0",
    "@ng-bootstrap/ng-bootstrap": "1.0.0-beta.5",
    "angular2-jwt": "^0.2.3",
    "chart.js": "2.5.x",
    "classlist.js": "1.1.x",
    "core-js": "2.4.x",
    "del": "3.0.x",
    "easy-pie-chart": "2.1.x",
    "font-awesome": "4.7.x",
    "gulp": "^3.9.1",
    "gulp-rename": "1.2.x",
    "gulp-run": "1.7.x",
    "hammerjs": "2.0.x",
    "ng-html-util": "1.0.x",
    "ngm-cli": "0.5.x",
    "rxjs": "^5.5.2",
    "screenfull": "3.3.x",
    "smoothscroll-polyfill": "0.3.x",
    "web-animations-js": "2.3.x",
    "zone.js": "0.8.x"
  },
  "devDependencies": {
    "@angular/cli": "^1.6.8",
    "@angular/compiler-cli": "^5.0.0",
    "@angular/language-service": "^5.0.0",
    "@types/jasmine": "2.5.38",
    "@types/node": "~6.0.85",
    "codelyzer": "~3.2.0",
    "jasmine-core": "~2.5.2",
    "jasmine-spec-reporter": "~3.2.0",
    "karma": "~1.4.1",
    "karma-chrome-launcher": "~2.0.0",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^0.2.0",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.7.0",
    "typescript": "~2.5.0",
    "uglify-es": "3.3.8",
    "webpack": "3.x"
  }
}

EDIT: I've forgotten to mention, that I can do a general build. The productive build has aot-compilation true by default. When I deactivate it, it seemingly works, but the uglification seems to break as well and the page is broken. Triggering an error like this: https://github.com/angular/angular-cli/issues/8391

My project only works if I use ng build only.

5
Remove DataService from providers because you inititialize it manually - yurzui
It seems to have cleared up one problem, but created an avalanche of errors. Most of them simply popped up, because I don't have the appropriate value in the component.ts files in, so it's not too surprising they popped up during the production. I'll work on clearing them and tell ya if it worked! Thank you for advice so far! - ak.leimrey
I'm here after getting stuck in the example given in the tutorial by Mosh Hamedani. Removing @Injectable(){} code block did the trick. - Vibhor Dube
@VibhorDube Avoid all his web-development tutorials like the plague. Most of them were already outdated by the time he released them. Worse, he never expends the effort to update them. - ak.leimrey
@ak.leimrey Sadly most of the students like me only come to know this after finishing almost 70-80% of the tutorial when the real functionality of the library starts and all the explained methods are deprecated that are shown in the video. :( - Vibhor Dube

5 Answers

31
votes

Your DataService service has two constructor parameters, url and http. http can be resolved because it is registered by the HttpClientModule, but the url parameter is not registered in the dependency injection container. That is the reason why you get the error.

I guess you always let inject a specific class, as for example UserDataService, into your components and never a DataService instance.

So you should refactor your DataService to an abstract DataServiceBase class and remove the @Injectable() decorator.

And as yurzui suggested, remove DataService from the list of providers.

14
votes

The error indicates that the first argument in the constructor is causing the problem. And it should because it's a simple string. Try injecting it like this:

@Injectable()
export class DataService {

constructor(@Inject('API_BASE_URL') private url: string, private http: HttpClient) { // ... }

In your providers:

providers: [DataService, {provide: 'API_BASE_URL', useValue: 'http://localhost:8080/users'}]
3
votes

I had exactly same error. I solved it by removing DataService from providers: [] and also removing the @Injectable decorator from DataService.

1
votes

Just in case it helps anyone, I had the same problem and it was because I had moved the @Injectable attribute off of the class that was unable to resolve any dependencies.

Where I had had

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

I had added another POCO object to the file and placed it between the @Injectable and the service class definition. That meant the POCO was now regarded as Injectable and the service no longer used the Dependency Injection framework.

0
votes

I faced the same issue and after 2-3 hours of struggle i realized that i was creating instance of an interface in my constructor .for example :-

constructor( private readonly dataTable: DataTable, ) {}

Note:- here DataTable is an interface .

Please check whether you are creating instance of an interface in your constructor , if yes then remove it .It worked for me .