Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Append items to an observable array in Angular2?

I have a service that fetches documents and list their metadata on a page which works fine. I want to implement "infinite scrolling" and looked at npm i angular2-infinite-scroll

At the moment I'm using an observable for the documents and the async pipe in an *ngFor loop

document-list.ts

export class DocumentList implements OnInit {
    documents: Observable<Array<Document>>;
    chunck: number = 100;
    from: number = 0;
    keyword: string = "";

    constructor(private _documentService: DocumentService) {}

    ngOnInit() {
    this.documents = this._documentService.getDocuments(this.chunck, this.from, this.keyword);
    }
}

With angular2-infinite-scroll I have a function that's called when I scroll to the bottom of the page, what I am trying to do is to fetch more documents and present their metadata on the page with what's already there

onScroll() {
this.from = documents.length ... ?
//this.documents = this._documentService.getDocuments(this.chunck, this.from, this.keyword);
}

I am not sure if this is possible when I'm using an observable? If I use a simple array for documents instead documents: Document[] I can do something like

onScroll() {
this._documentService.getDocuments(this.chunck, this.from, this.keyword)
    .subscribe(documents => this.documents.push(documents));
}

Any other ideas?

like image 407
John Doe Avatar asked Dec 10 '25 13:12

John Doe


1 Answers

You can try it with a Subject rather than an Observable. I would try something like...

For your DocumentsService:

import { Subject } from 'rxjs/Rx';

export class DocumentService {
  _documentSubject = Subject.create();

  getNextTen() {
    // ... get the document meta data however ... 
    this._documentSubject.next(documentMetaData);
  }

  get documentSubject() {
    return this._documentSubject;
  }

  //...
}

And then on your documents component, you'd do:

 // ...
documents: Array = [];
documentRetriever: Subject<any>;

constructor(ds: DocumentService) {
  //You maybe shouldn't do this in the constructor, but the point is
  //you only want to subscribe to the Subject once.
  this.documentRetriver = ds.documentSubject;
  this.documentRetriever.subscribe(newDocuments => {
    this.documents.push(newDocuments);
  })
}
onScroll() {
  this.ds.getNextTen();
}

Because of the nature of RxJS Subjects (they act as both Observables and Observers), you can pass data via .next() outside of the creation of the Observable.

You may or may not still need to use the async pipe when binding to the documents array.

For more info on Subjects:

ReactiveX Docs

Getting started with RxJS: Subjects

like image 108
ABabin Avatar answered Dec 13 '25 08:12

ABabin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!