H
H
HellYeahOmg2019-05-05 21:54:31
Angular
HellYeahOmg, 2019-05-05 21:54:31

How to make reactive data in Angular service?

The service contains an array with books and a book to be edited. When changing (adding) a book for editing in the service, it is necessary that the component into which the service is "injected" also receives the change.
At the moment, my code does not work, although there is another component that calls getBooks in the constructor in the same way and saves it locally, where the data is updated every time the array changes in the service.
Is it necessary to use rxjs here?

Service
import { Injectable } from "@angular/core";
import { Book } from "../models/book/book";

@Injectable({
  providedIn: "root"
})
export class BooksService {
  private books: Book[];

  private editingBook: Book; // book that needs to edit

  constructor() {
    this.books = JSON.parse(localStorage.getItem("books")) || [];
  }

  getBooks(): Book[] {
    return this.books;
  }

  getEditingBook(): Book {
    return this.editingBook;
  }

  addBook(book: Book): void {
    this.books.push(book);
    this.saveChanges();
  }

  deleteBook(book: Book): void {
    const index = this.books.findIndex(item => item.author === book.author);
    this.books.splice(index, 1);
    this.saveChanges();
  }

  editBook(book: Book): void {
    this.editingBook = book;
  }

  private saveChanges(): void {
    localStorage.setItem("books", JSON.stringify(this.books));
  }
}

Component
import { Component } from "@angular/core";
import { Book } from "src/app/models/book/book";
import { BooksService } from "src/app/services/books.service";

@Component({
  selector: "app-form",
  templateUrl: "./form.component.html",
  styleUrls: ["./form.component.sass"]
})
export class FormComponent {
  newBook: Book = {
    author: "",
    title: "",
    year: 0,
    pages: 0
  };

  editingBook: Book;

  constructor(private src: BooksService) {
    this.editingBook = this.src.getEditingBook(); // не обновляется
  }

  handleNewBook(): void {
    this.src.addBook(this.newBook);
    this.resetNewBook();
  }

  private resetNewBook(): void {
    this.newBook = {
      author: "",
      title: "",
      year: 0,
      pages: 0
    };
  }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Shvets, 2019-05-05
@HellYeahOmg

Look, in order for the data to be visually displayed, it is necessary that the detection of changes in this component work.
In the case of using rxjs, calling subscriptions initiates change detection (well, actually a little more complicated, but that's okay), but if you just change the object, then no. You'll have to track these things manually somehow.
Most likely in this component there is some kind of interaction with the user, the generation of events.
Is it possible to work with Angular but not use rxjs? Can. For example, to pull some event, and the component will listen to it and execute detectChanges. You can adapt mobx to this case, for example. You can attach some crutches like vuex, i.e. make setters that update the component. Or an effect in redux.
Should I work with Angular but not use rxjs? Certainly not. In the service, store data as a stream (subjects and their derivatives) or shareReplay, or use some add-ons, such as ngrx and others.
Rxjs is closely related to Angular itself and is used almost everywhere, if you don't know rxjs, you don't know Angular.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question