DEV Community

Cover image for Simple Angular Service using signals
Joshua Daza Rincon
Joshua Daza Rincon

Posted on

Simple Angular Service using signals

Related to Angular 17th launching I try to learn how works signals. So check how to share data between 2 components.

Firstable this example use standAlone components but the workflow is very similar compared with previous versions.

Create a service with data attribute (assigning the signal) with a number value. and set 2 methods to manage signal value.

store.ts

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

@Injectable({
  providedIn: 'root',
})
export class Store {

  private data = signal(0);

  setDataSignal(val: number) {
    this.data.set(val);
  }

  get DataSignal() {
    return this.data();
  }
}

Enter fullscreen mode Exit fullscreen mode

Consuming signal between components...

Now in main (standAlone component) using a constructor make an instance from Store to local store attribute. Then create a get returning the signal value executed.

main.ts

import 'zone.js';
import { Component, OnInit } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { Store } from '../store/store';
import { HeaderComponent } from './components/header/header.component';

@Component({
  selector: 'app-root',
  standalone: true,
  templateUrl: './main.html',
  imports: [HeaderComponent],
})
export class App {

  constructor(private store: Store) {}

  get dataValue() {
    return this.store.dataSignal;
  }
}

bootstrapApplication(App);

Enter fullscreen mode Exit fullscreen mode

In signals the expression require an execution to listen global state. It can be from service or component, for this example from service

I prefer avoid to write html code in main.ts component to keep all separated and more readable but if you prefer just replace templateUrl: './main.html' with template: '<h2>This is main with Data {{dataValue}}</h2>'.

main.html

<section>
  <h2>This is main with Data {{dataValue}}</h2>
</section>

Enter fullscreen mode Exit fullscreen mode

Second Component

Create a header component on this path components/header as a traditional angular component.

header.ts

import { Component } from '@angular/core';
import { Store } from '../../../store/store';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css'],
  standalone: true,
})
export class HeaderComponent {
  constructor(private store: Store) {}

  get dataValue() {
    return this.store.Data;
  }

  changeData(e: any) {
    this.store.setData(e);
  }
}
Enter fullscreen mode Exit fullscreen mode

to get dataValue is the same approach but to change data create changeData method to pass the new value.

header.html

<header>
  Header Component with DataValue: <strong>{{ dataValue }}</strong> <br />
  <button (click)="changeData(dataValue + 2)">change data</button>
</header>

Enter fullscreen mode Exit fullscreen mode

Using (click) directive set new value adding a number to the current dataValue. That trigger a new value listened globally for all components.

Conclusion

That new way to share data is more simple to write and read, signals definitely does not replace the previous way since
RxJS has a huge range of operators and features but is a huge beginning...

Github code

Top comments (0)