Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 5: Can't resolve all parameters for Service

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.

like image 643
ak.leimrey Avatar asked Feb 12 '18 13:02

ak.leimrey


2 Answers

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'}] 
like image 27
Boris Lobanov Avatar answered Oct 18 '22 02:10

Boris Lobanov


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.

like image 156
zgue Avatar answered Oct 18 '22 01:10

zgue