Search code examples
angulartypescriptangular7openlayers-5rxjs-observables

The Observer seems not to be executed whenever the observable is changing its value


The observer seems to initialize the subscription just fine. However, when the value of the layer changes the observer doesn't execute the function it supposes to. Am I missing something?

You can check my repository on github: https://github.com/stefiHB/ol-angular-ionic

layer-msg.service.ts

import { Injectable } from '@angular/core';
import {BehaviorSubject, Observable, Subject} from 'rxjs';
import {customMapLayers} from './customMapLayers';

@Injectable({
  providedIn: 'root'
})
export class LayerMsgService {

  private layer = new BehaviorSubject<customMapLayers>(customMapLayers.pwd);

  constructor() { }

  getLayer() {
    return this.layer.asObservable();
  }

  setLayer(mapLayer: customMapLayers) {
    this.layer.next(mapLayer);
    console.log('Setting new value...', this.layer.value);
  }
}


MyButtons.ts

import {LayerMsgService} from './layer-msg.service';
import {customMapLayers} from './customMapLayers';


export class MyButton {

  private layerService: LayerMsgService;
  buttonPWD: HTMLButtonElement;
  buttonOSM: HTMLButtonElement;
  myElement: Element;

  constructor(el: Element) {
    this.layerService = new LayerMsgService();

    this.buttonPWD = document.createElement('button');
    this.buttonPWD.innerHTML = 'pwd';
    this.buttonOSM = document.createElement('button');
    this.buttonOSM.innerHTML = 'osm';

    this.buttonOSM.addEventListener('click', () => this.changeLayer(customMapLayers.osm));
    this.buttonPWD.addEventListener('click', () => this.changeLayer(customMapLayers.pwd));

    el.appendChild(this.buttonPWD);
    el.appendChild(this.buttonOSM);
  }

  changeLayer(l: customMapLayers) {
    console.log('Request for Changing layer...');
    this.layerService.setLayer(l);
  }


}

app.component.ts

import {Component, OnDestroy, OnInit, Renderer2} from '@angular/core';
import {LayerMsgService} from './layer-msg.service';
import {Subscription} from 'rxjs';
import {MyButton} from './MyButton';
import {customMapLayers} from './customMapLayers';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
  title = 'ObservablesMashup';
  layer: customMapLayers;

  layerSub: Subscription;
  private myBtn: MyButton;

  myText: Element;

  constructor(private layerService: LayerMsgService) {

    this.layerSub = this.layerService.getLayer().subscribe(
      l => {
        if (l) {
          console.log('Getting layer... ', l);
          this.layer = l;
        }
      });
  }

  ngOnInit(): void {
    const el = document.getElementById('map');
    console.log(el);
    this.myBtn = new MyButton(el);
    this.myText = document.getElementById('p1');
  }

  ngOnDestroy(): void {
    this.layerSub.unsubscribe();
  }
}


I tried to use btn.onclick = (event) => {...} but it doesn't seem to fix the problem.

I expect the console to log:

Request for Changing layer...
Setting new value... PWD
Changing Layer... PWD

but the function of the observer is not being executing so this is the actual log when i click on the buttons:

Request for Changing layer...
Setting new value... PWD

Solution

  • The solution was simple. I was misdirected in the beggining because of the documentation. According to this url:

    https://angular.io/tutorial/toh-pt4#provide-the-heroservice

    "When you provide the service at the root level, Angular creates a single, shared instance of HeroService and injects into any class that asks for it. "

    I thought that the LayerMsgService was shared among all the classes. However, I had to give it as an argument in the MyButtons class.

    layer-msg.service.ts

    constructor(el: Element, layerMsgService : LayerMsgService  ) {
    // code...
    }