3

I have been trying to find the best solution to share some data beetween two componentes that share the same parent.

I am using an angular-material stepper. Step 1 has one component and step 2 has another one. What i am trying to do is to "click" 1 button in the component from the step 1 and refresh an array of data that affects component in step 2.

This is my code:

Global service:

  export class GlobalDataService {
  private reserveSource = new BehaviorSubject<any[]>([]);

  currentReserve = this.reserveSource.asObservable();

  constructor() { }

  changeReserve(reserve: any[]) {
    this.reserveSource.next(reserve)

  }
}

Component 1 that tries to update:

setSpace(id) {
this.apiObservableService
  .getService('http://localhost:8080/Spaces/' + id)
  .subscribe(
    result => {
      this.space = result;
      this.globaldataservice.changeReserve(result.reserves);
      sessionStorage.setItem('currentSpace', JSON.stringify(result));
    },
    error => console.log(error)
  );

}

Component 2 that tries to read and refresh:

ngOnInit(): void {

    this.currentUser = JSON.parse(sessionStorage.getItem('currentUser'));
    this.currentSpace = JSON.parse(sessionStorage.getItem('currentSpace'));

    this.globaldataservice.currentReserve.subscribe(message => this.reserves = message)
    console.log(this.reserves);
  }
AngelMdez
  • 170
  • 1
  • 10

1 Answers1

4

Quite frankly, your code should work fine, but here is how I deal with it, in case I missed something in your code.

GlobalDataStore should also give out the BehaviourSubject as Observable, so you can subscribe to it.

Also make behavioursubject private.

export class GlobalDataService {
  private reserveSource = new BehaviorSubject<any[]>([]);

  get reserveSource() {
       return this.reserveSource.asObservable();
  }
}

Then just subscribe to it in the component.

As a bonus, I also implement these functions in my stores (since I am also using BehaviourSubject)

//Gets the last value, that was pushed to the BehaviourSubject
get reserveSourceLastValue() {
   return this.reserveSource.getValue();
}

//Deep clones the last value, if I want a precise copy for form editing buffer
get reserveSourceForEdit() {
    return __lodash.cloneDeep( this.reserveSource.getValue() );
}

PRO PERFORMANCE TIP!

As a last note, if you do not unsubscribe from observables, then they are left open forever, even after the component itself is destroyed. To make matters worse, since you have the observable initialized in ngOnInit, then every time you route to and from this component, a new subscription is created.

Please read this article on how to gracefully unsubscribe from subscriptions in components.

Angular/RxJs When should I unsubscribe from `Subscription`

Karl Johan Vallner
  • 3,980
  • 4
  • 35
  • 46
  • +1 for that line in which you specified to destroy the subscription as mostly we all forget and keep that open. – faizan baig May 22 '18 at 04:01
  • Hello, thank you for your replay. I have try different version of the code and using behavioursubjets, replaysubjects, subjects. Sadly, I have already tried your solution before this post and didnt work. The main problem I am getting is that the subscription doesn't seem to get triggered in any case. – AngelMdez May 22 '18 at 07:24
  • Welll... One more idea there is, do you keep your stores in some submodule, whcih you export to root? Because if you provide your store in a submodule, then you will create 2 stores. on is a global store, which is injected into everything outside the module, and the services which use the store inside the base (not root) module, use the core store. – Karl Johan Vallner May 22 '18 at 07:29
  • Basically console.log("Hello World!") in the store constructor, then boot the application and move around. If this appears 2 times, then you know you have 2 singleton stores, with different data and observables online! – Karl Johan Vallner May 22 '18 at 07:30
  • Fixed it. I was creating multiple instances of the global service by adding [providers] to both of my components. Deleted that from partent and childs and worked flawlessly. Thank you! Sorry for not showing that port of the code, It was impossible for you to know. – AngelMdez May 22 '18 at 07:32