티스토리 뷰

[Error] uncaught (in promise) typeerror: cannot read properties of undefined (reading 'style')

Error Message

DOM 관련 에러

Use Tech

  • Svelte
  • ag_grid (Data table library)

Solve

Svelte의 {#if} 문법을 사용하니 갑자기 다음과 같은 에러가 발생하였습니다.
Error Message를 읽어보니 다음과 같이 해석을 할 수 있습니다.

uncaught (in promise) typeerror: 정의되지 않은 속성을 읽을 수 없습니다.('style' 읽기)

우선 결론부터 이야기를 해보겠습니다.
생성되지 않은 ag-grid 테이블(DOM)에 접근해서 발생한 문제입니다.

보통 undefined 된 것들을 반복하거나 생성되지 않은 DOM에 접근했을 때 많이 발생하는 Error입니다.

에러 메시지를 보고 다음과 같은 예측을 두고 문제에 접근하였습니다.

1. ag-grid 내부 function을 잘 못 사용하고 있다.

2. 정의되지 않은(undefined) 속성에 접근하려는 코드가 있다.

1. ag-grid 내부 function을 잘 못 사용하고 있다.

ag-grid에서 사용하는 option들이 있습니다.

그러나 cellRenderer, defaultColDef 등을 바꿔서 사용해 보고 ag-grid를 그리는 div의 inline attribute를 변경해 보았는데 문제는 해결되지 않아 다음 단계로 넘어가게 되었습니다.

2. 정의되지 않은(undefined) 속성에 접근하려는 코드가 있다.

사실 이 부분을 가장 크게 생각하고 있었습니다.
우선, undefined한 배열을 돌고 있는 것이 있는지, 접근하고 있는지를 파악해 보았는데 이 부분은 없었습니다. (대부분에 예외 처리를 해놨습니다)

그래서 stackoverflow에 생성되지 않은 DOM에 접근하는 경우도 이런 일이 발생한다는 글을 읽어 코드를 다시 보았습니다.

<해결 전>

  {#if ref_move_result}
        <div style="display: flex; justify-content: center;">
            <div class="div_result_container_cls">
                <div class="div_result_title_cls">↓ 이동한 브랜드 결과 ↓</div>
                <span class="span_result_brand_title_cls">{ref_moved_brand}(브랜드) 상품 리스트</span>
                <div bind:this={ref_result_product_this_grid} class="ag-theme-balham" style="height: 280px; font-size: 13px;"></div>
            </div>
        </div>
    {/if}

여러 상황을 해보니 {#if} {/if} 부분 제거해 보니 정상적으로 동작을 잘하는 것을 알게 되었지만 제가 알기로는 ref_move_resultfalse일 때 {#if} {/if} 내부의 DOM은 그려준다고 생각하고 있었지만 틀린 생각이었습니다. (=>{#if}가 false이면 내부 Html을 그려주지 않는다)

Svelte는 .svelte 파일을 구문 분석하고 JavaScript 파일을 생성하는 컴파일러입니다. 조금 자세히 들어가면 .svelte 파일 내부는 <script>, <style>, visual tag로 되어 있으며 다 parsing을 진행합니다.

<style>

style태그는 각 CSS 규칙에 고유한 접두사를 추가할 수 있도록 구문 분석이 되어 CSS 규칙과 충돌하지 않습니다.

[before]

h1 {
    color: red;
}

[after]

h1.random-code-12314 {
    color: red;
}

<script>

<script> 태그 내부 구문을 분석하여 export 문(props)을 추출하고 반응성 문을 찾습니다.

visual tag

Html 같은 태그를 분석합니다.

간단히 이렇게 동작하게 되는데 Svelte에는 tick(): DOM 업데이트가 완료되고 Promise 객체 반환하는 함수입니다. DOM이 아직 그려지지 않은 부분에 tick()을 넣어 문제를 해결하려고 했지만 Debugging을 통해 보니 ag-grid 라이브러리 자체에서 그려주는 내부 table에 접근해서 생긴 문제여서 다음과 같이 display: none을 사용해서 문제를 해결하였습니다.

<해결 후>

    <div style="display: {!ref_move_result ? 'none' : 'flex'}; justify-content: center;">
        <div class="div_result_container_cls">
            <div class="div_result_title_cls">↓ 이동한 브랜드 결과 ↓</div>
            <span class="span_result_brand_title_cls">{ref_moved_brand}(브랜드) 상품 리스트</span>
            <div bind:this={ref_result_product_this_grid} class="ag-theme-balham" style="height: 280px; font-size: 13px;"></div>
        </div>
    </div>

마치며

많은 생각을 했지만 가정을 여러 가지 해놓고 찾아가는 방법이 문제해결 하는 시간을 많이 단축한다는 것을 깨달았고 {#if}false 일 때 미리 그려주지 않아 내부에 자체적으로 Html 등을 그려주는 라이브러리를 사용하지 말아야겠다는 생각도 하게 되었습니다.

REF

https://dev.to/joshnuss/svelte-compiler-under-the-hood-4j20
https://itchallenger.tistory.com/822
https://svelte.dev/tutorial/tick

반응형
공지사항
최근에 올라온 글