What is a more efficient way to optimize the repeating 'for-of' loop?

I am faced with the following code challenge:

  runA() {
    const request = [];
    for (const item of this.items ) {
      request.push(this.getRequestData(item.prop1)); // want to generalize that
    }

    return forkJoin(...request).pipe(x => x);
  }

  runB() {
    const request = [];
    for (const item of this.items ) {
      request.push(this.getOtherData(item.prop2)); // want to generalize that
    }

    return forkJoin(...request).pipe(x => x);
  }

I am looking to refactor this code in order to pass different arguments into request.push() to avoid duplicating loops. The item object contains various properties, so in some cases I require item.prop1, while in others I need item.prop2. Therefore, my goal is to have the final code structured as follows:

  run(param) {
    const request = [];
    for (const item of this.items ) {
      request.push(param); // need to find the correct way to handle this
    }

    return forkJoin(...request).pipe(x => x);
  }

  runA() {
    run(this.getRequestData(item.prop1)) // need to get this right
  }

  runB() {
    run(this.getOtherData(item.prop2)) // need to get this right
  }

Is there a method to achieve this efficient refactoring in TypeScript?

Answer №1

Use this code snippet to achieve your desired functionality

getAllData(property){
 return forkJoin(Object.keys(this.objects).map(key=>this.retrieveData(this.objects[key][property])))
}

Answer №2

Your function serves two main purposes:

  1. It transforms the items into a request array.
  2. It then sends all requests in that array.

Combining these two tasks into one function would be ideal if the function consistently performed the same task each time. However, in your function, part 1 carries out different actions on different calls (prop1 vs prop2 and getRequestData vs getOtherData), so it does not make sense to include it in the function.

To illustrate this point, consider leaving part 1 in place, you might opt to send a selector function as a parameter, resulting in the following:

RunX((item) => {return getRequestData(item.prop1)});
RunX((item) => {return getOtherData(item.prop2)});

This unnecessarily complicates the following code:

let requests = this.items.map((item) => {return getRequestData(item.prop1)});
SubmitRequests(requests);
let requests = this.items.map((item) => {return getOtherData(item.prop2)});
SubmitRequests(requests);

If the processing logic actually repeats, consider extracting a method like getProp1Requests();

If you still choose to proceed with this approach, remember to send a selector function:

RunX(selector: (Item) => RequestData){

}

However, it is advisable not to use item[prop] as it could compromise type checking.

Answer №3

Instead of passing the getter function as an argument to the Run function, why not consider passing it directly?

  runAll(getter: (field: string) => any, propName: string) {
    const request = [];
    for (const item of this.items ) {
      request.push(getter(propName));
    }
    return forkJoin(...request).pipe(x => x);
  }

Usage:

runAll(this.getRequestData, 'prop1Name')
runAll(this.getOtherData, 'prop2Name')

To enhance type safety and ensure that only valid keys of ItemClass are passed:

runAll(getter: (field: string) => any, propName: keyof ItemClass) 

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

WebStorm is not auto-completing the Emotion Styled Components

