2

I have a simple component progressBar in order to display (or not) the progress bar. And a simple observable service.

Here is the service :

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable() 
export class ProgressBarService {
  subject = new BehaviorSubject<any>(false);
  changes = this.subject
              .asObservable()
              .do(changes => console.log('new state', changes)); 

  constructor(private http: Http) {
  }
  show() {
    this.subject.next(true);
  }
  hide() {
    this.subject.next(false);
  }
}

Nothing fancy here, just a BehaviorSubject which is set by default with false, hide/show is used to change the value with .next().

The component looks like this :

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { ProgressBarService } from './progressbar.service';

@Component({
  selector: 'app-progressbar',
  templateUrl: './progressbar.component.html',
  styleUrls: ['./progressbar.component.scss'],
  providers:[ProgressBarService]
})

export class ProgressbarComponent implements OnInit {

  isDisplay : boolean;

  constructor(private $progressbar : ProgressBarService) { }

  ngOnInit() {
    this.$progressbar
      .changes
      .subscribe((display : boolean) => this.isDisplay = display);
  }

  showProgress(){
    (this.isDisplay)
      ? this.$progressbar.hide()
      : this.$progressbar.show();
  }
}

During the init, the component subscribe to the subject in order to get the default value and set it to isDisplay. showProgress is only used to try it in my template.

<md-progress-bar mode="indeterminate" color="accent" *ngIf="isDisplay"></md-progress-bar>

<button type="submit" md-raised-button color="primary" (click)="showProgress()">Show/hide progressBar</button>

And it works just fine when the service is used inside the component.

But, when I try to call this service inside another component, it doesn't work.

Example : My other component called profilesComponent

import { ProgressBarService } from ../progressbar/progressbar.service';

@Component({
  selector: 'profiles',
  templateUrl: 'profiles.component.html',
  providers: [ProgressBarService]
})

export class ProfilesComponent implements OnInit {

  toto :boolean = false;

  constructor(private $progressbar : ProgressBarService) {}

  ngOnInit() {}

  showProgress() {
    if(this.toto) {
      this.$progressbar.hide();
      this.toto = false; 
    } else {
      this.$progressbar.show();
      this.toto = true;
    }
  }
}

I think it's because the two component does not share the same instance of the service but i can't find a way to do so. (Maybe providers in @NgModule?)

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
ByJC
  • 213
  • 1
  • 3
  • 9
  • 3
    Yes this could be a reason. declare it in NgModule and remove from both components. – micronyks Jan 25 '17 at 17:07
  • 1
    Holy **** ! You're right, it's the reason. I removed the `ProgressBarService` from the provider's components then I added it to `app.module.js`. Now they both share the same instance and it works ! Well, thank you sir. I just understood a thing tonight :) – ByJC Jan 25 '17 at 17:27
  • Great !!! enjoy Angular2 then ! – micronyks Jan 25 '17 at 17:31

1 Answers1

3

Thanks to @micronyks, Here is the solution.

For each component, I add the service in the provider's component. In result, the components create a new instance of the service.

In order to resolve the issue, i removed the service from the providers of each component then provide it to the main module.

import { ProgressBarService } from './progressbar/progressbar.service';

@NgModule({
  imports: [
    CommonModule,
    BrowserModule,
    HttpModule,
    AppRoutingModule,
    HomeModule,
    MaterialModule.forRoot()
  ],
  declarations: [AppComponent, ProgressbarComponent],
  providers: [ProgressBarService],
  bootstrap: [AppComponent],
})
export class AppModule { }

The components now share the same instance and the progress bar is well displayed.

ByJC
  • 213
  • 1
  • 3
  • 9