Can I modify a global array by updating a dynamically created array in the ngOnInit method of Angular?

Are there any suggestions on how to make a dynamic array available globally in Angular? I am currently using this codepen () which stores clicked countries in an array.

The issue is that the array is nested within a function in ngOnInit and I need it to be accessible globally to share between components. I have tried moving the empty array outside the function and making it equal to a global variable without success. Is there a way to update a global array from this nested position?

Map Component

import { Component, OnInit } from '@angular/core';
import { Router, RouterModule, ActivatedRoute } from '@angular/router';
import { AmChartsService } from "amcharts3-angular2";

declare var AmCharts : any;

@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})

export class MapComponent implements OnInit {

  selectedCountries: any;

  constructor()
 {}


  ngOnInit() {
  
    // code for map settings
      
function getSelectedCountries() {
  var selected = [];
  for(var i = 0; i < map.dataProvider.areas.length; i++) {
    if(map.dataProvider.areas[i].showAsSelected)
      selected.push(map.dataProvider.areas[i].enTitle);
  }

  return selected;
}



}


}

Answer №1

I've made a few changes to your code for better organization. I moved the getSelectedCountries() method outside of the ngOnInit() function and declared map as a component variable. I then populated this.selectedCountries with the result of calling getSelectedCountries().

import { Component, OnInit } from '@angular/core';
import { Router, RouterModule, ActivatedRoute } from '@angular/router';
import { AmChartsService } from "amcharts3-angular2";

declare var AmCharts: any;

@Component({
    selector: 'app-map',
    templateUrl: './map.component.html',
    styleUrls: ['./map.component.css']
})

export class MapComponent implements OnInit {

    selectedCountries: any;
    map: any;

    constructor()
    { }

    ngOnInit() {
        this.map = AmCharts.makeChart("mapdiv", {
            type: "map",
            theme: "dark",
            projection: "mercator",
            panEventsEnabled: true,
            backgroundColor: "#535364",
            backgroundAlpha: 1,
            zoomControl: {
                zoomControlEnabled: true
            },
            dataProvider: {
                map: "worldHigh",
                getAreasFromMap: true,
                areas: []
            },
            areasSettings: {
                autoZoom: false,
                selectable: true,
                color: "#B4B4B7",
                colorSolid: "#84ADE9",
                selectedColor: "#84ADE9",
                outlineColor: "#666666",
                rollOverColor: "#9EC2F7",
                rollOverOutlineColor: "#000000"
            },
            listeners: [{
                "event": "clickMapObject",
                "method": (e) => {
                    if (e.mapObject.objectType !== "MapArea")
                        return;
                    var area = e.mapObject;
                    area.showAsSelected = !area.showAsSelected;
                    e.chart.returnInitialColor(area);
                    let result = this.getSelectedCountries(this.map);
                    document.getElementById("selected").innerHTML = JSON.stringify(result );
                    this.selectedCountries = result;
                }
            }]
        });
    }

    getSelectedCountries(map: any) {
        var selected = [];
        for (var i = 0; i < map.dataProvider.areas.length; i++) {
            if (map.dataProvider.areas[i].showAsSelected)
                selected.push(map.dataProvider.areas[i].enTitle);
        }
        return selected;
    }
}

Answer №2

The optimal approach involves creating a shared service and including it in your main module that you initiate:

Shareable Service

@Injectable
export class AppService {
   sharableData: string;

   constructor(){
       this.sharableData = 'some data';
   }
}

Main Bootstrap Component

@Component({
  selector: 'my-app',
  template: '{{_appService.sharableData}}',
})
export class App { 

  constructor(private _appService: AppService) {}
}

@NgModule({
  imports: [ BrowserModule, FormsModule ],
  declarations: [ App, AnotherComponent ],
  bootstrap: [ App ],
  provide: [
     AppService
  ]
})
export class AppModule {}

Another Component

@Component({
  selector: 'another-component',
  template: '{{_appService.sharableData}}',
})
export class AnotherComponent { 

  constructor(private _appService: AppService) {}
}

Both components are contained within the same module, allowing them to share the same reference to the AppService due to its provision. This holds true even when using routed components within router-outlet.

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

Error: The terminal reports that the property 'then' cannot be found on the data type 'false' while trying to compile an Angular application

In my Angular application, which I initiate through the terminal with the command ng serve, I am encountering build errors that are showing in red on the terminal screen. ✔ Compiled successfully. ⠋ Generating browser application bundles... Error: s ...

Showing information from a JSON dataset of users once a specific User ID has been chosen

My task involves displaying user data from an array and then showing the details of the selected user. I attempted to achieve this with the following code: users = USERS; // contains data selectedUser: User; constructor() { } ngOnInit() { } onSelect(i ...

Angular 6's Select feature is failing to properly update user information

