1

In RxJs 5.4.3 how is it possible to implement a pattern similar to what could be achieved with .ofArrayChanges()? (which is not a function in 5.4.3)

http://jsfiddle.net/ablochs/6jr6syhz/1/

var arr = [1,2,3];
var source = Rx.Observable.ofArrayChanges(arr);

var subscription = source.subscribe(
    function (x) { console.log('Next: ' + x); },
    function (e) { console.log('Error: ' + e); },
    function ( ) { console.log('Completed'); });

arr.push(4)

RxJs .from operators docs

a_b
  • 1,828
  • 5
  • 23
  • 37
  • This won't be implemented in RxJS 5 because `Array.observe` is marked as obsolete https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/observe – martin Sep 27 '17 at 08:45
  • Ok, how is it possible to create a similar construct with the functions that are available? I'm looking for a way to subscribe to an array, which has been initially populated. – a_b Sep 27 '17 at 08:51
  • So do you need a new value emitted on each array modification, or just create observable with initial values from this array? – Oles Savluk Sep 27 '17 at 09:10
  • 1
    I need the initial values of the array plus a new value emitted on each push to the array. Context: the array holds timeseries data for a chart with timestamps and values. I need to populate the chart with data of the past (initial array values) plus new streaming data (new data push to array). – a_b Sep 27 '17 at 09:15

1 Answers1

1

Because of Array.observe is obsolete I recommend you to model your entire state in RxJS. Here is the tutorial from documentation - Creating applications with RxJS

And implementation for your case:

const onPush$ = new Rx.Subject();
const onChange$ = new Rx.Subject();

const initialValue = [1, 2, 3];
const series$ = Rx.Observable
  .merge(
    onPush$.map(value => 
      series => {
        series.push(value);
        return series;
      }
    ),
    onChange$.map(({ index, value }) => 
      series => {
        series[index] = value;
        return series;
      }
    )
  )
  .scan(
    (series, makeNew) => makeNew(series),
    initialValue
  );
  
  
series$.subscribe(v => console.log(v));

console.log('push 10');
onPush$.next(10);

console.log('change 0th to be 9');
onChange$.next({ index: 0, value: 9 });

console.log('push 1000');
onPush$.next(1000);
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

Another hacky but still possible solution is to use ES6 Proxy. Something similar to this - Getter/setter on javascript array?

Oles Savluk
  • 4,315
  • 1
  • 26
  • 40