7

I have alert service in a angular 4 project. All components can set alerts in that service, but only some show them and each one shows them in a unique location. So my question is how is it possible to define get a variable from a service in all the html files?

My service looks like this:

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

@Injectable()
export class AlertService {
  message;

  constructor() { }

  setMessage(message){
    this.message = message;
  }
}

And the component that wants to set a message just imports the service and calls setMessage method. But when i try to use message in html file like:

{{message}}

then its out of scope. How can i make this message accessible in all html files of all components?

Or maybe there is a better way to solve this kind of an requirement than a service variable?

georgeawg
  • 48,608
  • 13
  • 72
  • 95
user1985273
  • 1,817
  • 15
  • 50
  • 85

1 Answers1

10

In order to consume the message in your component you need to inject the service in your constructor (which you are probably doing).

Component:

export class MyComponent {
  constructor(public alertService: AlertService)

In the markup reference alertService.message instead of message.

{{ alertService.message }}
Joel Richman
  • 1,894
  • 12
  • 13
  • Please note, however, that the code shown above will NOT work with the AoT or the Angular CLI when doing a production build. The issue is outlined here: https://github.com/angular/angular-cli/issues/5623. Any property/field/function accessed from within a template be public. So the code above needs to be changed to: `constructor(public alertService: AlertService)` – DeborahK Jun 16 '17 at 00:40
  • The answer has been updated to declare alertService as public. Good catch DeborahK. – Joel Richman Jun 16 '17 at 01:04
  • is it valid also for Angular 9? And is it the better solution (https://stackoverflow.com/questions/63816520/angular-insert-service-in-the-file-html)? – yalabef21 Sep 09 '20 at 19:58
  • @yalabef21 Yes this still works in Angular 9. I don't think there is an issue consuming a publicly injected service directly in the markup. In the question you reference they use subscribe() method in the component and never unsubscribe(), this is an anti-pattern. It could be simplified by subscribing in the markup using the async pipe (i.e. _draftService.onErrorMessage() | async). Then it will automatically unsubscribe when the component goes out of scope. I usually use a state management library like NGRX for these scenarios, but that is unnecessary for small applications. – Joel Richman Sep 10 '20 at 00:34