jScheq
jScheq

Reputation: 21

How can I take access to property type BehaviorSubject from service?

I have a TttService service. It has a cells property. This is an array of objects. It changes only on the client. One component subscribes to its changes, the other component changes it. I want to make makeMove() change one of the properties of the desired object in the cell array and that the component that is signed on the cell should get these changes. How can this be realized?

If in method makeAMove() to make console.log(this.cells) - there will be empty. In this case, the component that was subscribed to cells through the initCells() method gets modified for the first time.

My service

import { Injectable } from '@angular/core';
import { TttServiceInteface } from '../interfaces/ttt-service-inteface';
import { CellInteface } from '../interfaces/cell-interface';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { asObservable } from './asObservable';

@Injectable()
export class TttService {
  public cells: BehaviorSubject<CellInteface[]> = new BehaviorSubject([]);

  constructor() { }

  initCells(fieldSize: number, fieldWidth: number): Observable<CellInteface[]> {
    const cells = [];

    for (let i = 0; i < fieldSize * fieldSize; i++) {
      cells.push({
        width: fieldWidth,
        height: fieldWidth,
        id: i
      });
    }
    this.cells.next(cells);

    return this.cells;
  }

  getCells() {
    return asObservable(this.cells);
  }

  makeAMove(id: number) {
    this.getCells()
      .subscribe((c: Array<CellInteface>) => {
        c.forEach(cell => {
          if (cell.id === id && !cell.id) {
            cell.value = 1;
          }
        });
        this.cells.next(c);
    });
}

My component

ngOnInit() {
    const border = (window.screen.availHeight - 150);
    this.fieldSize = 5;
    this.border = border + 100;

    this.tttService
      .initCells(this.fieldSize, border / this.fieldSize)
      .subscribe(cells => {
        console.log(cells);
        this.cells = cells;
      });
  }

Upvotes: 2

Views: 1351

Answers (1)

Anuradha Gunasekara
Anuradha Gunasekara

Reputation: 6983

Try this.

In your service.

 private cells: BehaviorSubject<CellInteface[]> = new BehaviorSubject([]);
 private arrayOfCells: CellInterface[];

 public initCells(fieldSize: number, fieldWidth: number): void {

    for (let i = 0; i < fieldSize * fieldSize; i++) {
      this.arrayOfCells.push({
        width: fieldWidth,
        height: fieldWidth,
        id: i
      });
    }
    this.cells.next(this.arrayOfCells);
  }

 public getCells(): Observable<CellInteface[]> {
    return this.cells.asObservable();
  }

  public makeAMove(id: number) {
    this.arrayOfCells.forEach(cell => {
      if (cell.id === id && !cell.id) {
        cell.value = 1;
      }
    });
    this.cells.next(this.arrayOfCells);
  }

In the subscribing component.

constructor(private tttService: YourService ) {
   this.tttService.getCells().subscribe((cells: CellInteface[]) => {
      // you can use cells variable in here. 
    });
}

In the data setting component.

constructor(private tttService: YourService ) {
       const border = (window.screen.availHeight - 150);
       this.fieldSize = 5;
       this.border = border + 100;

       this.tttService.initCells(this.fieldSize, border / this.fieldSize);

  //or you can call the makeAMove method.
       this.tttService.makeAMove(id).subscribe((res) => {
          // you get the updated cell array as res
       });
  }

Upvotes: 1

Related Questions