Component cannot subscribe to data source

社会主义新天地 提交于 2019-12-13 02:58:01

问题


I have this component listening for messages from a service. Note that every console.log() statement shown below is hit at least once, everything gets logged. That is, except "adding message to array" - that does not get logged, but it should get logged!

Here is the component:

import {Component, OnInit, Inject} from '@angular/core';
import {ChromeDataService} from '../../../../shared/services/events';


@Component({
  providers: [ChromeDataService],
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.scss']
})

export class EventsListComponent implements OnInit {

  isShowEventsList = false;
  events = [];

  constructor(private data: ChromeDataService) {
       console.log('events list component is constructed.');
  }

  ngOnInit() {
    console.log('events list component ngOnInit called.');
    this.data.currentMessage.subscribe(message => {
      console.log('adding message to array: ', message);
      this.events.push(message);
    })
  }

  showEventsList() {
    this.isShowEventsList = true;
  }

  hideEventsList() {
    this.isShowEventsList = false;
  }

}

here is the data source (an Angular service):

///<reference types="chrome"/>

import {Injectable, Component, Inject} from '@angular/core';
import {ReplaySubject} from "rxjs/ReplaySubject";

@Injectable()
export class ChromeDataService {

  private messageSource = new ReplaySubject<Object>();
  public currentMessage = this.messageSource.asObservable();
  private isListening: boolean = false;
  private listener: any;

  constructor() {

    const self = this;
    this.listener = function (msg, sender, sendResponse) {
      const parsed = JSON.parse(msg);
      console.log('extension received a message:', parsed);
      self.changeMessage(parsed);
    };
  }

  changeMessage(message: Object) {
    this.messageSource.next(message);
  }

  stopListening() {
    this.isListening = false;
    chrome.runtime.onMessage.removeListener(this.listener);
  }

  startListening() {
    this.isListening = true;
    chrome.runtime.onMessage.addListener(this.listener);
  }


}

does anyone know why when changeMessage() is called, that the subscribe() callback does not get invoked?

One big hint is that when I use new BehaviorSubject<Object>('initial'); instead of new Subject<Object>() - then initial does arrive and 'adding message to array' is logged.


回答1:


I monkey patched Chrome Messaging API with NgZone to update the view when app gets the response back from background page via chrome.runtime.sendMessage OR chrome.runtime.onMessage.
Here is the service I used in my chrome extension.

import { Injectable, NgZone } from "@angular/core";
import { Subject } from "rxjs/Subject";
import { Observable } from "rxjs/Observable";

/*
NgZone monkey patched chrome messaging service.
*/
@Injectable()
export class ChromeMsgSrv {

   constructor(private _ngZone: NgZone) { }

   public send(msg: any, cb: (resp: any) => any) {
      chrome.runtime.sendMessage(msg, (resp: any) => {
         this._ngZone.run(() => cb(resp))
      })
   }

   public onMsg(cb: (msg: any) => any) {
      chrome.runtime.onMessage.addListener((msg: any) => {
         this._ngZone.run(() => cb(msg))
      })
   }

}

@Olegzandr, I got here on this thread from DevKit.life. I wanted to contact you for the solution to this problem but couldn't found any contact-us page on your website (assuming Devkit.life is yours). Also, the backlink to this post is in a plain text and not an anchor or clickable element. Hopefully, you would correct these issue present on your website.




回答2:


In short, because I was calling providers:[ChromeDataService] in more than one place, my service was being created more than once. So I was subscribing to the wrong service.

See:

@Injectable service does not seem to be a singleton




回答3:


Try this:

changeMessage = (message : Object) => {}

And use Subject instead of replay.



来源:https://stackoverflow.com/questions/48143275/component-cannot-subscribe-to-data-source

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!