Files
ECC/pi/core/skills/angular-developer/references/creating-services.md
T
Affaan MustafaandGitHub c70874fae9 feat(pi): curated pi/core skills+prompts profile, CI load test, and 2.2.2 release sync (#3264)
Adds a curated, Pi-native, skills+prompts-only profile at pi/core/ for downstream packagers that mirror GitHub Releases.

- manifests/pi-core.json: explicit include lists, per-item exclusion reasons, curation rules, safety allowlists; every root skill and command must be classified.
- scripts/build-pi-core.js regenerates pi/core deterministically (package.json from VERSION, LICENSE, README.md, CURATION.md, skills/, commands/); --check fails CI on drift. council is renamed ecc-council inside pi/core only.
- Safety checks: no callable endpoints outside the allowlist, no npx/curl|sh/pip install, no secrets, no absolute home paths, no symlinks, valid frontmatter, no duplicate names.
- CI: build + drift check and an offline Pi CLI load test of pi/core.
- Release: VERSION, package.json and pi/core/package.json at 2.2.2, CHANGELOG, tag-triggered release verification, and a two-week cadence in CONTRIBUTING.md.

pi/core: 123 of 293 skills and 24 of 94 commands; 35,006 characters of skill description text.
2026-09-29 20:24:05 -05:00

2.6 KiB

Creating and Using Services

Services in Angular are reusable pieces of code that handle data fetching, business logic, or state management that multiple components or other services need to access.

Creating a Service

You can generate a service using the Angular CLI:

ng generate service my-data

Or you can manually create a TypeScript class and decorate it with @Injectable().

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

@Injectable({
  providedIn: 'root',
})
export class BasicDataStore {
  private data: string[] = [];

  addData(item: string): void {
    this.data.push(item);
  }

  getData(): string[] {
    return [...this.data];
  }
}

The providedIn: 'root' Option

Using providedIn: 'root' is the recommended approach for most services. It tells Angular to:

  • Create a single instance (singleton) for the entire application.
  • Make it available everywhere automatically, without needing to list it in any providers array.
  • Enable tree-shaking, meaning the service is only included in the final JavaScript bundle if it is actually injected somewhere.

Injecting a Service

Once a service is created, you can inject it into components, directives, or other services using the inject() function.

Injecting into a Component

import {Component, inject} from '@angular/core';
import {BasicDataStore} from './basic-data-store.service';

@Component({
  selector: 'app-example',
  template: `
    <div>
      <p>Data items: {{ dataStore.getData().length }}</p>
      <button (click)="dataStore.addData('New Item')">Add Item</button>
    </div>
  `,
})
export class Example {
  // Inject the service as a class field
  dataStore = inject(BasicDataStore);
}

Injecting into Another Service

Services can inject other services in the exact same way.

import {Injectable, inject} from '@angular/core';
import {AdvancedDataStore} from './advanced-data-store.service';

@Injectable({
  providedIn: 'root',
})
export class BasicDataStore {
  // Injecting another service
  private advancedDataStore = inject(AdvancedDataStore);

  private data: string[] = [];

  getData(): string[] {
    // Combine data from this service and the injected service
    return [...this.data, ...this.advancedDataStore.getData()];
  }
}

Advanced Service Patterns

While providedIn: 'root' covers most scenarios, you may sometimes need:

  • Component-specific instances: If a component needs its own isolated instance of a service, provide it directly in the component's @Component({ providers: [MyService] }) array.
  • Factory providers: For dynamic creation.
  • Value providers: For injecting configuration objects.