I have a function in my component.ts
file. What I want to do is to make sure that uploadFile()
operation is completed before this.isModalOpen=false
, this.form.reset()
and this.list.get()
are executed. My code works just fine but I want to do this to avoid potential problems in the future. If someone can propose a solution and also explain to me the logic behind it, I would appreciate it.
save() {
if (this.form.invalid) {
return;
}
if(this.selectedCandidate.id){
this.candidateService.update(this.selectedCandidate.id, this.form.value).subscribe(()=>{
if(this.form.get('file').value){
this.uploadFile(this.selectedCandidate.id);
}
this.isModalOpen=false;
this.form.reset();
this.list.get(); });
}
else{
this.candidateService.create(this.form.value).subscribe((candidateCreate)=>{
if(this.form.get('file').value){
this.uploadFile(candidateCreate.id);
}
this.isModalOpen=false;
this.form.reset();
this.list.get();
});
}
}
uploadFile()
is just a function to upload a pdf file.
uploadFile(id:string){
const formData = new FormData();
var SERVER_URL = `https://localhost:44310/api/app/cv/${id}/upload-cv`;
formData.append('file', this.form.get('file').value);
this.httpClient.post<any>(SERVER_URL,formData).subscribe((res) => console.log(res), (err) => console.log(err));
}
CodePudding user response:
Can you change your upload File function return the observable instead? If you need to catch the error wire up a catchError pipe.
uploadFile(id:string){
const formData = new FormData();
var SERVER_URL = `https://localhost:44310/api/app/cv/${id}/upload-cv`;
formData.append('file', this.form.get('file').value);
return this.httpClient.post<any>(SERVER_URL,formData)
}
this.candidateService.create(this.form.value).subscribe((candidateCreate)=>{
if(this.form.get('file').value){
this.uploadFile(candidateCreate.id)
.subscribe(() => this.isModelOpen=false);
}
else {
this.isModalOpen=false;
this.form.reset();
this.list.get();
}
});
CodePudding user response:
If you make your uploadFile
method return an observable:
uploadFile(id:string): Observable<any> {
const formData = new FormData();
var SERVER_URL = `https://localhost:44310/api/app/cv/${id}/upload-cv`;
formData.append('file', this.form.get('file').value);
return this.httpClient.post<any>(SERVER_URL, formData);
}
You could do something like this:
save() {
if (this.form.invalid) {
return;
}
operation$ = this.selectedCandidate.id
? this.candidateService.update(this.selectedCandidate.id, this.form.value)
: this.candidateService.create(this.form.value);
request$ = operation$.pipe(
switchMap(canidate => this.form.get('file').value
? this.uploadFile(candidate.id)
: of(undefined)
)
);
reqeust$.subscribe(() => {
this.isModalOpen = false;
this.form.reset();
this.list.get();
}));
}
The idea here is to use build a single observable (request$
) that will emit once all of your "work" is done. We define request$
to begin with operation$
piping its emission into a switchMap
.
We pass a function that returns an observable into switchMap
; the function returns either the call to uploadFile()
or an observable that instantly emits undefined
(indicating no file was uploaded) using of
.
This "inner observable" is subscribed to automatically by switchMap
and its emissions are emitted.
Now, we can simply subscribe to request$
and receive an emission whenever the work is done. Therefore, anything inside your subscribe()
will only be executed after the work is done.