We are currently facing an issue with our user profile edit form. When users try to update their information by changing simple input fields, the changes are reflected successfully. However, when they make selections in dropdown menus, the values do not ge ...

The name 'Map' cannot be located. Is it necessary to alter your target library?

After running the command tsc app.ts, an error occurs showing: Error TS2583: 'Map' is not recognized. Should the target library be changed? Consider updating the lib compiler option to es2015 or newer. I want the code to compile without any issu ...

The correct procedure for refreshing a page in Angular 8

Note: I found some code snippets online but, after testing them out, I have doubts about their reliability due to inconsistencies. In my script, I have developed two utility functions - one for moving to the parent node and another for reloading the curre ...

Service is not designed as a singleton within the MatDialog module

Whenever I launch a Mat Dialog popup in Angular Material and try to access a singleton service, the service appears to be a new instance within the dialog rather than the singleton service utilized throughout the application. Although I am familiar with w ...

Addressing the reactivity issue when incorporating basic markdown directive into vuejs

In an effort to reduce dependency on vue-i18n formatting, I decided to create a simple Markdown formatter directive that only implements bold, emphasize, and strike-through styles. The current implementation of the directive is as follows: import _Vue ...

Could you please share the standard naming convention used for interfaces and classes in TypeScript?

Here's what I have: interface IUser { email: string password: string } class User { email: string password: string constructor(email: string, password: string) { this.email = email this.password = password } isEmailValid(): boo ...

Identifying whether a particular area is represented in a geographic map array presents a significant challenge

Having an issue with typescript currently. I have a variable that contains different string entries representing x, y positions. The entries are as follows: ["3,3","3,4","3,5","2,3","2,4","2,5","-1,-2","-2,- 2","-2,-1"] My goal is to determine if this land ...

There will be no further upgrades available for Angular CLI after version 1.6.0

Based on the latest information from npm, the current version of @angular/cli is v6.2.5. Upon running ng -v, the output shows: _ _ ____ _ ___ / \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _| / △ &b ...

Is it possible to deactivate the click event on an Angular mat table row?

Within my Angular mat table, I have implemented code that expands a table row when clicked. However, I now need to prevent certain rows from being clickable based on the "element.disable" property. <ng-container matColumnDef="id"> <th mat-hea ...

Round off Kendo Column Chart edges and add a personalized highlight shade

https://i.sstatic.net/RpHnR.png Is there a way to create a kendo column chart with rounded borders similar to the image provided? Below is the code snippet I am currently using. Additionally, how can I customize the hover-over color for the columns in the ...

Angular Material: Setting the Sidenav/Drawer to Automatically Open by Default

I am currently utilizing the Angular Material Sidenav component within my project. Upon serving the webpage, I encounter an issue where the sidebar is not visible initially (as shown in the first image). However, after resizing the browser window for som ...

Error: Unable to retrieve the value of 'secret' as it is undefined when attempting to assign a response cookie in Express framework

Today's operation that I've carried out countless times seems to be going awry. For some reason, I am unable to set a refresh token cookie using Express. Here is the error message in full /home/me/Code/apGymBE/node_modules/express/lib/response.j ...

Which rxjs operator should be used when dealing with nested subscriptions in the presence of an if statement?

In my Angular/Typescript project, I am dealing with 2 subscriptions. Each subscription is subscribing to its own observable A and B, which are located outside the component in the service file. Sometimes, when A changes, B may or may not change based on c ...

Exploring the File Selection Dialog in Node.js with TypeScript

Is it possible to display a file dialog in a Node.js TypeScript project without involving a browser or HTML? In my setup, I run the project through CMD and would like to show a box similar to this image: https://i.stack.imgur.com/nJt3h.png Any suggestio ...

Angular 2's innovative approach to implementing a sticky footer concept

Is there a way to make my footer sticky without being fixed? I attempted using the CSS negative margin trick, but it did not work as expected. In the provided Plunker code, I tried to replicate the issue in my Angular 2 app. The goal is for the footer to s ...

Trouble seeing span in ion-item in Ionic 2: How can I display plain text instead?

It seems like I may be overlooking something, as I am experiencing an issue with adding a span to an Ion Item, where the span is not being rendered, nor is the div. <ion-card> <ion-card-title> </ion-card-title> <div> < ...

Guide on converting JSON data into a PDF using TypeScript

I need to take JSON data and convert it into a PDF format when the PDF button is clicked in the UI. I have tried a few things but I'm struggling with binding the response to the PDF function. My goal is to display values from the "actualExpenses" arra ...

Arrange the columns in Angular Material Table in various directions

Is there a way to sort all columns in an Angular material table by descending order, while keeping the active column sorted in ascending order? I have been trying to achieve this using the code below: @ViewChild(MatSort) sort: MatSort; <table matSort ...