Tengo una función que crea el cliente, pero antes de eso debería verificar si hay nombres similares en la base de datos. Si los hay, devuelve una cadena de matriz con esos nombres, si no, devuelve una matriz vacía. Mi código hasta ahora:
let similarNames:string[] = []; this.clientsService.getSimilarNames(clientFormData.clientName, 0).subscribe(res => { similarNames = res; console.log("Length: ", similarNames.length) console.log(similarNames) <-- console.log shows that everything is fine there if(similarNames.length > 0){ this.confirmationService.confirm({ message: 'There are already similar names:' + similarNames, header: 'Similar names', icon: 'fa fa-exclamation-triangle', acceptLabel: 'Yes', rejectLabel: 'No', accept: () => {}, reject: () => {return;} }) } this.clientsService.createClient(clientFormData).subscribe(resp => { this.isLoading = false; this.onCreateClientSuccess(); }, error => { this.isLoading = false; this.messageHelperService.showErrorMessage(error, this.messages.CreateError); }); })Mi problema es que this.clientService.createClient no espera a que finalice el código en la declaración if. En este momento, crea el cliente y luego muestra nombres similares y solicita crear. Quiero que funcione así: si hay algún nombre similar, debe aparecer una ventana emergente con una lista de esos nombres y, si se acepta, debe continuar con la creación de un cliente; si se rechaza, debe salir de la función y no crear el cliente.
¡Hola y bienvenido a la comunidad de StackOverflow en primer lugar!
En realidad, procedería con RxJS encadenándolos con pipe y exhaustMap .
this.clientsService.getSimilarNames(clientFormData.clientName, 0).pipe( exhaustMap(res => { similarNames = res; console.log("Length: ", similarNames.length) console.log(similarNames) <-- console.log shows that everything is fine there if( similarNames.length > 0 ){ return this.confirmationService.confirm({ message: 'There are already similar names:' + similarNames, header: 'Similar names', icon: 'fa fa-exclamation-triangle', acceptLabel: 'Yes', rejectLabel: 'No', accept: () => {}, reject: () => {return;} }) } return of(); }), exhaustMap(responseFromConfirm => this.clientsService.createClient(clientFormData)) ).subscribe( () => { this.isLoading = false; this.onCreateClientSuccess(); }, error => { this.isLoading = false; this.messageHelperService.showErrorMessage(error, this.messages.CreateError); }); De esta manera, está encadenando su operación asíncrona y emitiendo el valor del siguiente operador solo cuando se completa. Por supuesto, la creación se activará incluso si falla la comprobación de los similiarNames .
Para obtener más información acerca de, consulte exhaustMap
Puede poner el código creatClient en otra else y duplicarlo en el uso de la devolución de llamada de accept
Por supuesto, entonces duplicará el código sin una buena razón.
Entonces, es mejor crear una función para el código "común" y hacer algo como
tenga en cuenta que la función es una función de flecha, para preservar this
let similarNames: string[] = []; this.clientsService.getSimilarNames(clientFormData.clientName, 0).subscribe(res => { similarNames = res; console.log("Length: ", similarNames.length) console.log(similarNames) const fn = () => { this.clientsService.createClient(clientFormData).subscribe(resp => { this.isLoading = false; this.onCreateClientSuccess(); }, error => { this.isLoading = false; this.messageHelperService.showErrorMessage(error, this.messages.CreateError); }); }; if (similarNames.length > 0) { this.confirmationService.confirm({ message: 'There are already similar names:' + similarNames, header: 'Similar names', icon: 'fa fa-exclamation-triangle', acceptLabel: 'Yes', rejectLabel: 'No', accept: fn, reject: () => {} }); } else { fn() } })Otra alternativa es usar async/await y una nueva Promesa: parece OTT para la situación, pero el código parece limpio (en mi humilde opinión)
let similarNames: string[] = []; this.clientsService.getSimilarNames(clientFormData.clientName, 0).subscribe(async (res) => { similarNames = res; try { if (similarNames.length > 0) { await new Promise((resolve, reject) => { this.confirmationService.confirm({ message: 'There are already similar names:' + similarNames, header: 'Similar names', icon: 'fa fa-exclamation-triangle', acceptLabel: 'Yes', rejectLabel: 'No', accept: resolve, reject: reject // will result a thrown error }); }); } this.clientsService.createClient(clientFormData).subscribe(resp => { this.isLoading = false; this.onCreateClientSuccess(); }, error => { this.isLoading = false; this.messageHelperService.showErrorMessage(error, this.messages.CreateError); }); } catch { } })