Search code examples
rxjsreactivex

RxJS Google Maps Markers


I'm trying to retrieve only new "Google Map" Markers from DataBase by utilizing RxJS observables and jQuery $.ajax

I'm receiving an array of markers every 5 seconds. When the data inside the array has been changed, i.e new markers appended, I need to filter out only new markers.

var oldArray = [["ObjA",3455,643523,2],["ObjB",5346,2134,1],["ObjC",5341,7135,0]];
var newArray = [["ObjA",3455,643523,2],["ObjD",2384,4791,3],["ObjB",5346,2134,1],["ObjC",5341,7135,0],["ObjF",2631,7228,4]];

So here from newArray I need to filter out ["ObjD",2384,4791,3] and ["ObjF",2631,7228,4]

I have no clue how it can be done, and can it be done at all by utilizing only RxJS.

I would really appreciate if someone could lead me in the right direction!

var observable = Rx.Observable
  .interval(5000)
  .flatMap(function() {
    return Rx.Observable
      .from($.ajax({url: "https://somedomain.com/json"}).promise())
  })
  .filter(x => !!x === true)
  .distinctUntilChanged();


observable.subscribe((response) => {
      var newMarker = $.parseJSON(response.data);                    
});

Solution

  • For working on arrays, you don't need RxJS, you can use the new array operators in ES6:

    onlyNewArray = 
        newArray
            .filter(newItem => 
                !oldArray.some(oldItem => oldItem[0] === newItem[0]));
    

    some() will go through the items in the array one by one and if any fulfill the criteria it will return true. Here we check if each of the items in newArray is present in the old, and if they are don't include them in onlyNewArray


    Update

    This will check if all items in oldItem are equal to the corresponding item in newItem:

    onlyNewArray = 
        newArray
            .filter(newItem => 
                !oldArray.some(oldItem => 
                    oldItem.every((prop, index) =>
                        prop === newItem[index])));
    

    Update 2

    To only check a consecutive part of the array, you can slice it first:

    onlyNewArray = 
        newArray
            .filter(newItem => 
                !oldArray.some(oldItem => 
                    oldItem
                        .slice(0,3)
                        .every((prop, index) =>
                            prop === newItem[index])));
    

    Alternatively, you can provide an index to skip and then use a simple if/else clause:

    let dontCheck = 1;
    
    onlyNewArray = 
        newArray
            .filter(newItem => 
                !oldArray.some(oldItem => 
                    oldItem.every((prop, index) => {
                        if(index == dontCheck){
                            return true;
                        } else {
                            prop === newItem[index]
                        }
                    })));