http 통신에서 에러가 났을 때 화면에 에러 메시지를 표시하는 흐름은 흔히 볼 수 있는 화면 구성입니다. 하지만 만약 Angular의 OnPush Change Detection Strategy를 사용한다면 원하는 대로 화면 갱신이 이뤄지지 않을 수도 있습니다. 이번 포스트는 OnPush 전략 시 Observable을 사용해서 화며 갱신이 이루어지고 에러 메시지를 표시하는 과정을 소개하겠습니다.
1. 문제점 : OnPush 사용시 프로퍼티 값이 바뀌어도 화면이 갱신이 되지 않음
우선 문제되는 컴포넌트의 코드를 살펴보겠습니다.
컴포넌트에서 Angular의 OnPush 변경 감지를 사용하고 있습니다. OnPush 변경 감지 전략은 input 프로퍼티, 이벤트, async 파이프를 사용하는 옵저버블 의 변경 사항에만 감지를 해줍니다. 컴포넌트의 변경 감지 전략을 OnPush로 하는 주요한 이유는 성능 향상을 위해서입니다. 퍼포먼스를 올리고 싶은 페이지가 있다면 해당 컴포넌트를 OnPush 전략으로 바꿔보는 것도 의미 있는 시도가 되곤 합니다.
http 통신에서 에러가 났을때, 다시 말해 데이터 스트림에서 에러가 발생했을 때 catchError를 사용하여 에러를 잡아주고 에러 메시지를 errrMessage에 할당해 주고 있습니다. 이것으로 에러가 발생했을 시 에러 메시지가 화면에 출력되는 것을 기대하지만 현재 코드로는 화면 갱신이 이뤄지지 않습니다. errorMessage를 출력하는 템플릿 코드를 살펴보겠습니다.
ngIf로 errorMessage가 유효한지 확인한 다음, 인터폴레이션으로 errorMessage를 출력하고 있습니다. OnPush 전략만 아니라면 유효한 코드입니다. 하지만 현재 컴포넌트는 OnPush 변경 감지 전략을 사용하고 있으므로 errorMessage와 같이 로컬 속성에 설정된 바운드 값은 변경 감지를 트리거하지 않으므로 UI를 업데이트하지 않습니다.
잘못된 url를 일부러 호출해 보고 에러를 내보겠습니다.
화면에 에러가 발생 했지만, 에러 메시지가 화면에 출력되지 않았습니다. 이 현상을 옵저버블을 활용해 해결해 보도록 하겠습니다.
2. 해결책 : 옵저버블로 수정하기
errorMessage 프로퍼티를 옵저버블인 액션 스트림으로 변경해 보겠습니다.
액션 스트림은 Subject를 이용해 만듭니다. Subject를 만들어 주었고 errorMessageSubject에 할당해 주었습니다. 그런 다음 asObservable을 사용하여 연결할 옵저버블을 노출합니다. catchError안의 함수에서는 이제 Subject의 next 메서드를 호출하여 스트림에 내보낼 값을 전달합니다. 이제 errorMessage 프로퍼티 대신에 errorMessage$ 옵저버블을 사용하도록 템플릿을 업데이트해야 합니다.
errorMessage$를 async 파이프를 사용하여 옵저버블이 바인딩되도록 템플릿을 수정하였습니다. 템플릿에 변수를 사용하기 위해 as를 사용하였습니다.
에러 메시지를 스트림으로 바꿔주는 수정이 다 끝났습니다. 에러가 발생했을 때 화면을 살펴보겠습니다.
에러가 잘 나오네요! 우리는 에러를 옵저버블로 바꿔주고 async 파이프로 구독하게 수정하였습니다. 그 덕에 OnPush 변경 감지 전략에서도 변경이 감지되어 화면이 갱신되었습니다. 에러 메시지도 잘 표시되었고 화면의 OnPush 전략으로 인해 성능도 향상 되었습니다.
여기까지 수고하셨습니다.
'프로그래밍 > Angular' 카테고리의 다른 글
[RxJS / angular] 22. concatMap 이해하기 (옵저버블 매핑 + concat ) (0) | 2022.08.12 |
---|---|
[RxJS / angular] 21. 고차 옵저버블과 고차 매핑 연산자 (0) | 2022.08.09 |
[RxJS / angular] 19. Subject 액션 스트림으로 데이터 필터링 하기 (0) | 2022.08.02 |
[RxJS / angular] 18. Subject와 BehaviorSubject (0) | 2022.07.30 |
[RxJS / angular] 17. 데이터 스트림과 액션 스트림, Subject를 사용하는 이유 (0) | 2022.07.28 |
댓글