5

I am quite new to RxJS so I apologize in advance if this has been answered already.

I have an Angular 2 application and in one of the components I have a plain object. I am binding the UI to this object. What I would like to do is to be able to capture all changes to this object regardless if they come from code or from the user changing one of the fields.

I was looking at the observable object but it seems that the subscribers can only receive notifications if the new is pushed via the Emit method. How would this work in the case of a property bound to a input field for example?

Is there a better way of doing this?

Here is what my code looks like:

export class MyComponent {
  app: ApplicationModel = new ApplicationModel(); <--- this is the object I want to track
  
  constructor(api: APIService) {
    api.getApplication().then((data) => {
      this.app = data; 
    });
  }
}

I am looking for something similar to the way Knockout allows you to receive change notifications:

myViewModel.personName.subscribe(function(newValue) {
    alert("The person's new name is " + newValue);
});

Thank you.

6
  • Possible duplicate of How to detect when an @Input() value changes in Angular2 Commented Mar 23, 2017 at 22:00
  • I don't think so. In my case the object is created in the component itself, it is not imported via @Input Commented Mar 23, 2017 at 22:05
  • You're going the wrong way because this cannot be done. That's why Angular relies on observables and has all these inputs. Commented Mar 23, 2017 at 22:14
  • 1
    With the death of Object.observe(), this is tricky to do. It would be better to do it properly and use an immutable object and emit every new version of the object via an observable. Commented Mar 23, 2017 at 22:17
  • 1
    Yes, this likely will help. Or ApplicationModel can expose observable(s) and push values to them through prop getters/setters. This depends on how it is being used. Commented Mar 23, 2017 at 22:23

1 Answer 1

5

Either when using @Input or simply tracking changes from a service or even the same component, you can use BehaviorSubject.

import { BehaviorSubject } from 'rxjs/BehaviorSubject';

appModel = new BehaviorSubject(new ApplicationModel());

Push new changes:

appModel.next(applicationModelModified);

Subscribe to new changes:

appModel.subscribe(val => ...)

Read value at any point:

appModel.value
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @zurfyx. How would that work with properties that are bound to UI elements (e.g. an input)? do I still have to manually call the next method?
@dpdragnev because of how BehaviorSubject works, yes. I'm not sure if there's a more direct alternative. Though, for groups of elements (like forms), you might want to listen to changes that affect any of the group (i.e. this.myForm.valueChanges.subscribe) and push the changes after you have processed them.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.