Child component in Angular2 makes an observer call to its parent object

Let me try to explain this in the best way possible.

I have a service that includes an observable class responsible for updating itself. This observable class needs to be pushed out to the app using the observer within the service. How can I trigger that observer from the child without creating a dependency loop?

Here's a simplified example:

class MyService {
  subClass$: Observable<SubClass>;
  _subClassObserver: Observer<SubClass>;

  constructor(private _subClassStore: SubClass){
    this.subClass$ = new Observable(observer => {
      this._subClassObserver = observer
    }).share();
  }

  pushData(){
    this._subClassObserver.next(this._subClassStore)
  }
}

class SubClass {
  displayData: string;
  displayData2: number;

  constructor(){
    socket.on('setData', function(obj){
      this.displayData = obj.dd1;
      this.displayData2 = obj.dd2;
      //How can I call pushData() in MyService from here to update the app with data?
    }
  }
}

The _subClassStore is updated through a stream received from socket.io. How can I notify MyService when the SubClass data changes, so it can push it using _subClassObserver.next(_subClassStore)?

UPDATE: I've added more details to the above example to demonstrate their relationship and usage.

SubClass acts as a listener for data streams from socket.io and stores the information in the class. It begins listening upon the construction of MyService.

The objective of MyService is to offer multiple such sub classes that can be subscribed to throughout the app. Each one allows access to a different data stream and its associated data, but all are contained within a single service.

The main question remains how to invoke the pushData() function in the parent to keep the stream updated for subscribers in the app.

Update 2:

This might provide some clarity. Below is how it would be written as a service without the sub class. The reason for not adopting this approach is the need to manage a significant number of these listeners stored to Observables. Abstracting them into classes simplifies the management of information, but I'm struggling with pushing it to the app:

class MyService {
  class1$: Observable<DataStream>;
  _class1Observer: Observer<DataStream>;
  _class1Store: DataStream;

