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

Enhancing systemjs-builder with DefinitelyTyped

Is there a dedicated TypeScript definition file for systemjs-builder available? https://github.com/systemjs/builder I encountered an issue where the systemjs.d.ts file does not seem to cover it, leading to a "cannot find module" error when trying to impor ...

Behaviorsubject has a circular relationship

I have a situation where I am monitoring changes in a behaviorSubject and then modifying the data before updating the behaviorSubject with the updated information. This seems to create a loop. What would be a more effective approach for handling this sce ...

Angular 4 async pipe not functioning as expected for Observable to update UI

I have a simple dataset loaded into an observable as shown below: public tasks: Observable<UserTask[]>; constructor(private dataService: HttpdataService, private changeDetector: ChangeDetectorRef) { } ngOnInit() { this.loadTasks(); } loadTasks() ...

When imported, Node / JS instantly generates a new instance

Is there a way to instantiate a class without importing it first and using new afterward? Instead of var mainClass = require('../dist/main'); // has "class Main { ... }" var mainInstance = new mainClass(); I am looking for something like var ...

Disallow the use of properties in a nested interface

Is there a way to define an interface or type that restricts a specific key in a child of the interface when used in union types? I am looking for the correct definition for Abc: type Abc = { someField: { prohibited?: never, }, }; type Use ...

Redux Saga effect does not have a matching overload for this call

Encountering an error in my Redux Saga file, specifically when using the takeLatest() Saga effect. TypeScript is throwing the following error: (alias) const getMovies: ActionCreatorWithoutPayload<string> import getMovies No overload matches this call ...

Error Alert: Redux unable to retrieve data from Django API due to CORS issue

Currently, I am working on a project with a frontend application running on http://localhost:3000 and a backend API on http://localhost:8000. However, I am facing a CORS issue when trying to make requests from the frontend to the backend API. The error me ...

Utilizing WebWorkers with @mediapipe/tasks-vision (Pose Landmarker): A Step-by-Step Guide

I've been experimenting with using a web worker to detect poses frame by frame, and then displaying the results on the main thread. However, I'm encountering some delays and synchronization issues. My setup involves Next.js 14.0.4 with @mediapip ...

What is the best way to convert a tuple containing key/value pairs into an object?

How can the function keyValueArrayToObject be rewritten in order to ensure that the type of keyValueObject is specifically {a: number; b: string}, instead of the current type which is {[k: string]: any}? const arrayOfKeyValue = [ {key: 'a', val ...

ng2-toastr in conjunction with akveo/ng2-admin - Styles not being applied

I recently integrated ng2-toastr into my akveo/ng2-admin dashboard, utilizing the latest version with Angular 4. Following the provided installation documentation, I imported the necessary CSS in the index.html file and declared ToastModule in the app.modu ...

There was an issue encountered when creating the class: The parameters provided do not correspond to any valid call target signature

I am facing an issue with my code. Here is the scenario: export class MyClass { public name:string; public addr:string; constructor() {} } I have imported MyClass and trying to use it like this: import { MyClass } from './MyClass' ...

Saving Data in an Angular Material Table: A How-to Guide

I have a basic angular material table and I am looking for a way to save the data displayed in each row when a button is clicked. Is it possible to save each row of data as an object and push it to an array? If so, how can I achieve this? <div class=& ...

My goal is to prevent users from using the Backspace key within the input field

Let's say we want to prevent users from using the backspace key on an input field in this scenario. In our template, we pass the $event like so: <input (input)="onInput($event)"> Meanwhile, in our app.component.ts file, the function ...

Deciphering the .vimrc setup for tooltips and symbols in TypeScript

Currently, I have integrated the Tsuquyomi plugin for my typescript development in Vim. The documentation mentions tooltips for symbols under the cursor, which are working fine. The issue arises as I am using terminal-based Vim, and even if I were using a ...

A mistake has been identified: The object could potentially be 'null'. TS2531 for window.document

This is my first time integrating TypeScript into my project. When attempting to access something using window.document.getElementById(), I keep encountering the error: Type error: Object is possibly 'null'. TS2531 I've looked online for ...

Steps for automatically closing a TextPrompt if the end user does not respond within a specific time frame

How can I programmatically close a Prompt in Microsoft Chatbot SDK v4, such as TextPrompt or ConfirmPrompt, and end the dialog after a certain period of time if the user does not reply? I attempted to use setTimeout and step.endDialog but encountered issu ...

Ways to verify if a function has completed execution and proceed to invoke another function

I am seeking to verify if a user has chosen an item from the ngFor form and then redirect them to another page upon submitting the form with the updated value. HTML: <mat-select placeholder="Treatment" [(ngModel)]="model.TreatmentA" name="TreatmentA" ...

javascript + react - managing state with a combination of different variable types

In my React application, I have this piece of code where the variable items is expected to be an array based on the interface. However, in the initial state, it is set as null because I need it to be initialized that way. I could have used ?Array in the i ...

Ways to recover information that is not typically found

My firebase database has two main trees: "tag" and "user". Each user is associated with a set of tags, referred to as preferences. Here is the structure of my database: I am trying to display a list of preferences that a specific user does not have. Exam ...

Using Moneris with Google Pay in Angular

I'm currently working on implementing Google Pay with Moneris Gateway using the Google-Pay-button-Angular library. However, I'm unsure of how to connect Moneris with it. I followed a tutorial provided in this link but I'm unsure where to inp ...