0

I have an angular entity Z which one of its properties is a list of another entity Y, I need to delete entity Z and when I do it I need to delete the list of entity Y inside of it. The problem is that first I need to delete all the Y values and then delete the Z due to FK problems on database. My method is the following:

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

and the deleteYInZ is:

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

I have an async problem here I tried to do async deleteYInZ and then put an await on the onDelete method but It's not working

How can I do to first delete all the Y and after it finishes delete all the Z?

0

3 Answers 3

1

This can be done by using an external async/await function or you can use the new for...of iteration (as you're doing right now).

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

But, honestly, if you have access to the BE, I'd change your approach a little bit. Instead of doing a forEach or for...of or whatever other iteration, you should use a bulkDelete. This way you will save a few request to your BE and a few DB executions :). Something like this:

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),
  );
}

This way, lets say you have a MySQL DB, you will be doing just 1 delete by doing a where in (1, 2, 3, 4, n) instead of doing 1 request and 1 delete per each of your Y items.

Sign up to request clarification or add additional context in comments.

1 Comment

This is a good approach for data rows, but I was under the impression he was deleting entities and I can't imagine there would be that many to remove at one time (i.e. I don't think the cost of back and forth to the database is that much).
1

try use a promise in this flow, using the then operator in delete function. so only after the for termination will it return

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(() => {
      });
    }
  })

}

2 Comments

This approach returns the following error: Uncaught (in promise): TypeError: Cannot read property 'targetService' of undefined
It doesn't recognize the targetService call that I make on the constructor private targetService: TargetService
0

Whenever you have for loops or for each loops with an asynchronous action within them within Javascript, they can throw YOU for a loop instead because they don't exactly behave as most expect -- in most cases, the for loop will complete before the asynchronous actions. I would try something like the following (hopefully at least gets you on the right track):

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);
    }
}

On an aside, you should not be subscribing to everything, especially with inner observable loops, but rather piping it and returning observables using tools like mergeMap (you should make it so that only the caller is subscribing, otherwise you may run into other issues, like weird behavior and memory leaks). That is beyond the scope of this question, but I would look more into rxjs and how to do this in a reactive methodology.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.