How to generate an array within a TypeScript extension function

As I was working on creating an extension method using typeScript, the main goal was to establish a static or normal variable within the method. The ServiceCollector method was invoked three times in order to send and store data or objects in an array.
Below is the code snippet:

import { Employee } from "./Employee.model";

let datafetcher: Employee[] = [];

declare global {
  interface Object {
    ServiceCollector(data): any[];
  }
}

Object.defineProperty(Object.prototype, 'ServiceCollector', {
  value: function(data) {
    datafetcher.push(data);
    console.log(datafetcher);
    return "done";
  },
  enumerable: false
});

The array datafetcher successfully stores the values. However, it encounters an issue where it overrides all previous data with the most recent one.

Array : 0: {code: 101, FirstName: "Aditya"}

/*Adding another value */
Array : 0: {code: 102, FirstName: "Aryan"}
Array : 1: {code: 102, FirstName: "Aryan"}

/*Adding another value */
Array : 0: {code: 103, FirstName: "Kundan"}
Array : 1: {code: 103, FirstName: "Kundan"}
Array : 2: {code: 103, FirstName: "Kundan"}

I've put effort into finding a solution but haven't been able to pinpoint why this behavior persists. This is how the ServiceCollector method is being called

import { Component, OnInit } from '@angular/core';
import { Employee } from './Employee.model';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  EmployeeObject: Employee = {};
  ParentObject: Object = {};

  submit1() {
    this.EmployeeObject.code = 102;
    this.EmployeeObject.FirstName = 'Aryan Toke';
    console.log("Submit 1", this.EmployeeObject);
    this.ParentObject.ServiceCollector(this.EmployeeObject);
  }

  submit2() {
    this.EmployeeObject.code = 103;
    this.EmployeeObject.FirstName = 'Kundan Toke';
    console.log("Submit 2", this.EmployeeObject);
    this.ParentObject.ServiceCollector(this.EmployeeObject);
  }

  ngOnInit(): void {
    this.EmployeeObject.code = 101;
    this.EmployeeObject.FirstName = 'Aditya Toke';
    console.log("ngoninit", this.EmployeeObject);
    this.ParentObject.ServiceCollector(this.EmployeeObject);
  }

}

Upon clicking the submit1() and submit2() buttons, the respective methods are triggered.

Answer №1

The data storage service, known as my-service.ts

import { Employee } from "./Employee.model";

@Injectable({
  providedIn: 'root'
})
export class MyService {

  myStoreArray: Employee[] = [];

  saveData(data:Employee){
    this.myStoreArray.push(data);
    console.log("Data saved "+JSON.stringify(data));
  }

}

In the component.ts file

import { Component, OnInit } from '@angular/core';
import { Employee } from './Employee.model';
import { MyService } from 'wherever you choose to place your service ./my-service.ts';

export class AppComponent implements OnInit {

  constructor(private mySvc: MyService) { }

  submit1() {
    let newEmployee: Employee = {
      code: 102,
      FirstName: 'Aryan Toke'
    }
    console.log("Submit 1", newEmployee);
    this.mySvc.saveData(newEmployee);
  }
  submit2() {
    let newEmployee: Employee = {
      code: 103,
      FirstName: 'Kundan Toke'
    }
    console.log("Submit 2", newEmployee);
    this.mySvc.saveData(newEmployee);
  }
  ngOnInit(): void {
    let newEmployee: Employee = {
      code: 101,
      FirstName: 'Aditya Toke'
    }
    console.log("ngoninit", newEmployee);
    this.mySvc.saveData(newEmployee);
  }
}

Answer №2

The issue arises from repeatedly adding the same reference of EmployeeObject to the array and modifying it with the most recent values each time.

To resolve this, it is recommended to create a new object when passing data to the service.

For example:

this.ParentObject.ServiceCollector({code: A, FirstName: B});

Additionally, note that the approach mentioned in Francesco's response is more aligned with TypeScript/Angular best practices compared to using Object.defineProperty method. I recommend learning more about services by visiting: https://angular.io/guide/architecture-services

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

Typescript: Streamline the process of assigning types to enum-like objects

