Waiting for a function to complete its processing loop in Angular 7

In my code, I'm dealing with an angular entity called Z which has a property that is a list of another entity named Y. My goal is to delete the entity Z, but before doing so, I need to also delete all the Y entities within it. The challenge arises from foreign key constraints in the database, which require me to delete all instances of Y before deleting Z.

onDelete(id: number, name: string, Y: Y[]) {
    this.deleteYInZ(Y);
    this.ZService.deleteZ(this.selectedSecuritySubject.value, id).subscribe(() => {
      this.getAllZ();
      }
  }

The method deleteYInZ looks like this:

 deleteYInZ(Y: Y[]) {
    for (const Yentity of Y) {
      this.targetService.deleteTarget(this.selectedSecuritySubject.value, Yentity .ID).subscribe(() => {
      });
    }
  }

I'm facing an asynchronous issue here as I tried to make the deleteYInZ async and then used an await in the onDelete method, but it's not functioning correctly.

Can someone guide me on how I can properly handle the deletion process by first removing all Y entities before proceeding to remove all Z entities?

Answer №1

To accomplish this task, you have the option of utilizing an external async/await function or taking advantage of the new for...of iteration method (which is currently being used).

for (const theY of Y) {
  await yourDeleteFunction(theY);
}

However, if possible, I recommend adjusting your approach if you have access to the backend. Instead of employing forEach, for...of, or any other form of iteration, consider implementing a bulk delete operation. This way, you can reduce the number of requests sent to the backend and also minimize database executions. Here's an example:

deleteZInz(id: number, name: string, items: Y[]) {
  this.deleteYInz(items)
    .subscribe(result => {
      this.ZService.deleteZ(...etc);
    });
}

deleteYInz(items: Y[]): Observable<yourReturnType> {
  return this.targetService.deleteBulk(
    this.selectedSecuritySubject.value,
    items.map(item => item.id),
  );
}

By following this approach, let's say you are working with a MySQL database, you will only be performing one delete operation by using a where in (1, 2, 3, 4, n) clause instead of making separate requests for each of your Y items.

Answer №2

Consider implementing a promise in this workflow by utilizing the then operator within the delete function. This way, the return will only occur after the completion of the 'for' loop.

onDelete(id: number, name: string, Y: Y[]) {
this.deleteYInZ(Y).then(_ => {
    this.ZService.deleteZ(this.selectedSecuritySubject.value, id).subscribe(() => {
    this.getAllZ();
  });

}

deleteYInZ(Y: Y[]) {
  return Promise.resolve().then(function () {
    for (const Yentity of Y) {
      this.targetService.deleteTarget(this.selectedSecuritySubject.value,Yentity.ID).subscribe(() => {
      });
    }
  })

}

Answer №3

When using for loops or for each loops in Javascript that involve asynchronous actions, they can present unexpected challenges due to their behavior. In most cases, the for loop will complete before the asynchronous actions, leading to confusion. Here is a suggestion to help navigate this issue:

async onDelete(id: number, name: string, Y: Y[]) {
    await this.deleteYInZ(Y);
    ...
}

async deleteYInZ(Y: Y[]) {
    await this.asyncForEach(Y, async (Yentity) => {
        await this.targetService.deleteTarget(this.selectedSecuritySubject.value, Yentity.ID);
    });
}

async asyncForEach(array, callback) {
    for (let index = 0; index < array.length; index++) {
        await callback(array[index], index, array);
    }
}

Additionally, it's important to avoid subscribing to everything when dealing with inner observable loops. Instead, consider piping and returning observables using tools like mergeMap. This helps prevent issues like strange behavior and memory leaks. While this topic extends beyond the current question, I recommend exploring rxjs and adopting a more reactive approach.

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

Pass the value of the search input to child components in Angular 2

Within my Angular 2 application, I am faced with the task of sending the value from an HTML search input to 3 child components only when the user pauses typing for 300ms and has entered a different value than what was previously in the input field. After r ...

Having trouble with customizing a selected ListItemButton in Material-UI - need some help with

After reviewing the documentation, I discovered a method to override the styling of the selected class by introducing a new class under .MuiSelected. The implementation looks something like this: const customStyles = makeStyles(() => ({ customizedSele ...

Create an array that can contain a mix of nested arrays and objects

Working on my project using Angular and TypeScript includes defining an array that can contain arrays or objects. public arrangedFooterMenu: IMenuItemType[][] | IMenuItemType[] = []; typesOfData.forEach(type => { let filteredData: IMenuItemType | ...

Combine a pair of select statements to utilize the RxJS store within an Angular Guard

When working on an Angular Guard, I encountered a challenge where I needed to select two fields from the ngrx store. Here is the code snippet for reference: @Injectable() export class RoleGuard implements CanActivate { constructor( public router: A ...

How to properly display an Angular Template expression in an Angular HTML Component Template without any issues?

When writing documentation within an Angular App, is there a way to prevent code from executing and instead display it as regular text? {{ date | date :'short'}} Many sources suggest using a span element to achieve this: <span class="pun"&g ...

Ensuring the selected date matches any consecutive dates within the dates array in Angular

Imagine if 01/01/2022 is chosen from the input field, and my array of dates looks something like this: ['31/12/2021', '01/11/2021', '02/01/2022'...] In this scenario, when '31/12/2021' and '02/01/2022' are ...

3 Ways to Ensure Your Picture Uploads are Visible Right Away

I am currently working on an Ionic app that enables users to upload images to Firebase storage. One issue I am encountering is that the image only changes once a new one is selected, after closing and reopening the app. I would like it to update immediatel ...

What is the recommended return type in Typescript for a component that returns a Material-UI TableContainer?

My component is generating a Material-UI Table wrapped inside a TableContainer const DataReleaseChart = (): React.FC<?> => { return ( <TableContainer sx={{ display: 'grid', rowGap: 7, }} > ...

What are the best practices for sharing context in express and typescript?

Implementing a solution to expose a value to all request handlers using express and typescript is my goal. I am looking for a way to easily "inject" this value from a middleware or an alternative method that allows for simple mocking if needed. Here is th ...

NativeScript: The workspace path specified does not contain a valid workspace file

Currently, I am developing a new project using NativeScript and Angular. To streamline the process, I attempted to utilize Angular generators (schematics) through the command line. The command I executed was tns generate component <component name> U ...

Implementing Facebook Javascript SDK to enable login and trigger re-authentication using React Web and Typescript within a component

As a newcomer to stack overflow, I welcome any suggestions on how I can improve my question. I'm in need of guidance concerning logging a user into facebook and requiring them to authenticate their profile or select another profile manually, rather t ...

Exploring the Power of PrimeNG and Observables in Angular 4 with RxJS

After configuring my Angular 4 project with a service like this: const usersURL = 'http://my.super.url.php'; @Injectable() export class UserService { users: Observable<User[]> constructor (public http:Http) let tick$ = Observ ...

Unraveling the Intricacies of Manipulating Values through mockStore.overrideSelector

There is a certain selector that I'm working with, and it returns either true or false. To ensure accurate testing in my unit test, I need to cover scenarios where this value is both true and false. To set up for the test, I have initially configured ...

Introducing a new element in TypeScript using a separate method with parameters

Currently, I am attempting to create a method that will allow me to add an element to my array. Despite being new to typescript, I have been struggling to determine what needs to go into the addNewProduct function. While seeking help, I came across the p ...

Tips for extracting IDs from multiple checkboxes that have been selected upon submission in an Ionic 2+/Angular 2+ environment

I am facing an issue with retrieving the ID of the checked item upon submission. While I can successfully fetch the selected ID on change, I am unable to do so on submit. It is worth noting that the data I am receiving does not include a "checked" value. T ...

Issue: Module '@angular/compiler' not found

After downloading an angular template, I encountered an issue while running "ng serve": Cannot find module '@angular/compiler' Error: Cannot find module '@angular/compiler' ... I tried various solutions found on the internet, incl ...

Passing an array of ID's between two components in Angular: A comprehensive guide

Greetings fellow readers, I have encountered a new challenge in my Angular project. I need to pass an array of IDs from one component to a completely unrelated component. Most solutions suggest using ViewChild, Input, or Output, but since the components ar ...

Troubleshooting a navigation issue in Angular involving the mat-sidenav element of material UI while transitioning between components

I would greatly appreciate your assistance in resolving the issue I am facing. I have been trying to navigate from one view to another, but when I use an <a> tag nested within a <mat-sidenav>, I encounter the following error: "Uncaught (in prom ...

Is it just me, or does the this.router.subscribe method no longer exist in Angular 2's @angular/router library?

I'm experiencing an issue in Angular 2 with the library @angular/router. It appears that the method this.router.subscribe no longer exists. Previously, this code worked fine on an older version of the router that has since been deprecated. Does anyon ...

Tips for conducting a worldwide search in Angular 2?

I'm currently navigating my way through angular2 development and I am aiming to conduct a comprehensive search within an array of JSON objects. To illustrate, consider this sample array: invoiceList = [ { invoiceNumber: 1234, invo ...