Tips for exchanging information between two distinct components within Angular across separate modules

How do I share data between 2 different components from 2 different modules?

I have a dashboard module and a preference module, each with their respective components: dashboard.component.ts and preference.component.ts

In order to pass data between these components, I created a bar.service.ts service with the following code:

private messageSource = 'orderView';

  changeMessage(message: string) {
    this.messageSource = message;
  }

The preference.component.ts file includes the following code:

this.bar.changeMessage('groupByView');

And the dashboard.component.ts contains:

console.log(this.bar.messageSource);

Both modules are accessed through routing, with the preference module displaying the preference page and the dashboard module displaying the dashboard page.

However, when a user is on the preference page and changes the messageSource to 'groupByView', it does not reflect on the dashboard page.

The dashboard page always shows the value 'orderView' in the messageSource.

Answer №1

To incorporate observables into your Angular project, you can utilize the built-in functionalities.

Here is an example of setting up a service (YourService):

@Injectable() // { providedIn: 'root' } ? read below
export class YourService {
  messageSourceSubject: BehaviorSubject<string> = new BehaviorSubject<string>('orderView');
  messageSource: Observable<string> = this.messageSourceSubject.asObservable();

    publishMessage(message: string): void {
      this.messageSourceSubject.next(message);
    }
}

Make sure to register your service in the root service (providedIn property of Injectable) or within the providers array of your root module.

When accessing data in TypeScript within your components:

constructor(public yourService: YourService) {
  this.yourService
    .messageSource
    .subscribe(message => console.log(message));
  // Remember to unsubscribe either on destroy (`subscription.unsubscribe` - subscribe returns it) or using `pipe(takeUntil(this.destroy))`, which is an RxJS operator from `rxjs/operators`.
}

If you want to display this data in HTML:

<div>{{ yourService.messageSource | async }}</div>

The async keyword represents an AsyncPipe, available in CommonModule from @angular/common. Using AsyncPipe automatically handles unsubscribing for you.

For components using the ChangeDetectionStrategy.OnPush mode, ensure Angular triggers change detection in the future by utilizing the ChangeDetectorRef dependency and calling its markForCheck method when necessary.

Answer №2

You can utilize the Subject feature.

View Demo

Bar Service Implementation:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs';

@Injectable()
export class BarService {

// Observable string sources
  private messageSource = new Subject<string>();
  messageSource$ = this.messageSource.asObservable();


  constructor() { }


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

}

Preference Component Logic:

import { Component, OnInit } from '@angular/core';
import { BarService } from '../bar.service';
@Component({
  selector: 'app-preference',
  templateUrl: './preference.component.html',
  styleUrls: ['./preference.component.css']
})
export class PreferenceComponent implements OnInit {

  constructor(private barService: BarService) { }

  ngOnInit() {

  }
  onChange() {
    this.barService.changeMessage(`Update dashboard at ${ new Date()}`)
  }

}

Preference Template Structure:

<p>
preference operational! 
<button (click)="onChange()">Refresh Dashboard</button>
</p>

Dashboard Component Setup:

import { Component, OnInit } from '@angular/core';
import { BarService } from '../bar.service';
@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {

  changeMessage: any;
 constructor(private barService: BarService) { }

  ngOnInit() {
    this.barService.messageSource$.subscribe((res)=>{
      this.changeMessage = res;
    });
  }

}

Dashboard Template Display:

<p>
dashboard functioning well! {{changeMessage}}
</p>

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

When an item in the accordion is clicked, the modal's left side scroll bar automatically scrolls to the top. Is there a solution to prevent this behavior and

When I first load the page and click on the Sales accordion, then proceed to click on Total reported and forecasted sales, the scrollbar jumps back up to the top The marked ng-container is specifically for the UI of Total reported and forecasted sales He ...

extract objects from an array of objects based on a specified array

