Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DI Error in Angular Component

I'm fairly new to Angular 2 and Typescript. I have a DI Error as below that I couldn't solve. I was trying to understand how this DI works:

I'm trying to build a simple signup component that uses a service for validation and REST API operations.

Here is my component:

authentication.component.ts

import { Component, Injectable } from '@angular/core';
import { UserService } from './user.service';
import { User } from './user';


@Component({
    moduleId: module.id,
    selector: 'authentication',
    styles: ['input[type=email].ng-invalid {border: 1px solid #dd0000}'],
    template: `
    <h3>Sign Up</h3>
    <hr>

    <form (ngSubmit)="signup()" >
        <input type="email" name="email" required
        [(ngModel)]="user.email"/>
        <input type="password" name="password" required
        [(ngModel)]="user.password"/>
        <input type="submit" />
    </form>
    <span class.has-error>{{hasError}}</span>`
})
@Injectable()
export class AuthenticationComponent {

    public error: Error;
    public user: User;

    constructor(public userService: UserService) {}
    public signup(): void {
        this.userService.init(this.user);
        this.userService.signup().subscribe(
            s=>console.log(s),
            e=>console.log(e)
        )
    }

    get diagnostic () {
        return JSON.stringify(this.user)
    };
}

And this is my component:

user.service.ts

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { User } from './user';


@Injectable()
export class UserService {

public user: User;

constructor(
    private http: Http,
    private headers: Headers = new Headers({'Content-Type': 'application/json'}),
    private requestOptions: RequestOptions = new RequestOptions({headers: headers})) {}

    public init(user: User) {
        this.user = user;
    }
    signup (): Observable<Response> {
        if (this.user.password !== this.user.passwordConfirm) {
      return Observable.throw(new Error('Şifreleriniz uyuşmuyor!'))
        } else {
          return this.http.post('/signup', this.user, this.requestOptions);
        }
    }
}

This is the stack:

Error: DI Error
    at NoProviderError.ZoneAwareError (http://localhost:3000/node_modules/zone.js/dist/zone.js:958:33)
    at NoProviderError.BaseError [as constructor] (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:1239:20)
    at NoProviderError.AbstractProviderError [as constructor] (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:1365:20)
    at new NoProviderError (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:1405:20)
    at ReflectiveInjector_._throwOrNull (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:2937:23)
    at ReflectiveInjector_._getByKeyDefault (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:2976:29)
    at ReflectiveInjector_._getByKey (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:2908:29)
    at ReflectiveInjector_.get (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:2777:25)
    at AppModuleInjector.NgModuleInjector.get (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:8491:56)
    at CompiledTemplate.proxyViewClass.AppView.injectorGet (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:11935:49)
    at CompiledTemplate.proxyViewClass.DebugAppView.injectorGet (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:12315:53)
    at ElementInjector.get (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:11790:31)
    at ReflectiveInjector_._getByKeyDefault (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:2973:28)
    at ReflectiveInjector_._getByKey (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:2908:29)
    at ReflectiveInjector_.get (http://localhost:3000/node_modules/@angular/core/bundles/core.umd.js:2777:25)
like image 341
Lupus Avatar asked Feb 24 '17 08:02

Lupus


People also ask

What are DI in Angular?

Dependency injection, or DI, is one of the fundamental concepts in Angular. DI is wired into the Angular framework and allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need.

What is DI token in Angular?

The Dependency Injection system in Angular uses tokens to uniquely identify a Provider. There are three types of tokens that you can create in Angular. They are Type Token, String Token, and Injection Token. DI Tokens. Type Token.

What is the use of @injectable in Angular?

The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency. Likewise, the @Injectable() decorator indicates that a component, class, pipe, or NgModule has a dependency on a service.

What is @injectable providedIn root?

Providing a servicelink The service itself is a class that the CLI generated and that's decorated with @Injectable() . By default, this decorator has a providedIn property, which creates a provider for the service. In this case, providedIn: 'root' specifies that Angular should provide the service in the root injector.


1 Answers

If you don't want to use singleton service pattern (means having different instances scoped to component(s) only), you have to put providers:[UserService] in @Component decorator as shown below,

@Component({
    moduleId: module.id,
    selector: 'authentication',

    providers: [UserService]    ///<<<===here

    styles: ['input[type=email].ng-invalid {border: 1px solid #dd0000}'],
    ...
    ...

})

But let's say if you want to have a single instance of your UserService then you have to define it in @NgModule decorator of your root or app component

import { UserService } from './user.service';

@NgModule({
   imports:[...]

   providers:[UserService]      ///<<<===here
   ...
   ...
})
like image 50
Nikhil Shah Avatar answered Sep 28 '22 09:09

Nikhil Shah