What is the correct way to implement strong typing for a reactive array consisting of interface Class objects in TypeScript?

My goal is to develop a dynamic array that can store data fetched from a database through an HTTP request using a SQL query. Since I lack direct access to the database, my only option is to submit a query to retrieve the required information. The retrieved data will be stored in a reactive state that I have established. Here is a snippet of my code:

const dataState: any = reactive({
  items: [],
});

function fetchData(query: string) {
  query = `SELECT * FROM dept_sales WHERE store_id = 1 AND date = 20181114`;
  axios
    .post(`url_link`, query)
    .then((response) => {
      dataState.items = response.data;
    })
}

To enhance my TypeScript skills, I am aiming to introduce typing to avoid using 'any'. Knowing the structure of the incoming data, I have defined an interface and a class as follows:

interface ISalesInfo {
  storeId: number;
  salesAmount: number;
  salesQuantity: number;
  salesDepartment: number;
}

class SalesData implements ISalesInfo {
  storeId: number;
  salesAmount?: number;
  salesQuantity?: number;
  salesDepartment?: number;

  constructor(
    storeId: number,
    salesAmount: number,
    salesQuantity: number,
    salesDepartment: number
  ) {
    this.storeId = storeId;
    this.salesAmount = salesAmount;
    this.salesQuantity = salesQuantity;
    this.salesDepartment = salesDepartment;
  }
}

My objective is to iterate through the data within dataState.items, create a new instance of SalesData for each iteration, and append it to a new typed array.

let salesList = reactive({}); // works, but remains typed as 'any'

let salesList: Array<SalesData> = []; // successfully compiles with proper typing, 
//but lacks reactivity resulting in rendering issues on screen.


