1

I am trying to make a service for my Angular 2 component with TypeScript. I read a lot of tutorials on how to create a service and all of them said that my service needs to use the decorator @Injectable and that I should just be able to inject it in my component. This does not seem to be working for me when I want to inject my service, but using @Inject does.

My Service:

    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs';

    @Injectable()
    export class GeolocationService {

    /**
     * Get the current location of the user
     * @return {Observable<any>} An observable with the location of the user.
     */
    public getLocation(): Observable<any> {
        return Observable.create(observer => {
            if (window.navigator && window.navigator.geolocation) {
                window.navigator.geolocation.getCurrentPosition(position => {
                    observer.next(position);
                    observer.complete();
                }, error => {
                    observer.error(error);
                }, {
                    maximumAge: 0
                });
            } else {
                observer.error('Browser does not support location services');
            }
        });
    }
}

My component, version that is not working (v1):

import { GeolocationService } from './geolocation.service';

@Component({
    templateUrl: 'home.component.html',
    styleUrls: [ 'home.component.scss' ],
    providers: [ GeolocationService ]
})
export class HomeComponent implements OnInit {

    constructor(private myService: GeolocationService) {
        this.myService.getLocation()
            .subscribe(position => console.log('my position', position));
            // .error(err => console.log('oop error', err))
    }
}

My component, working version (v2)

import { GeolocationService } from './geolocation.service';

@Component({
    templateUrl: 'home.component.html',
    styleUrls: [ 'home.component.scss' ],
    providers: [ GeolocationService ]
})
export class HomeComponent implements OnInit {

    constructor(@Inject(GeolocationService) private myService: GeolocationService) {
        this.myService.getLocation()
            .subscribe(position => console.log('my position', position));
            // .error(err => console.log('oop error', err))
    }
}

Can you please explain to me why only the second version works?

Kim Kern
  • 54,283
  • 17
  • 197
  • 195
bbrakenhoff
  • 179
  • 1
  • 6
  • 1
    Define "not working". What happens, precisely? Can you reproduce that in a plunkr? – JB Nizet Nov 28 '16 at 20:25
  • 1
    Possible your question is very similar to http://stackoverflow.com/questions/39602890/angularjs-2-0-cant-inject-anything-through-component-constructor – yurzui Nov 28 '16 at 20:29
  • add it to your module – chabeee Nov 28 '16 at 20:54
  • Could you please add your tsconfig and the error message you see in your console when running the first version? Please be aware that @Injectable is not required when your service class itself doesn't have any dependencies to be injected. For a service to be injectable, you must `provide` it and have the correct type definition in the component's `constructor`. I assume there is some configuration problem. – Andreas Jägle Nov 28 '16 at 21:40

2 Answers2

0

@Inject() is a manual way of telling Angular that a parameter must be injected. It is not recommended to use it in the way you are using it.

For the first example, I think you didn't tell your app module that you are using that injectable. You have to import it on your main app module and use it as a provider. Then you will be able to inject it to other components, as you have said to the dependency injector that GeolocationService class now can be injected in other classes.

Jorge
  • 540
  • 6
  • 21
0

I found out that "emitDecoratorMetadata" was missing in my tsconfig.json . I confused it with "emitDecoratorData". Thanks though for your help!

bbrakenhoff
  • 179
  • 1
  • 6