1

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
skassi
  • 79
  • 8

2 Answers2

1

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...
}
skassi
  • 79
  • 8
0

The function setLayer from the service is in charge of emitting new values.

It's called in the controller.changeLayer function, which itself is called on button clicks, defined a bit earlier.

if the stream doesn't make a new event, it probably means that the buttons aren't doing their job.

Seeing that you use addEventListener, i would first tell you to change to btn.onclick = (event) => {...} to try it.

if it still doesn't work, try seeing if button clicks work, and if they don't, it means you either don't click on the right ones, or you are outisde of Angular's context (see NgZone)

  • ```btn.onclick = (event) => {...}``` doesn't seem to fix the problem. But either way the buttons I think they work(?). The ```controller.changeLayer``` is been executing. Also the setLayer() in map.service.ts is been executed, because it logs in the console the message: "Setting new value...' and prints the correct value. – skassi Oct 07 '19 at 09:32
  • @skassi could you provide a [mcve] of your issue ? It's hard to help you without any evidence that it doesn't work ... Other than that, I don't see what's wrong ! –  Oct 07 '19 at 09:43
  • I tried that before posting a question here but I couldn't make a minimal reproducible example. However I will give it one more try. I also posted my GitHub repository with that particular project, so you can download it if you have the time. Anyway, I will try again the minimal reproducible example. Thanks. – skassi Oct 07 '19 at 09:52
  • @skassi I'm on a corporate computer, I am limited by a firewall (and we use bitbucket ... Yay). For a [mcve], you can mock most of your code, as long as the issue is reproduced. If you can't manage to make it, then it probably means you have a typo/error somewhere ! So go from your [mcve], and rebuild your components/services so that they work. –  Oct 07 '19 at 09:57
  • I've tried to provide a more minimal reproducible example. Same problem with the observer in the ```app.component.ts``` – skassi Oct 07 '19 at 10:57