  constructor(){
    this._class1store = {displayData: 'hello', displayData2: 0};

    this.class1$ = new Observable(observer => {
      this._class1Observer = observer
    }).share();

    socket.on('setData', function(obj){
      this._class1Store.displayData = obj.dd1;
      this._class1Store.displayData2 = obj.dd2;
      this._class1Observer.next(this._class1Store)
    }
  }

interface DataStream = {
   displayData: string;
   displayData2: number;
}

Answer №1

It's recommended to use ()=> instead of function(obj). Otherwise, the context of this may not correctly refer to the MyService instance.

  constructor(){
    socket.on('setData', (obj) =>{
      this.displayData = obj.dd1;
      this.displayData2 = obj.dd2;
      //How can we invoke pushData() in MyService from this point to send data to the app?
    }
  }

There is a possibility that socket could operate outside Angular's zone. It's worth considering:

  constructor(zone: NgZone){
    socket.on('setData', (obj) =>{
      zone.run(() => {
        this.displayData = obj.dd1;
        this.displayData2 = obj.dd2;
        //How can we trigger pushData() in MyService from here to send data to the app?
      });
    }
  }

In order for SubClass to call a method in MyService, it requires a reference to MyService.

class MyService {
  subClass$: Observable<SubClass>;
  _subClassObserver: Observer<SubClass>;

  constructor(private _subClassStore: SubClass){
    _subClassStore.myService = this;
    this.subClass$ = new Observable(observer => {
      this._subSubClassObserverver
    }).share();
  }

  pushData(){
    this._subClassObserver.next(this._subClassStore)
  }
}

class SubClass {
  displayData: string;
  displayData2: number;
  myService: MyService;

  constructor(zone: NgZone){
    socket.on('setData', (obj) =>{
      zone.run(() => {
        this.displayData = obj.dd1;
        this.displayData2 = obj.dd2;
        this.myService.pushData();
      });
    }
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Looking to compare two elements within different arrays? The method outlined below is specifically designed for comparing to individual values rather than entire arrays

Is this the right approach? How can we iterate through each array to compare values? Should these data structures be modified or transformed first? Below is the data that needs to be compared. The objective is to match userID with DocumentID. const videos ...

Assistance with jQuery in Javascript is needed

Currently, I am in search of an effective vertical text scroller. My desired scroller would move vertically in a continuous manner, ensuring there is never any empty space while waiting for the next text to appear. I am open to using either JavaScript or ...

The readyState is stubbornly refusing to reach 4

I have been working on developing a dynamic AJAX search bar that interacts with my database. Below is the code I have been using. function getXmlHttpRequestObject(){ if(window.XMLHttpRequest){ return new XMLHttpRequest(); } else if (window.ActiveXObj ...

The issue with onclientclick in Asp.Net button

I am experiencing a peculiar problem that I cannot seem to solve. The issue revolves around a button that I have implemented using the following code: <asp:Button ID="btnSave" runat="server" ClientIDMode="Static" Text="Save" OnClientClick="return Confi ...

How to Utilize Muuri Javascript Library with Bootstrap Tabs: Resizing Required for Expansion?

Struggling for days and feeling frustrated, I'm hoping someone can help me crack this mystery. My idea is straightforward - three Bootstrap 4 tabs with drag and drop functionality inside each, all displayed in a responsive stacked masonry layout. To a ...

Can text be inserted into an SWF file using ASP.NET or Javascript via an online platform?

I am managing a website that features videos created by a graphic designer who updates and adds new content regularly. I am looking to add dynamic text to these videos after a specific amount of time, such as "Hosted by XXX". However, I am hesitant to ask ...

Is there a way to extract data from the Redux state in a React component?

Seeking assistance with making an API request from Redux, followed by saving the data in my React state (arrdata). Although the API call is successful, I am facing challenges updating the App.js state based on the Redux API call. Any suggestions or insig ...

Checking connectivity in an Ionic application

Within my Ionic application, I am faced with the task of executing specific actions depending on whether the user is currently connected to the internet or not. I plan on utilizing the $cordovaNetwork plugin to determine the connectivity status within the ...

Limiting the number of items shown in the dropdown panel of an NgSelect

Currently, I am utilizing Angular ngselect to showcase a dropdown menu with multiple options. However, due to the limited screen space, I need to restrict the number of items visible in the dropdown to about 3, allowing users to scroll through the rest. W ...

Angular nested lists with drag and drop functionality

Recently, I've been working on creating a drag and drop dashboard and stumbled upon an amazing nested list at this link. This particular implementation uses the AngularJs JavaScript framework. However, since I don't have much experience with it, ...

When dealing with errors in fetching JSON data, consider implementing a robust error handling strategy and

Is there a way to provide a fallback JSON string in case the fetch URL fails to connect? const Response3 = await fetch(`https://example.com/match/get?_=&id=${matchlist[2].id}`) ...

Maintain checkbox selection even after leaving the page

I am looking for a way to maintain the state of a checkbox even after navigating away from the page in an AngularJS and bootstrap environment. Currently, I find that my bound variable gets reset to false every time I reload the page when the controller run ...

Check to see if the property of the object does not exist within the array and update as

My goal is to add the variable content into the database content using the $push method, but only if the content.hash doesn't already exist in the database. I want to avoid duplicating information unnecessarily. return shops.updateAsync({ "user": u ...

Combining 2 objects in vue.js that share a common field name

Currently, I am attempting to merge two objects based on a shared key, specifically when they have two fields with the same name but differing values. var players = [{ id : 'a', name : "player1",team:1},{ id : 'b', name : &quo ...

Altering various HTML components with every swipe of SwiperJS

I am new to working with JavaScript and I have integrated a Swiper JS element into my HTML page. Here is the current code I am using: <head> <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css&quo ...

What is the best way to upload a canvas image from a GUI to the back-end using an AJAX call and setting the content-type as "image/jpeg"?

What is the best method for saving a canvas image from GUI to back-end using an AJAX call that accepts content type "image/jpeg" and avoids the error "jquery.js: 8453 Uncaught TypeError: Illegal invocation?" HTML <canvas id="myImage"></canvas> ...

Is it possible to enforce strict typing for a property within an object that is declared as type 'any'?

In my code, I am dealing with a parent object of type 'any' that remains constant and cannot be changed. Within this context, I need to define a property for the parent object, but no matter what I try, it always ends up being loosely typed as &a ...

Exploring the capabilities of require() in nodeJS

I'm wondering about the inner workings of the require() function in a nodeJS application. What exactly does require() return? Let's say I want to utilize two third-party packages: lodash and request. After installing these packages, my code mig ...

Creating a unique Angular filter involves combining different techniques and functionalities to tailor

Hey there! I'm just diving into the world of Angular JS and I'm looking to filter any Twitter text that comes back containing a hashtag, and turn that word into a clickable link. For example: If the returned twitter text is "The quick brown #f ...

AngularJS: Pause the data binding functionality temporarily

How can I temporarily deactivate data binding in AngularJS? I am working with a list called items that is being displayed using ng-repeat. I need to perform some operations on this list without immediately updating the page, as this could cause slowdown. ...