Liam Clarke
Liam Clarke

Reputation: 263

How to merge 2 objects that contain an array of objects each?

I have an observable that gets data from an API, this is hooked up to a paginating feature. How do I add the response data object on to the variable which holds the first pages data. Essentially what Array push does.

Right now each pagination will send a request to the API, even the previous pages since I am overwriting the data. I would like to add the array of objects (data.articles) on to the end of the category that is selected.


data = {
   general: undefined,
   business: undefined,
   entertainment: undefined,
   health: undefined,
   science: undefined,
   sports: undefined,
   technology: undefined
};

this.newsService.getNews(endpoint, params).subscribe(data => {
   this.data[category] = data.articles;
});

I expect the data to work like this:

If i show 1 article on the general tab, data.general will hold an array with one object in it. When i click next page, data.general should hold an array with 2 objects in it, and so on.

Solution

Array.prototype.push worked, for some reason when i initially tried this it didn't work. But i think that was because it was undefined initially. The below however works fine.

if (!this.data[category]) {
   this.data[category] = data.articles;
} else {
   Array.prototype.push.apply(this.data[category], data.articles);
}

Upvotes: 0

Views: 179

Answers (2)

DeborahK
DeborahK

Reputation: 60518

I know you have already accepted an answer, but if you were interested in retaining the data in streams instead of in arrays, you can do something like this:

  // Action Stream
  private productInsertedSubject = new Subject<Product>();
  productInsertedAction$ = this.productInsertedSubject.asObservable();

  // Merge the streams
  productsWithAdd$ = merge(
    this.products$,                       // Original stream of data
    this.productInsertedAction$           // New data
  )
    .pipe(
      scan((acc: Product[], value: Product) => [...acc, value]),
      catchError(err => {
        console.error(err);
        return throwError(err);
      })
    );

And if you were adding an array instead of a single value, the technique would be similar.

Upvotes: 1

William Gunawan
William Gunawan

Reputation: 750

Try this, maybe this is what you want.

Array.prototype.push.apply(this.data[category], data.articles); 

Above code will merge to array of objects into one and set to this.data[category]

Upvotes: 1

Related Questions