One common practice in JavaScript is using objects as pseudo-enums: const application = { ELECTRIC: {propA: true, propB: 11, propC: "eee"}, HYDRAULIC: {propA: false, propB: 59, propC: "hhh"}, PNEUMATIC: {propA: true, propB: ...

how to verify if a variable exists in TypeScript

Is there a recommended method for verifying if a variable has a value in TypeScript 4.2? My variable may contain a boolean value. I'm thinking that using if(v){} won't suffice as the condition could be disregarded if it's set to false. ...

How should a React Testing Library wrapper be properly typed in a TypeScript environment?

There's this code snippet from Kent C. Dodd's library that I find extremely helpful import * as React from 'react' import {render as rtlRender} from '@testing-library/react' import {ThemeProvider} from 'components/theme& ...

"Encountering a 400 bad request error when making a Graphql POST

Seeking assistance with my graphql code. I have included the service and component files below. I am currently new to graphql and not utilizing the apollo client; instead, I am attaching a query on top of the HTTP POST call to send requests to the graphql ...

Using Angular 4 to retrieve a dynamic array from Firebase

I have a dilemma while creating reviews for the products in my shop. I am facing an issue with the button and click event that is supposed to save the review on the database. Later, when I try to read those reviews and calculate the rating for the product, ...

Managing a digital timepiece within a multiplayer gaming environment

I'm currently developing a fast-paced game where players control a block resembling a clock. To accurately calculate the time taken by each player to make moves, I store the start time of the game and record the timestamp of every move in the databas ...

When using react-admin with TypeScript, it is not possible to treat a namespace as a type

Encountering issues while adding files from the react-admin example demo, facing some errors: 'Cannot use namespace 'FilterProps' as a type.' Snippet of code: https://github.com/marmelab/react-admin/blob/master/examples/demo/src/orde ...

Error 2322: Troubleshooting Typescript arrow functions overloads issues

Everything seems to be working well with the code below, except for an error that occurs with the resolve constant. const resolve: Resolve Type '(param: "case 1" | "case 2" | "case 3") => boolean | "string" | ...

Using Angular: Fetch HTTP Data Once and Return as Observable in Service

My Goal: I need to retrieve data via HTTP only once and then share it across my entire application as properties. However, since HTTP requests can be slow, my app should continuously monitor these properties. The challenge is to ensure that the HTTP call i ...

Best practices for working with child components in Vue.js using TypeScript: Steer clear of directly mutating props

I feel like I'm stuck in a loop here. Currently, I have a Vue.js 2 app set up and running with TypeScript. However, I'm encountering an issue when trying to pass data to a child component that originates from the store. <template> < ...

Tips for eliminating contenthash (hash) from the names of JavaScript and CSS files

Google's cached pages are only updated once or twice a day, which can result in broken sites on these cached versions. To prevent this issue, it is recommended to remove the contenthash from the middle of the filename for JavaScript files and eliminat ...

Ways to customize background color for a particular date?

I have been using the fullcalendar npm package to display a calendar on my website. I am trying to figure out how to set a background color for a specific selected date. I tried looking into this issue on GitHub at this link. However, it seems that dayRe ...

Angular 2: Streamlining user interface connections with extensive data rows

My challenge lies in displaying a list of items stored in an array[] when the user clicks on a tab. The data set contains around 10k rows, which is quite large, and currently takes approximately 2 to 3 seconds to render on the UI after the click event. I a ...

Issue detected in the ngx-joyride package: Error found in ./node_modules/ngx-joyride/assets/images/close.svg

During my build process, I encountered an error with ngx-joyride: ERROR in ./node_modules/ngx-joyride/assets/images/close.svg Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type." <line x1="1" y1=" ...

Issue: UNSUPPORTED: The keyword "id" is not supported, please use "$id" for the schema ID after upgrading to Angular13

After upgrading from Angular 12 to Angular 13, I encountered an error while running my e2e tests. How can I go about identifying the root cause of this issue? I am able to compile with 'ng build'. /opt/wdio/node_modules/@angular-devkit/core/nod ...

How can I access a service without the need to import its provider module?

My goal is to grasp the concept of multiple NgModules in an angular application and how they interact, specifically focusing on importing a SharedModule for commonly used services into lazily loaded feature modules. Here's the sequence of steps I fol ...

Code error TS2345 occurs when assigning the argument of type '{ headers: HttpHeaders; }' to a parameter of type 'RequestOptionsArgs'. This indicates a mismatch in the type of data being passed, causing an

Upon running ionic serve, these are the results that I am encountering. My setup consists of Ionic4 version with Angular 8. While executing the command, this error appears: src/app/home/home.page.ts:60:77 - error TS2345: Argument of type '{ headers ...

Angular Material datetime picker with an option for transparent background

After upgrading my angular from version 15 to 16, I encountered a strange issue with the material date time picker. The GUI part of the picker appeared half transparent as shown in this image: Has anyone else faced this kind of problem with the material d ...

Stopping the subscription to an observable within the component while adjusting parameters dynamically

FILTER SERVICE - implementation for basic data filtering using observables import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; import { Filter } from '../../models/filter.model'; imp ...

SvgIcon is not a recognized element within the JSX syntax

Encountering a frustrating TypeScript error in an Electron React App, using MUI and MUI Icons. Although it's not halting the build process, I'm determined to resolve it as it's causing issues with defining props for icons. In a previous pro ...