Within my JSON array, I have data structured like this: const data = [ { "uniqueId": 1233, "serviceTags": [ { "Id": 11602, "tagId": "FRRRR", "missingRequired&quo ...

Preserve the timestamp of when the radio query was chosen

I'm interested in finding a way to save the user's selected answer for a radio button question and track the time they saved it. Is there a way to achieve this using HTML alone? Or would I need to utilize another coding language or package? Just ...

The HTTP GET request was successful, however, there is no data being displayed on the screen

I am currently facing an issue with fetching data from a web server. The data is retrieved successfully as I can see the object in the console log, but it does not render in the component template. export class CountrydetailsComponent implements OnInit { ...

Angular 7 - Creating tooltips with multiline text

I've utilized template strings to create a multi-line string. toolTip = ` ${Test} : ${number} ${Test} : ${number} ${Test} : ${number} ${Test} : ${number} ${Test} : ${number}}`; The issue I'm facing is that w ...

"Exploring the world of unit testing with Chutzpah and Jasmine in TypeScript

Currently, I am in the process of configuring Chutzpah and Jasmine to work together within visual studio. My main objective is to successfully run unit tests with TeamCity integration. Whenever I save my code, all TypeScript files are compiled into a sing ...

Tips for adding an item to an array within a Map using functional programming in TypeScript/JavaScript

As I embark on my transition from object-oriented programming to functional programming in TypeScript, I am encountering challenges. I am trying to convert imperative TypeScript code into a more functional style, but I'm struggling with the following ...

Why is the lifecycle callback not being triggered?

I am currently learning how to develop with Vue.js. I have been trying to use the lifecycle callbacks in my code. In my App.vue file, I have implemented the onMounted callback. However, when I run the code, I do not see the message appearing in the consol ...

PrimeNG editor: The value is not being displayed in the formControl

I am working with a component that includes a formGroup containing two controls: `enFormGroup: FormGroup = this.fb.group({ titleEn: ['test', Validators.required], textEn: ['hello world', Validators.required], });` Withi ...

Sending intricate JavaScript object to the controller. The array of objects is consistently empty

I am facing an issue with passing an object to my C# controller. While all the properties are getting populated correctly, the list I have always ends up with a count of 0. I've tried setting the header to content-type/json and using Json.stringify. F ...

Error: Unable to locate binding.gyp file

I'm currently in the process of setting up the required modules for my web application. As I execute $npm install, an error message pops up: john@mylaptop frontend % npm install > <a href="/cdn-cgi/l/email-protection" class="__cf_ ...

Issue with Angular @Input when navigating back in browser causing component to not render

Within the parent component, I am fetching a list of products from the store: // ... ngOnInit() { this.products$.subscribe(products => { this.products = products; }) } // ... <!-- ... --> <ng-container *ngIf="products"> ...

Retrieve a zip file using Angular RX and extract its contents

I am receiving a zip file from the backend and I need to extract its contents (which consist of a collection of JSON files for large offline data). API call: getOfflineTimetables() { let req = new Request(myOptions); return this.http.request(req ...

The function of edit does not exist

I'm currently working on creating a discord bot that will send a message to a specific channel upon startup. Initially, I was able to send the message to the designated channel without any issues. However, when I attempted to edit the message, an erro ...

Exploring the functionality of angular reactive forms in creating intricate JSON structures

After numerous attempts to resolve the issue on my own, I am reaching out to an Angular developer for assistance. My goal is to display a JSON object in the UI: Here is the JSON Object : items={"departure":"New York","arrival":"California","stations":[ ...

Update the js file by incorporating the import statement

Currently, I am in the process of transitioning to using imports instead of requires for modules. Here is an example of my previous code: const { NETWORK } = require(`${basePath}/constants/network.js`); The content of network.js file is as follows: export ...

How can we enhance the React.Component interface by adding a "direct" property?

Consider the following code snippet: interface Props extends React.HTMLAttributes { // ... } interface State { // ... } interface TextFieldComponent { field: HTMLInputElement | HTMLTextAreaElement } export default class TextField extends React.Co ...

Looping issue with ForEach in Typscript with Firebase Functions

While browsing through various questions on this topic, I've noticed that the specific answers provided don't quite fit my situation. My query involves converting a Google Firebase RTB datasnapshot into an array of custom objects, each representi ...

Show the distinct values of a mat-select element that retrieves information from an Angular filtered dataSource

Working on an Angular 9 app where data is displayed using a mat-table and filtered based on certain fields. The issue I'm facing is that the dropdown menu shows duplicate values, which is expected since some values may be repeated in the dataset. The ...

Retrieve the file from the input field

I have a requirement to retrieve an xls file and convert its content into json format. Currently, I am able to achieve this by specifying the file path directly in my code like below: var url = "D:/ionic/Docs/Test.xlsx"; However, I now need to allow ...