1

I am trying to share few services all over my app, theses services are in charge of the API call on my node server.

By following the official documentation, this is what I tried

// app.component.ts

import { Component }            from "@angular/core";
import { ROUTER_DIRECTIVES }    from '@angular/router';
import "./rxjs-operators";
import {CampaignApiService}     from "./services/api/campaign.api.service";
import {PlatformApiService}     from "./services/api/platform.api.service";
import {TeamApiService}         from "./services/api/team.api.service";
import {UserApiService}         from "./services/api/user.api.service";


@Component({
    moduleId: module.id,
    selector: 'app',
    templateUrl: "app.component.html",
    providers: [
        TeamApiService,
        PlatformApiService,
        CampaignApiService,
        UserApiService,
    ],
    styleUrls: [],
    directives: [ROUTER_DIRECTIVES]
})
export class AppComponent { }

In one of my components I am now trying to access my team.api.service which is supposed to be accessible because provided by one of the parents components, but I am facing this error

ReferenceError: TeamApiService is not defined at eval (app/components/team/index/team.index.component.js:48:77)

The only component between my app and teamIndex is the router, I probably missed something about dependency injections.

This is the component involved in the rendering which cause the error

// team.index.component.ts

import {
    Component, trigger,
    state, style,
    transition, animate,
    OnInit
}                               from "@angular/core";
import { JSONP_PROVIDERS }      from '@angular/http';
import { TeamShowComponent }    from "../show/team.show.component";
import { Observable }           from 'rxjs/Observable';

// Users
import { Team }                 from "../../../models/team.model";
import { TeamService }          from "../../../services/team.service";

@Component({
    moduleId: module.id,
    selector: 'TeamIndex',
    templateUrl: "team.index.html",
    providers: [JSONP_PROVIDERS, TeamService, TeamApiService],
    directives: [TeamShowComponent],
    animations: [
        trigger('teamSelected', [
            state('false', style({
                transform: 'scale(1)'
            })),
            state('true', style({
                transform: 'scale(1)',
                "z-index": 25
            })),
            transition('false => true', animate('100ms ease-in')),
            transition('true => false', animate('100ms ease-out'))
        ])]
})

export class TeamIndexComponent implements OnInit {
    teams: Observable<Team[]>;
    distinctSettings: string[];
    mode = "Observable";
    selectedTeam: Team;

    constructor (private teamService: TeamService, private teamApiService: TeamApiService) {}

    ngOnInit() {
        this.getTeams();
        this.teams.subscribe(
            teams => {
                this.distinctSettings = this.teamService.getDistinctSettings(teams)
            }
        )
    }

    getTeams() {
        this.teams = this.teamApiService.getTeams();
    }

    onSelect(team: Team) {
        if (team === this.selectedTeam)
            this.selectedTeam = null;
        else
            this.selectedTeam = team;
    }

    isSelected(team: Team) {
        return team === this.selectedTeam;
    }
}

I feel obviously a bit weird to didn't import my team.api.service in the component where I am using it. If I add this import it's working well, but then according to the documentation I will be using different instances of my service.

Etienne Cha
  • 345
  • 3
  • 11
  • Possibly Missing bootstrapping `@NgModule({providers: []})` Need to have it [With RC5 onwards, thanks to Radim Köhler](http://stackoverflow.com/a/39290087/452708) – Abhijeet Nov 12 '16 at 04:15
  • here is a very detailed explanation too - https://www.c-sharpcorner.com/article/how-to-create-service-and-access-in-multiple-components-and-its-advantages-in-an/ – Mauricio Gracia Gutierrez Jun 18 '21 at 01:21

2 Answers2

4

There is nothing wrong when you import your service in the component where you want to use service.

Documentation says,

A new instance of service will get created when you include your service in providers:[] of your component.

So its fine if you are using your service as:

import your service in main.ts

import {TeamApiService} from "./services/api/team.api.service";
bootstrap(TeamIndexComponent,[TeamApiService ]
).then(
    success => console.log('App bootstrapped!'),
    error => console.log(error)
);

then only one instance of your service will be accessible throughout your app.

then you can use this instance in whatever component you want.

component 1

import {TeamApiService} from "./services/api/team.api.service";
import {Component} from '@angular/core'
@Component({
selector:'demo',
templateUrl:'demo.component.html',    
})
export class DemoComponent{
    //inject the service in your current component
    constructor(private _teamApiService:TeamApiService){

    }
}

just make sure you don't specify your service in providers:[] array as it will create new instance.

Hope this helps.

Bhushan Gadekar
  • 13,485
  • 21
  • 82
  • 131
1

Perhaps it's a typo but you forgot to import the TeamApiService class in the module of the TeamIndexComponent component:

import { TeamApiService } from '...';
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • You are right, I miss understand the doc, I was scared to create a duplicate instance of my service by adding this import. In fact only adding it to the providers create this duplication. – Etienne Cha Aug 09 '16 at 09:53