Ways to transfer an array between two unrelated components using a shared service and BehaviorSubject in Angular

I have been facing difficulties passing an array from one component to another. The issue arises when the array is passed between components and ends up being empty. Despite seeing integers in the console, the array is being passed before any values are pushed into it. After trying various approaches and conducting extensive research, I discovered that using BehaviorSubject as outlined in this discussion would be the best solution: Angular 4 pass data between 2 not related components

The only challenge is that the example given focuses on passing a string, while my requirement is to pass an integer array instead. We need to find a suitable example similar to the mentioned one but tailored for passing integer arrays. The service.ts acts as the shared service between compA and compB. In this case, compA is the component that should receive the array from compB, which holds the necessary array for passing to compA. So, which component should subscribe to the BehaviorSubject? Below is a simplified snippet of my code with commented lines indicating my progress towards implementing BehaviorSubject with an array.

Shared Service - service.ts

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpParams } from '@http';
    import { BehaviorSubject } from 'rxjs/BehaviourSubject';
    import { RootService } from '../../../common/root-service/root.service';


   @Injectable()
    export class service {
    
    //dataSource: BehaviorSubject<Array<number>> = new BehaviourSubject([]);
    //dataPlot = this.userDataSource.asObservable();


    dataPlot: Array<number> = [];

    

    constructor(private http: HttpClient, private appRootService: RootService) { }
    
    ... Some Code ...
    
    /**
    updateDataPlot(data) {
        this.dataSource.next(data);
    }
    */

    setDataPlot(data: Array<number>) {
        this.dataPlot = data; 
    }

    getDataPlot(): Array<number> {
         return this.dataPlot;
    }
}

ComponentA - compA.ts

import { Component, HostListener } from '@angular/core';
import { service } from '../../..common/service';
 
... Some Code...

@Component({
    selector: 'compA',
    styleUrls: ['./compA.css'],
    templateUrl: './compA.html'
})

export class compA {

... Some Code ...

dataPlotArray: Array<number>;

constructor(private sw: Service){
     this.getDataPlot();
}

... Some Code ...


getDataPlot() {
     this.dataPlotArray = this.sw.getDataPlot()
}

... Rest of Code ...

ComponentB - compB.ts

import { Component, HostListener } from '@angular/core';
import { service } from '../../..common/service';
 
... Some Code...

@Component({
    selector: 'compB',
    styleUrls: ['./compB.css'],
    templateUrl: './compB.html'
})

export class compB {

... Some Code ...

dataPlot: Array<number> = [];

constructor(private sw: Service){
     this.setDataPlot();
}

... Some Code ...

/**
setDataPlot() {
   this.sw.setDataPlot.subscribe((this.dataPlot) => { 
     this.sw.updateDataPlot(this.dataPlot);
  })
}
*/

setDataPlot() {
     this.sw.setDataPlot(this.dataPlot);
}

... Rest of Code ...

Answer №1

We can optimize the code by removing unnecessary mistakes and extra lines.

It's advisable to start class names with a capital letter for better practice. Additionally, avoid using methods like getDataPlot() and opt for an Observable instead.

Here is an improved version of your service:

...
@Injectable()
export class Service {
    
    dataSource$$: BehaviorSubject<Array<number>> = new BehaviorSubject([]);
    dataPlot$ = this.dataSource$$.asObservable();

    constructor(private http: HttpClient, private appRootService: RootService) { }
    
    ... Relevant Code Here ...
   
    updateDataPlot(data) {
        this.dataSource$$.next(data);
    }

}

Refactored Component A:

...

@Component({
    selector: 'compA',
    styleUrls: ['./compA.css'],
    templateUrl: './compA.html'
})

export class CompA {

  ... Modified Code ...

  dataPlotArray: Array<number>;

  constructor(private sw: Service){
    this.sw.dataPlot$.subscribe( data=> this.dataPlotArray = data);
  }

... Additional Code Changes ...
}

Revised Component B:

...

@Component({
    selector: 'compB',
    styleUrls: ['./compB.css'],
    templateUrl: './compB.html'
})

export class CompB {

... Updated Code ...

  dataPlot: Array<number> = [];

  constructor(private sw: Service){
    //fetch data here and assign it to dataPlot variable

    this.setDataPlot();
  }

  ... Adjusted Logic ...