function typeSales() {
  for (let i = 0; i < dataState.items.length; i++) {
    salesList[i] = new SalesData(
      dataState.items[i].ds_store_id,
      dataState.items[i].ds_amt,
      dataState.items[i].ds_qty,
      dataState.items[i].ds_dept
    );

Is there a method to establish a reactive array that is correctly typed (containing objects of type SalesData)?

Answer №1

After some trial and error, I managed to craft a piece of code that successfully generates a reactive array containing interfaced objects:

let salesContainer = reactive({
      sales: [] as SalesData[],
});

However, accessing the data now requires me to use:

salesContainer.sales[0].

I was hoping to simplify this process by using:

salesContainer[0]; 

Is there a more efficient solution available?

UPDATE with potentially improved solution:

let salesContainer: SalesData[] = reactive([]);

function buildSalesData() {
  for (let i = 0; i < state.posts.length; i++) {
    salesContainer.push(
      new SalesData(
        state.posts[i].ds_store_id,
        state.posts[i].ds_amt,
        state.posts[i].ds_qty,
        state.posts[i].ds_dept
      )
    );
  }
}

Seems like this approach is working smoothly!

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

Guide on importing images from directories in Vue

As I delve into learning vue.js, a particular issue has surfaced. I am in the process of creating an SFC and encountering difficulties with loading images from the 'src / assets / logo.png' folder. Below is the code snippet: <template> & ...

Vue Component Unit Testing: Resolving "Unexpected Identifier" Error in Jest Setup

Having just started using Jest, I wanted to run a simple unit test to make sure everything was set up correctly. However, I encountered numerous errors during compilation while troubleshooting the issues. When running the test suite, Jest successfully loc ...

Error TS2304: The identifier 'Map' cannot be found in version 5.1.0 of Node.js, TypeScript version 1.6.2, and WebStorm 11

While utilizing the filewatchers in my WebStorm 11, I encountered a TS2304 error related to ts-compiler 1.62. The error message reads: TS2304: Cannot find name 'Map' By deactivating the filewatcher and running the command tsc --target es6 app ...

What is the best way to iterate through an array of arrays using a foreach loop to calculate the total number of specific properties?

For instance, if YieldCalcValues were to look something like this: [ [ 850, 500 ], [ 3, 6 ], [ 1200, 5000 ], [ 526170, 526170 ] ] I am looking to create a foreach loop that calculates the yield per for each product. How can I accomplish this correctly? l ...

Strategies for transferring ngModel data from child components to parent components (child to parent to grandparent)

I am currently working on multiple parent components that utilize template-driven forms: user-data.components.ts admin-data.components.ts customer-data.components.ts Each of these parent components have form elements that are child components utilizing NG ...

The custom validation feature in Angular 4 is failing to function as expected

Currently, my focus is on Angular 4 where I have developed a custom validator for checking CGPA values (to ensure it is between 2.0 and 4.0). Although the predefined `Validators.required` works fine, my custom validator seems to be not triggering as expect ...

Maintaining checkbox selection while switching pages in Angular

When I try to edit the settings for accepting payments in all currencies under the "Pricing" component, the checkbox is unchecked every time I return to the "General" section. How can I prevent this from happening and keep the checkbox checked? Refer to ...

Are there ways to implement Vue.js transitions without directly setting the height in the code?

I'm having an issue with a Vue app I created where I need to make an element expand and collapse when a button is clicked. I want the effect to be smooth and animated, but using the <transition> tag alone isn't working as expected. The prob ...

Utilizing the Double Mapping Feature in React with Typescript

It seems I might be overlooking something, can someone guide me on how to properly double map in this scenario? I'm encountering an error on the second map: Property 'map' does not exist on type '{ departure: { code: string; name: strin ...

The Vue warning indicates that there was a failed type check for the "value" prop. It was expecting an array but received a number with a value of 1

I am facing an issue with an input of type number where I need to restrict the user from entering a number greater than ten. Initially, everything was working fine until I decided to change the value to an array (from value: 1 to value: [1, 1]) After swit ...

Troubleshooting the error message "TypeError: Cannot read property 'name' of undefined" when working with data binding in Angular 4

I am brand new to Angular and I have been working on creating a custom Component. Specifically, I am trying to display a list of Courses (objects) which consist of two properties: id and name. So far, this logic is functioning properly. However, when attem ...

Angular StrictNullChecks: "Error - object may be null"

I am encountering an issue with the 'strictNullChecks' setting in my Angular project. This has resulted in numerous errors across my templates (.html), such as: <input #inputValue type="text" (keyup.ent ...

Encountering an issue with the message: "Property 'ref' is not available on the type 'IntrinsicAttributes'."

Having trouble implementing a link in React and TypeScript that scrolls to the correct component after clicking? I'm using the useRef Hook, but encountering an error: Type '{ ref: MutableRefObject<HTMLDivElement | null>; }' is not assi ...

Utilize Typescript to Invoke Functions of Different Components in Angular 2

Hello everyone, I am a newcomer to Angular 2 and I'm looking to utilize the value of one component in another component. This will help me populate data based on that particular value. In my setup, I have three Components - App.Component, Category.Co ...

After being initialized, the added Vue.js DOM elements do not function together

I updated an HTML page with ajax contents and incorporated Vue.js for front-end events. Unfortunately, the dynamically added elements are not interacting with the Vue.js instance, even when I attempted to forceUpdate them. Any suggestions on how to resol ...

Displaying a div component in React and Typescript upon clicking an element

I've been working on a to-do list project using React and TypeScript. In order to display my completed tasks, I have added a "done" button to the DOM that triggers a function when clicked. Initially, I attempted to use a useState hook in the function ...

Is it possible to use @ViewChild to target an element based on its class name?

The author of this article on Creating Advanced Components demonstrates selecting an element by creating a directive first: @Directive({ selector: '.tooltip-container' }) export class TooltipContainerDirective {} Then, the author uses this d ...

Creating a currency input field in HTML using a pattern textbox

In a project using HTML, Angular 2, and Typescript, I am working with a textbox. How can I ensure that it only accepts numbers along with either one dot or one comma? The input should allow for an infinite number of digits followed by a dot or a comma and ...

Encounter issue with NPM locating package.json file while running VueJS on Docker-Compose

Having trouble setting up a vue js app with docker-compose. When running 'npm install' in Docker, it's showing an error that npm cannot locate the package.json file. I made sure that I created the vue js project using vue js cli before attem ...

Properly specifying the data type for a generic type variable within a function in TypeScript

As I work on my express project, I am currently coding a function called route. const morph = (params: Function[]) => (req: Request) => params.map(f => f(req)) const applyTransformers = (transformers: Function[]) => (response: any) => { ...