How to view object changes using rxjs 5

I would like to see the object, so all subscribers will be informed about the changes.

I already saw before , but the answer does not matter, since RXjs verion 5 does not include ofObjectChanges API in it.

I looked at some "hacks", for example, to create an observer that returns a function:

let myObservable =  new Observable((observer) => {
  return (data) => {
    observer.next(data)
  }
}) 
//...
myObservable.subscribe()('someData')

However, I am sure there is a more elegant way to do this. Any ideas?

+4
source share
3 answers

ES6 Proxies. -, . - Observable.ofObjectChanges. ( set. traps):

Observable.ofProxyChanges = (target) => {
  let subject = new Subject
  let proxy = new Proxy(target, {
    set(target, key, val) {
      let oldValue = target[key]
      target[key] = val
      subject.next({
        type: oldValue === undefined ? "add" : "change",
        object: target,
        name: key,
        oldValue: oldValue
      })
    }
  })
  return [proxy, subject.asObservable()]
}

let [obj, objChange$] = Observable.ofProxyChanges({})
objChange$.subscribe(console.log)

obj.bar = 1 // logs { type: "add", name: "bar", object: { bar: 1 } }
obj.foo = 2 // logs { type: "add", name: "foo", object: { bar: 1, foo: 2 } }
obj.foo = 3 // logs { type: "change", name: "foo", object: { bar: 1, foo: 3 }, oldValue: 2 }
+4

I would suggest using something similar to the redux approach when changes to an object can be made in a predetermined way:

function factory(reducerByType, initialState) {
  const action$ = new Rx.Subject();
  const state$ = action$
    .startWith(initialState)
    .scan((state, action) => {
      if (reducerByType.hasOwnProperty(action.type)) {
        return reducerByType[action.type](state, action);
      }
      
      return state;
    })
    .distinctUntilChanged();
  
  
  return {
    action$,
    state$,
    dispatch: action => action$.next(action)
  }
}

const {state$, dispatch} = factory({
  ADD: (state, action) =>  state + action.number,
  SUBTRACT: (state, action) =>  state - action.number,
}, 0);

state$.subscribe(val => console.log(val));

dispatch({
  type: 'ADD',
  number: 10,
});

dispatch({
  type: 'SUBTRACT',
  number: 15,
});

dispatch({
  type: 'SUBTRACT',
  number: 0,
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.js"></script>
Run codeHide result
+3
source

Source: https://habr.com/ru/post/1678551/


All Articles