0

I'm using Angular 7 (and one day I have to upgrade my version). I have a service that have some variables that can change according to some Promise (http GET, PUT, ... response).

I wish to print these variables on a template.

Can I do this:

app.component.html:

<ng-container *ngIf="this.dogService.isWarningProblem">
    <ngb-alert [dismissible]="false" type="warning" style="text-align: center">
        {{this.dogService.errorMessage}}
    </ngb-alert>
</ng-container>

app.service.ts:

export class DraftService {

    public errorMessage: string;
    public isWarningProblem: boolean;

    constructor
        (
            private generalErrorService: GeneralErrorService,
            private http: HttpClient
        ) {
            [...]
        }

    public launchPingEditReadDraftByActionOfferIdUrl(action: string, offerIdUrl: string): Subscription {
        return interval(10).subscribe(
            () => {
                //Get variables from the server and set them.
            },
            () => {}
        );
    }

}

I wish to use service because the algorithm is equal to another components but they cannot see the variables of others components. So, I can not use the subscription with Behavior Subject and Observable:

Are there any better solutions?

ng-hobby
  • 2,077
  • 2
  • 13
  • 26
yalabef21
  • 151
  • 9

1 Answers1

1

No, it is not the best practice to render the service result directly into the template. It's better to inject your service as a dependency (Dependency Injection) into your component which set some variables with service result and render those in your template. So try something like this:

app.service.ts

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

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

    private errorMessage$ = new Subject<string>();
    private isWarningProblem$ = new Subject<boolean>();

    
    constructor (
      private generalErrorService: GeneralErrorService,
      private http: HttpClient
    ) {
       this.launchPingEditReadDraftByActionOfferIdUrl();
    }

    sendErrorMessage(message: string) {
        this.errorMessage$.next({ text: message });
    }

    clearErrorMessages() {
        this.errorMessage$.next();
    }

    onErrorMessage(): Observable<any> {
        return this.errorMessage$.asObservable();
    }

    public launchPingEditReadDraftByActionOfferIdUrl (action: string, offerIdUrl: string): Subscription {
      interval(10).subscribe(
        (res) => {
          this.sendErrorMessage(res.errorMessage);
          // The other like this
        });
    }
}

app.component.ts

import { Component } from '@angular/core';
import { DraftService } from './draft-service';

@Component({
  selector: 'app-template',
  templateUrl: './template.component.html',
  styleUrls: ['./template.component.css'],
})
export class TemplateComponent {

  public errorMessage: string;
  public isWarningProblem: boolean;

  constructor(
    private _draftService: DraftService,
  ) { }
   
  ngOnInit() {
    this._draftService.onErrorMessage().subscribe(
      res => {
        this.errorMessage = res
        //The other like this
      }
    );
  }
}

app.component.html

<ng-container *ngIf="isWarningProblem">
  <ngb-alert [dismissible]="false" type = "warning" style="text-align: center">
    {{errorMessage}}
  </ngb-alert>
</ng-container>
ng-hobby
  • 2,077
  • 2
  • 13
  • 26
  • I thank you, but `interval(10).subscribe` set the value every 10 minutes and in your solution I cannot that the new value will be set. – yalabef21 Sep 09 '20 at 19:18
  • It's Ok. In your Service.ts and in the `interval(10).subscribe()` emit an event using a new observable.next() and in component cause you've subscribed for that will get the new values and reset your variables and your template will be rendered. – ng-hobby Sep 09 '20 at 20:32
  • I added a sample service for you in my answer. check it out – ng-hobby Sep 09 '20 at 20:53