Home > Enterprise >  Determining the order within subscribe()
Determining the order within subscribe()

Time:05-17

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.

  • Related