Angular外部订阅值为空

huangapple go评论92阅读模式
英文:

Angular Outside Subscribe Value Null

问题

我在一个项目中工作,基本上通过一个叫做 ServiceHandler 的中介类调用服务方法。在组件中,结果变量的控制台输出是 `undefined`。
有没有解决这个问题的方法?

**组件**

    this.entityServiceHandler.saveEntityWithCondition(entity).subscribe(data => { this.result = data});

    console.log(this.result);

**ServiceHandler**

    public saveEntityWithCondition(entity): Observable<Entity>{
    	var subject = new Subject<any>();

    	this.subscriptions.push(
    	  forkJoin({
    		conditionTrue: this.entityService.isConditionTrue(entity.property)
    	  }).subscribe(({ conditionTrue }) => {

    		if (conditionTrue) {

    			this.entityService.save(entity).subscribe(
    			  (response: Entity) => {
    				subject.next(response);

    			  },
    			  (errorResponse: HttpErrorResponse) => {

    			  }
    			)
    		}
    	  },
    	  err => {},
    	  () => {
    	  }));

    	return subject.asObservable();

    }

**服务**

    public save(item: Entity) : Observable<Entity>{

      public save(item: Entity): Observable<Entity> {   
          return this.httpClient.post<Entity>(`path`, item).pipe(catchError((err) => this.handleAndThrowError(err)));
        }  
    }
英文:

I work on a project that basically calls service method via a mediate class which is called ServiceHandler. In the component the console output of the result variable is undefined.
Is there any solution to solve this problem?

Component

this.entityServiceHandler.saveEntityWithCondition(entity).subscribe(data =&gt; { this.result = data});

console.log(this.result);

ServiceHandler

public saveEntityWithCondition(entity): Observable&lt;Entity&gt;{
	var subject = new Subject&lt;any&gt;();

	this.subscriptions.push(
	  forkJoin({
		conditionTrue: this.entityService.isConditionTrue(entity.property)
	  }).subscribe(({ conditionTrue }) =&gt; {
   
		if (conditionTrue) {
		
			this.entityService.save(entity).subscribe(
			  (response: Entity) =&gt; {
				subject.next(response);
				
			  },
			  (errorResponse: HttpErrorResponse) =&gt; {
				
			  }
			)
		}
	  },
	  err =&gt; {},
	  () =&gt; {
	  }));

	return subject.asObservable();

}

Service

public save(item: Entity) : Observable&lt;Entity&gt;{

  public save(item: Entity): Observable&lt;Entity&gt; {   
      return this.httpClient.post&lt;Entity&gt;(`path`, item).pipe(catchError((err) =&gt; this.handleAndThrowError(err)));
    }  
}

答案1

得分: 1

Welcome to StackOverflow. The reason why you see undefined is that you are mixing synchronous and asynchronous code and this often leads to problems. Just move the console.log inside the subscribe and it should be OK.

// Kode asinkron - memerlukan waktu untuk menyelesaikan
this.entityServiceHandler.saveEntityWithCondition(entity).subscribe(data =&gt; {
  this.result = data;
  console.log(this.resul) // Ini akan ditampilkan
});

// Kode sinkron - terjadi segera setelah memanggil yang sebelumnya, tidak menunggu
// untuk menyelesaikannya. Ini berarti, hasilnya tidak terdefinisi
console.log(this.result);

EDIT:
Saya mengambil kebebasan dan menyederhanakan kode Anda sedikit. Anda melakukan banyak hal yang tidak perlu, seperti forkJoin hanya untuk satu observable. Atau mendorong langganan ke dalam Array, kemungkinan untuk menutupnya nanti, tetapi tidak diperlukan ketika Anda menyusun ulang kode Anda sedikit.

import { filter, switchMap, catchError, EMPTY } from 'rxjs';

public saveEntityWithCondition(entity): Observable<Entity> {
  // Tidak perlu forkJoin, cukup panggil fungsi dan salurkan
  return this.entityService.isConditionTrue(entity.property).pipe(
    // Ini memastikan bahwa conditionTrue memang benar
    filter(conditionTrue => conditionTrue),
    // Kemudian gunakan switchMap untuk memanggil layanan entitas dan melakukan penyimpanan
    switchMap(() => this.entityService.save(entity)),
    // Dan gunakan catchError untuk menangani masalah yang mungkin terjadi
    catchError(error => {
      // tangani kesalahan dengan cara tertentu - misalnya, log atau yang lain;
      return EMPTY; 
    })
  );

}

Anda tidak memerlukan subject lagi karena Anda mengembalikan Observable<Entity> langsung.

Anda juga tidak perlu mendorong Subscription ke dalam array, karena berkat HttpClient yang Anda gunakan dan operator switchMap yang disertakan, itu akan menangani unsubcribe secara otomatis, ketika save selesai.

英文:

welcome to StackOverflow. The reason why you see undefined is that you are mixing synchronous and asynchronous code and this often leads to problems. Just move the console.log inside the subscribe and it should be OK.

// Asynchronous code - takes some time to finalize
this.entityServiceHandler.saveEntityWithCondition(entity).subscribe(data =&gt; {
  this.result = data;
  console.log(this.resul) // This&#39;ll be shown
});

// Synchronous code - happens just after calling previous, doesn&#39;t wait for it
// to finish. This means, result is undefined
console.log(this.result);

EDIT:
I took a liberty and simplified your code a bit. You are doing lots of unnecessary things, like forkJoin for just one observable. Or pushing a subscription to an Array, likely to close it later, but it's not needed when you refcator your code a bit.

import { filter, switchMap, catchError, EMPTY } from &#39;rxjs&#39;;

public saveEntityWithCondition(entity): Observable&lt;Entity&gt; {
  // No need to forkJoin, just call the function and pipe it
  return this.entityService.isConditionTrue(entity.property).pipe(
    // This makes sure that conditionTrue is true indeed
    filter(conditionTrue =&gt; conditionTrue),
    // Then use switchMap to call the entity service and perform save
    switchMap(() =&gt; this.entityService.save(entity)),
    // And use catchError to handle possible issues
    catchError(error =&gt; {
      // handle error in some way - i.e. log it or something;
      return EMPTY; 
    })
  );

}

You don't need subject anymore because you are returning the Observable&lt;Entity&gt; directly.

You also don't need to push the Subscription to an array, because thanks to the HttpClient you are using and the switchMap operator included, it will handle unsubcribe automatically, when save is finished.

huangapple
  • 本文由 发表于 2023年8月10日 12:16:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76872621.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定