Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to subscribe to array change?

I am wondering if it's possible to subscribe to a change object, that is an array. My use case is the following: user reloads a page, that requires the whole collection to be loaded, and then get one object with a specific id. As I know, I can create a function like this:

In constructor:

this.getById(id);

And the function

getById(id: string){
    this.object = this.objectsService.getById(id);
    if (this.object.name){ //check if object exist
        //Do something
    } else {
        setTimeout(()=>{
            this.getById(id)
        }, 1000);
    }
}

However, I got a feeling that this is not the best thing to do. So, what I would like to do is something like this:

let objects = this.objectService.getObjects() // returns object that will hold the collection;
objects.subscribe((value) => { 
    if(value.length) {
        //Do something
    }
});
like image 828
uksz Avatar asked Jul 29 '16 09:07

uksz


2 Answers

You can store a reference to your data array instead of Observable. For example when the call from the http service return with Observable, you can do

function getObjects:Promise<Item[]>{
        return this.http.get(this.apiUrl)
                      .toPromise()
                      .then(this.extractData)
    }

    private extractData(res: Response) {
      let body = res.json();
      return body.data || { };
    }

In your component class, you can store data like this:

this.objectService.getObjects().then(items=> this.items = items);

Next, when you need to get an item by its id, you can do:

let currentItem = this.items.filter(x=> x.id == currentId)

By doing that way you have the list cached when your page loads and have the value ready when users's selection is changed.

like image 97
Toan Nguyen Avatar answered Oct 05 '22 04:10

Toan Nguyen


If I am understanding your question correctly, you are looking to create an observable from an array so you can subscribe to it? If so, you might be looking for Rx.Observable.from(iterable, [mapFn], [thisArgs],[scheduler]. There is a page in the rxjs docs about this.

It creates an observable from an Array, to which you can then subscribe.

Something like this might be what you are looking for

 Rx.Observable.from([1,2,3]).subscribe(x => // do something with x);

Subscribe to changing array

As pointed out in the comments, the above approach subscribes to the array and observes the values that are currently in the array, but it does not deal with changes to this Array.

Perhaps an approach here would be to create a subject, and observe the subject. Instead of pushing values to the existing arrays, you push values to the Subject (which holds basically an array of the elements). When you push to the Subject, you generate an event that can be caught by a subscriber.

like image 37
Dylan Meeus Avatar answered Oct 05 '22 03:10

Dylan Meeus