Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to add an object to an observable of array

I have an angular project with a service called BookService.

private books: Subject<Book[]>;

getBookList(skip:number = 0,limit:number = 0): Subject<Book[]> {
  return this.books;
}

addBookToList(book:Book) {
}

this service help me to monitor the changes in a list of books, I also want to be able to add a single book to the list using the addBookToList function but I dont know how to add a single book the this observable (the subject-observer) is it possible to add a single book

like image 326
Yedidya kfir Avatar asked Aug 15 '18 18:08

Yedidya kfir


People also ask

How do you map an array to an observable?

To convert from array to observable you can use Rx. Observable. from(array) . To convert from observable to array, use obs.

Is an observable an array?

An observable produces values over time. An array is created as a static set of values. In a sense, observables are asynchronous where arrays are synchronous.

How do you create an observable object in Angular 8?

We can use the observable constructor to create an observable stream of any type. The observable's subscribe() executes with the constructor argument. The Observer object received by a subscriber function then publishes values using the observer's next() method. Add or modify the RxJS import to add Observer function.

Can you subscribe to an observable?

Executing an Observable But the observable function does not emit any values until it is executed. The subscribe() method calls the observable's function that produces and emits data. Thus, subscribing to an observable starts a flow of data between the observable and the observer.


1 Answers

A subject is a type of observable. As such, it is a stream. You can add an item (such as a book) to the stream and the item will be broadcast to any observers of the stream.

However, it is not like a normal array. Once the item is added to the stream and broadcast, it will no longer be accessible in the subject's "list". It will only be accessible in the components that subscribed to this Subject.

To add something to the subject's stream:

 this.books.next(book);

This adds it to the stream and broadcasts it to all existing subscribers.

If you want to keep a "cache" of books, consider defining your books as a simple array and not as the Subject.

Here is an example of one of my services:

export class MovieService {
  private movies: Movie[];

  private selectedMovieSource = new Subject<Movie | null>();
  selectedMovieChanges$ = this.selectedMovieSource.asObservable();

  constructor(private http: HttpClient) { }

  changeSelectedMovie(selectedMovie: Movie | null): void {
    this.selectedMovieSource.next(selectedMovie);
  }

  // more code here
}

Notice that my movies is an actual array that contains my "cache" of movies. The Subject is set as a separate property.

You can see my complete example here: https://github.com/DeborahK/MovieHunter-communication/tree/master/MH-4

Check out the movie.service.ts and the movie components that call it.

UPDATE:

Another option would be to instead use a BehaviorSubject which maintains the value of your Subject and can be referred to at any time:

private books: BehaviourSubject<Book[]> = new BehaviorSubject<Book[]>([]);

getBookList(skip:number = 0,limit:number = 0): BehaviorSubject<Book[]> {
  return this.books;
}

addBookToList(book:Book) {
  // apply the current value of your books Subject to a local variable
  let myBooks = this.books.getValue();
  // push that book into your copy's array
  myBooks.push(book);
  // apply the local updated array value as your new array of books Subject
  this.books.next(myBooks);
}

Note that this adds the entire array of books to the stream each time.

like image 136
DeborahK Avatar answered Oct 13 '22 03:10

DeborahK