While using @emotion/styled in WebStorm, I have noticed that there is no Intellisense for autocomplete within my style object. However, Typescript does seem to be checking to some extent: const StepTimer = styled.button({ borderRadius: 50, height: &ap ...

What is the best way to extract and retrieve the most recent data from an XmlHttpRequest?

Currently, I am using a web service that returns an SseEmitter to program a loading bar. The method to receive it looks like this: static async synchronize(component: Vue) { let xhr = new XMLHttpRequest(); xhr.open('PATCH', 'myUrl.co ...

"Encountering issues when trying to retrieve a global variable in TypeScript

Currently facing an issue with my code. I declared the markers variable inside a class to make it global and accessible throughout the class. However, I am able to access markers inside initMap but encountering difficulties accessing it within the function ...

Exploring Click Events in Angular with OpenLayers Features

After creating a map with parking points as features, I now want to implement a click function for the features. When a feature is clicked, I want to display a popup with the corresponding parking data. I've tried searching online for information on ...

Tips for adjusting the timing of an interval in Angular and RxJS to create dynamic changes

I am looking to dynamically adjust the delay of an interval, but my knowledge of Angular is limited which is hindering my progress in this task. Below is the current code snippet I am working with: timeDiffs : number[] = [] <== this array contains time ...

The synergy between ternary operators and Vue filters

Recently, I came across a peculiar issue while working with Vue. Take a look at the code snippet from vue.html: <label :text= "$props.information ? (($props.information.primary || $props.information.secondary) | myFilter) : `No info`"> </lab ...

When the nestjs interface appears to be missing a defined method

Upon reviewing the code at this link: https://github.com/nestjs/nest/tree/master/packages/common One can see that the interface ArgumentsHost has been defined, but the contents of its methods are not explicitly defined. However, when looking at the foll ...

What steps can be taken to effectively build a test suite architecture using Jest?

After exploring all the available resources on the Jest documentation website, including various guides and examples, I have yet to find a solution to my specific question. I am in search of a methodology that would enable me to individually run test case ...

When using html2canvas in Angular, it is not possible to call an expression that does not have a call signature

I'm currently working on integrating the html2canvas library into an Angular 8 project. Despite trying to install the html2canvas types using npm install --save @types/html2canvas, I'm still facing issues with its functionality. Here's how ...

Restricting Dates in Angular 2 Date Picker

I encountered an issue while attempting to disable specific dates in a date picker. Here is my custom date picker written in TypeScript: import { DateFormatter } from './ng2-bootstrap/date-formatter'; import { DatePickerComponent } from './n ...

Angular 7 fails to send XHR request

This is my initial question, so I'll try to keep it concise. Here is the Angular method that I am using: delete(id: number): Observable<User[]> { console.log(id); return this.http.delete(`${this.baseUrl}/deleteUser`) .pipe(map(re ...

Enum-centric type guard

Could I create a custom type guard to verify if a specified string is part of a specific string enum in a more specialized way? Check out the following example: enum MyEnum { Option1 = 'option one', Option2 = 'option two', } const ...

The reason for the Jest failure is that it was unable to locate the text of the button

As someone who is new to writing tests, I am attempting to verify that the menu opens up when clicked. The options within the menu consist of buttons labeled "Edit" and "Delete". However, the test fails with the message: "Unable to find an element with te ...

A guide to utilizing the spread operator within a typescript tuple

Is it possible to set the structure of an array without knowing the exact number of elements it will contain? How can I achieve this flexibility in defining array configurations? (Check out a playground version here): type numStrArr = [number, ...string]; ...

Angular textbox with dynamic concatenated name functionality

Hello, I'm currently working with some code that looks like this: <div *ngFor="let phone of phoneList; let phIndx = index;"> <div class="peoplePhoneTxtDiv"> <input [disabled]="phone.disabled" class="peoplePhoneTxtBox" type="text" ...

Protractor: Stuck on the current piece of Code

Why is the "else" code inside the "IsPresent()" function not getting executed in Protractor with Jasmine framework? The "IF" code works fine, but when I provide a value from an Excel file, the execution stops at the "IF" block. Any suggestions on why it&ap ...

Assign object properties to a constant variable while validating the values

When receiving the features object, I am assigning its values to constants based on their properties. const { featureCode, featureSubType, contentId, price, family: { relationCountsConfig: { motherCount, fatherCount, childrenCount }, max ...

The process of removing and appending a child element using WebDriverIO

I am trying to use browser.execute in WebDriverIO to remove a child element from a parent element and then append it back later. However, I keep receiving the error message "stale element reference: stale element not found". It is puzzling because keepin ...

Angular messaging service error TS2769: There is no overload that fits this call

Currently, I am attempting to utilize a messenger service to send products to the cart component. Within the 'Product' class, there are various product attributes stored. Although I managed to successfully log the product to the console in the ca ...

Reactive forms in Angular now support changing focus when the Enter key is pressed

I have successfully created a table and a button that generates dynamic rows with inputs inside the table. One issue I'm facing is that when I press enter in the first input, a new row is created (which works), but I can't seem to focus on the ne ...