Jedi Schmedi
Jedi Schmedi

Reputation: 818

Service based on observable

I got an view that holds 4 components. These 4 components subscribes to a service where they get the updated object that they work with.

This is service:

@Injectable()
export class testService {

  private testSubject = new BehaviorSubject<Test>(null);

  constructor() { }

  public setTest(test: Test) {
    this.testSubject.next(test);
  }

  public getTest(): Observable<Test> {
    return this.testSubject.asObservable();
  }
}

And the components subscribe as following:

this.testService.getTest()
  .takeUntil(this.unsubscribe)
  .subscribe(
    res => {

      this._test = res;
    },
    err => {
      console.log(err);
    }
  );

The problem is that when I change any property of _test in any component I get a change in the other components as well. I would like the behavior to be that the change is capsulated in that component and by calling the setTest on the testService I trigger the subscribe in the other components in thier view. Because now it seems they all edit the same object as the service returns a reference.

How can I achive this behavior/pattern easiest? Should I deepclone every response from the service in the components?

Br

Upvotes: 0

Views: 29

Answers (1)

Sergi Dote Teixidor
Sergi Dote Teixidor

Reputation: 640

Of course. This behavior is because your are using a subject that is hot and all subscribers are notified when it changes. This is the Subject nature.

If you want affect only a component you have two solutions: 1) use on observable instead of a subject 2) or create one service per component (using @component.providers property), but this is a very bad practice.

Upvotes: 1

Related Questions