Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

어리바리 신입 개발자의 얼렁뚱땅 개발 기록 ✨

23.07.30 / [jquery / 데이터테이블]Uncaught TypeError: Cannot read properties of undefined (reading 'style') 본문

TEAM PROJECT

23.07.30 / [jquery / 데이터테이블]Uncaught TypeError: Cannot read properties of undefined (reading 'style')

낫쏘링 2023. 7. 30. 03:21
728x90

Uncaught TypeError: Cannot read properties of undefined (reading 'style')
    at bt (jquery.dataTables.min.js:1:29409)
    at ot (jquery.dataTables.min.js:1:22201)
    at t (jquery.dataTables.min.js:1:45564)
    at HTMLTableElement.<anonymous> (jquery.dataTables.min.js:1:45651)
    at Function.each (jquery.min.js:1:2967)
    at S.fn.init.each (jquery.min.js:1:1453)
    at S.fn.init.Qt [as dataTable] (jquery.dataTables.min.js:1:40646)
    at P.fn.DataTable (jquery.dataTables.min.js:1:81973)
    at HTMLTableElement.<anonymous> (pointStandardManage:1068:17)
    at Function.each (jquery.min.js:1:2967)

하나의 화면에 탭을 이용해서 ajax로 데이터를 받아와 다섯 개의 테이블을 동적으로 생성하는 작업을 하는 중 발생한 오류

 

이런식으로 하나의 화면에서 탭을 클릭하면 각각 다른 데이터를 담은 테이블이 출력된다.

  • 탭을 클릭하면 각 탭의 아이디를 tableId 변수로 담아준다.
  • ajax를 통해서 tableId를 컨트롤러에 보내주고 각 테이블에 해당하는 데이터를 받아온다.
  • 각 테이블의 컬럼 개수가 다르기 때문에 for문을 통해서 배열에 컬럼을 모두 담아주고 데이터 테이블의 속성에 추가해줬다.
 // key(title) : <th> , value(data) : <td>에 담아주기 위해 배열 선언 
const newData = [
    { 
    // tbody의 모든 tr의 첫번째 인덱스에는 체크박스를 추가해줬다.
    data: null, 
    defaultContent: '<input type="checkbox" class="custom-control custom-checkbox checkbox checks">', 
    orderable: false, 
    targets: 0 
    }
];

// response는 ajax를 통해 받아온 data로 배열 안에 객체 여러 개가 존재하는 형태
// response : 배열 , list : 객체
for (let obj of response){
    for(let key in obj){
        newData.push({
            title: key,  // key 자체를 문자열로 컬럼에 넣어줄 예정
            data: key  // key와 일치하는 value를 행으로 넣어줄 예정 (data의 키)
        });
    }
    break; // 어차피 컬럼은 객체 하나만 돌아도 되기 때문에 한 번만 돌고 반복문을 끝내준다.
}

$('#pointStandardManage').each(function() {
    const table = $(this);
    table.DataTable({
        data: response, // 배열에 담아줬던 data와 일치하는 것을 response에서 찾는다.
        columns: newData // 배열에 담아줬던 key들
    });
});

 

그랬더니 기존 html에 존재하는 컬럼 개수 (th 태그의 개수) 와 컬럼 개수가 같은 테이블들은 정상적으로 출력됐지만 컬럼 개수가 더 많은 테이블들은 Uncaught TypeError: Cannot read properties of undefined (reading 'style') 오류가 발생했다.

검색해보니 기존에 html에 존재하는 th태그와 받아온 newData의 개수가 달라서 그런거였다.

그래서 기존에 출력됐던 테이블의 컬럼 개수와 개수가 일치하는 테이블은 출력이됐는데 더 많은 테이블은 오류가 발생했던 것....!

검색해서 찾은 해결 방법은 그냥 컬럼 개수에 맞게 th 태그를 추가해주라는 것 뿐이었다.

나는 받아오는 컬럼 개수를 모른다는 가정하에 테이블을 생성해주고 싶기도 했고,
테이블이 5개나 돼서 컬럼 개수가 다른 데이터를 받아올 때 마다 th 태그를 하나 하나 추가해주면 코드가 너무 길어지기 때문에 (나중에 테이블이 10개가 되면....?????)
이미 받아뒀던 newData 배열의 길이와 for문을 이용해서 추가해주기로 했다.

// thead의 th와 tbody의 td 비우기 
// (깔끔하게 지워주고 다시 시작하기 위해서 지워줬다.)
// 단, 체크박스는 굳이 지워주지 않았음
$('thead tr th:not(:first-child)').remove();
$('tbody').remove();

// newData의 길이(새로 받아온 테이블의 컬럼 개수)를 변수에 담아준다.
// 단, 위에서 체크박스는 지워주지 않았기 때문에 -1을 해줬다.
const newDataNum = newData.length-1; 

// for문을 돌면서 newDataNum 만큼 th 태그 추가
for(let i = 0 ; i < newDataNum ; i += 1) {
    $('thead tr').append('<th></th>');			        	
}

 

그랬더니 해결됐다 !

728x90