DB update가 성공했는지 확인하기 위해 node-sqlite3의 Database.run에서 제공하는 this.changes를 사용하려 한다.
TL; DR
화살표 함수 대신 함수 선언문을 사용하자.
문제 확인
아래와 같이 코드를 작성하면,
db.run(`
UPDATE your_table_name
SET value1=(?), value2=(?)
WHERE id=(?) AND created=date('now', 'localtime');
`,
[value1, value2, id],
(err) => {
if (err)
console.error(err.message);
handler({
status: (this.changes === 1) ? "modify_success" : "modify_failed"
})
}
);
아래와 같은 에러가 발생한다.
Uncaught TypeError: Cannot read property 'changes' of undefined
at Statement.eval (webpack-internal:///./src/db/db.js:180:20)
this가 undefined라는 소리인데, 분명 명세서에는 맞게 적혀있는데?? sqlite3의 소스코드에 직접 접근해봤다. (db.run을 cmd + click하면 바로 코드를 확인할 수 있다.) 모듈은 typescript로 작성되어 있다. callback이 RunResult 타입의 this를 변수로 받는 걸 확인할 수 있다.
export class Database extends events.EventEmitter {
...
run(sql: string, callback?: (this: RunResult, err: Error | null) => void): this;
run(sql: string, params: any, callback?: (this: RunResult, err: Error | null) => void): this;
run(sql: string, ...params: any[]): this;
...
}
맞는데??? 왜 안될까?
문제의 원인 = (err) => { ... }
내 지식이 짧기도 하지만, 라이브러리 설계의 문제이기도 하다. ES6부터 제공되는 화살표 함수는 this를 정의하지 않는다. 대신 코드 바깥의 함수에서 사용하는 this 값을 그대로 사용한다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/애로우_펑션
정확한 내용은 MDN의 화살표 함수 문서에서 바인딩 되지 않은 this
를 참고하면 좋을 듯하다.
- webpack이 ES6를 strict mode로 컴파일한다.
- 화살표 함수 속 this는 lexical, 정적 변수가 되어버린다.
- this 값을 덮어쓸 수 없다.
위 과정을 거쳐 에러가 발생하는 것이다.
문제 해결
문제를 해결하기 위해 화살표 함수를 함수 선언문으로 변경하였다.
이미 Git repository에 해당 문제에 대한 이슈가 등록되어 있지만, 2015년에 올라온 이슈가 아직까지 Open 된 상태라 고쳐질 가능성은 없다고 봐야하는 듯. 대안으로 mozilla에서 만든 promise-sqlite를 제시한 사람이 있다.
이슈: https://github.com/mapbox/node-sqlite3/issues/560
대안: https://github.com/mozilla/promise-sqlite
도움이 된 링크
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/애로우_펑션
https://github.com/mapbox/node-sqlite3/issues/560
맨 마지막 블로그에서 답을 얻고 더 찾다보니 위 이슈와 MDN 레퍼런스를 찾았다. 위 글을 쓴 이유는 해당 블로그 글에서는 원인을 설명해주지 않기 때문.
'React' 카테고리의 다른 글
이거 하나만 있으면 클린 코드 해결! ESLint (0) | 2020.01.22 |
---|---|
이슈 8 Error: Cannot find module 'source-map-support/source-map-support.js' (0) | 2020.01.22 |
이슈 6 단 한 줄! index.js로 내 코드 깔끔하게 import하기 (0) | 2020.01.17 |
이슈 5 react 아이콘 사용법 react-icons (0) | 2020.01.14 |
이슈 4 react form 버튼 새로고침 막기 (0) | 2020.01.14 |