  setDataPlot() {
     this.sw.updateDataPlot(this.dataPlot);
  }

}

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

Angular 4 not refreshing the view

I have encountered an issue where I am setting an array value in one component inside a subscribe method and then getting the values of that array in another component. After receiving the values, I set a flag in the component where I obtained the array va ...

Enhancing Angular functionality with the addition of values to an array in a separate component

I need help with adding a value to an array in the 2nd component when a button in the 1st component is clicked. I am working on Angular 4. How can I achieve this? @Component({ selector: 'app-sibling', template: ` {{message}} <butt ...

Which types of mouse events are compatible with Angular2?

Exploring mouse events in Angular2 has sparked my curiosity. I have implemented the click event, but now I wonder what other mouse events are available, such as mouseover. Where can I find a comprehensive list of mouse events supported by Angular2? The o ...

A guide to pulling out hues from a color scheme in Material 3

When working with Material 2 (Angular 17), I would extract colors using the syntax: mat.get-color-from-palette($primary, 800). How can this be achieved in Material 3 (Angular 18)? ...

Retrieve an array of specific column values from an array of objects using Typescript

How can I extract an array from an array of objects? Data var result1 = [ {id:1, name:'Sandra', type:'user', username:'sandra'}, {id:2, name:'John', type:'admin', username:'johnny2'}, ...

This marks my initial attempt at developing an Angular project using Git Bash, and the outcome is quite remarkable

I have a project named a4app that I am trying to create, but it seems to be taking around 10 minutes to finish and is showing errors. The messages displayed are quite odd, and I suspect there may be an issue with the setup. I have not yet used the app that ...

Guide on redirecting to the login page in angular2 when a process is left incomplete

I am facing an issue with the Popup used for device verification during login. When I click on the login button with valid credentials, a popup opens if the device is not trusted. Once I provide the necessary information and successfully validate, it shoul ...

I'm currently working on building a fresh window with Tauri 1.2, combining the powers of Rust, React, and Typescript. However, I've encountered a few

Utilizing Tauri's WindowBuilder in Rust, I attempted to create a new window. Despite successfully generating a blank window, I encountered challenges: The inability to display any content on the window The failure to close the window Being relativel ...

What is the best way to retrieve all keys from a deeply nested object using recursion

type NestedObject = { amount: number, error: string | null, data: { rows: [], messages: { goodNews: string | null, badNews: string | null } } } //attempting to recursively retrieve all keys type AllKeys<T, K extends keyof T> = T e ...

Issue with ESLint error in TypeScript PrimeReact async Button click handler

I am currently facing an issue with exporting data from a DataTable in PrimeReact. The onClick function for the Button does not allow async callbacks as flagged by eslint. Can someone guide me on how to properly call this function? const exportCSV = us ...

Facing issue in Angular 5 tutorial: Error encountered - module '@angular-in-memory-web-api' not found

While researching my issue, I came across a similar question related to angular2. However, the solutions provided were specific to angular2 or instructed me to run the same command that I am already using, prompting me to ask for help here. I am currently ...

Guide on creating a class with properties and their data types programmatically using TypeScript

For example, consider the following class that implements the ProjectAttrs interface: export class ProjectAttrsImpl implements ProjectAttrs { name: string; description: string | null; coordinates: string | null; } I am dealing with a large ...

Issues arise due to data inconsistency stemming from the combination of a for loop and .map() function within the BACK4APP

I seem to be facing a challenge with data consistency caused by the for (const object of results) {} loop in the Sandbox Link at line41. The issue is that the results are displayed as a single result after using the .map() method. However, when I perform a ...

Angular 2 applications with routing capabilities running within nested iframes

Currently, I am in the process of developing an Outlook add-in using Angular 2. Since it is an outlook hosted app, it will be run within a cross-domain iframe and I have no control over this setup. The iframe is also sandboxed with specific properties incl ...

Show a single image sequentially using Angular 8

I am facing an issue with displaying avatars for each object from a MongoDB database. Currently, when I display multiple objects, all the avatars are being displayed for each object instead of just one avatar per object. Here is the code snippet that I a ...

You may encounter an error stating "Property X does not exist on type 'Vue'" when attempting to access somePropOrMethod on this.$parent or this.$root in your code

When using VueJS with TypeScript, trying to access a property or method using this.$parent.somePropOrMethod or this.$root.somePropOrMethod can lead to a type error stating that Property somePropOrMethod does not exist on type 'Vue' The defined i ...

The magical transformation of Angular Charts.js creating a stunning masterpiece on a blank canvas

I encountered some difficulties while trying to implement angular charts.js on my dialog. Initially, I followed the steps outlined in a tutorial meant for Angular 5 found at this link: 's-build-an-Angular-5-Chart.js-App---Tutorial. I simply copied the ...

Tips for associating an identifier with a preexisting symbol in a TypeScript compiler transformer

Trying to implement a typescript compiler transform with the typescript compiler API has been challenging. Despite emitting new Identifier nodes to the final .js file, they appear to lack symbol binding information, resulting in incorrect output. For inst ...

Is there a way to determine the specific type of a property or field during runtime in TypeScript?

Is there a way to retrieve the class or class name of a property in TypeScript, specifically from a property decorator when the property does not have a set value? Let's consider an example: class Example { abc: ABC } How can I access the class or ...

Can you explain the distinction between using keyof within an indexer versus outside of it?

Consider the TypeScript snippet below: type ForwardVal<T> = { [K in keyof T]: string; }; type ForwardKeyOf<T extends string | number | symbol> = { [K in T]: string; }; type ByObj = ForwardVal<number[]>; // string[] ...