У меня есть функция, которая создает клиента, но перед этим она должна проверить, есть ли похожие имена в базе данных. Если есть, возвращает строку массива с этими именами, если нет, возвращает пустой массив. Мой код до сих пор:
let similarNames:string[] = [];
this.clientsService.getSimilarNames(clientFormData.clientName, 0).subscribe(res => {
similarNames = res;
console.info("Length: ", similarNames.length)
console.info(similarNames) <-- console.info 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);
});
})
Моя проблема в том, что this.clientService.createClient не ждет завершения кода в операторе if. Прямо сейчас он создает клиента, а затем показывает похожие имена и просит создать. Я хочу работать так: если есть какое-либо похожее имя, всплывающее окно должно появиться со списком этих имен, и если оно будет принято, оно должно просто перейти к созданию клиента, если отклонено, оно должно выйти из функции и не создавать клиент.
Вы можете поместить код creatClient в else
и продублировать его при использовании обратного вызова accept
Конечно, тогда вы будете дублировать код без уважительной причины.
Итак, лучше создать функцию для «общего» кода и сделать что-то вроде
обратите внимание, что функция является функцией стрелки, чтобы сохранить this
let similarNames: string[] = [];
this.clientsService.getSimilarNames(clientFormData.clientName, 0).subscribe(res => {
similarNames = res;
console.info("Length: ", similarNames.length)
console.info(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()
}
})
Другой альтернативой является использование async/await и нового промиса - кажется, OTT для ситуации, но код выглядит чистым (ИМХО).
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 {
}
})
@Pr0tn12 Pr0tn12 Я только что отредактировал ответ, потому что понял: p
Привет и добро пожаловать в сообщество StackOverflow!
На самом деле, я бы продолжил с RxJS, объединив их в цепочку с pipe
и exhaustMap
.
this.clientsService.getSimilarNames(clientFormData.clientName, 0).pipe(
exhaustMap(res => {
similarNames = res;
console.info("Length: ", similarNames.length)
console.info(similarNames) <-- console.info 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);
});
Таким образом, вы связываете свою асинхронную операцию и выдаете значение следующего оператора только после завершения. Конечно, создание будет запущено, даже если проверка на similiarNames
не пройдена.
Я знаю, что могу просто вставить в accept, но я ищу способ без дублирования кода