Dealing with changes on complex data with BehaviorSubject

3158 views angular
6

Let's say I have a Service that provides a BehaviorSubject to any component that wants to get the latest version of some data.

export class DataService {    
    private messageSource = new BehaviorSubject<Data>(this.data);
    currentMessage = this.messageSource.asObservable();
}

export class Component implements OnInit {

    message:Data;

    constructor(private data: DataService) { }

    ngOnInit() {
      this.data.currentMessage.subscribe(
        message => {
          this.message = JSON.parse(JSON.stringify(message))
        }
      )
    }
}

The Data is complex:

class Data {
    id:number
    prop1:string
    prop2:Array<{prop1:number, prop2:string}>
}

The Data changes over time, and the components are only concerned with the latest version of the data. My question is: How can the components know what exactly changed about the data when they get notified?

For example, let's say that only one field of one item in prop2 changed. Every component will get the new data, but they don't know what exactly changed. Knowing what changed would open up many opportunities for rendering optimization.

Is there a built-in way to do this with BehaviorSubject? Is the component supposed to figure out the differences after it gets notified? How is this usually done?

answered question

This isn't an RxJS concern. However, if you treat the data held by the subject as immutable, you will get what want for free if you use Angular's OnPush change detection.

1 Answer

13

That's not the job of Subjects to care about the type of their payload, let alone what properties have changed.

There are other tools to diff objects, e.g. you might want to check reduce of the lodash library. There are plenty of others if your search the web for deep diff

You could store the most recent Data in your components and everytime you receive a new one via your subject you diff it, apply your changes and overwrite the stored Data with the latest one.

posted this

Have an answer?

JD

Please login first before posting an answer.