728x90
자바스크립트에서 공부를 하고 Typescrpt에서도 this를 자주 보게 된다. 그런데 이해를 제대로 하지 않고 SKIP 하는 순간 this의 지옥이 찾아온다.. ㅋㅋ
코드를 보면서 이해를 해보자. 아래의 hashingPw메서드에서 this.password 에서 this는 무엇을 가리키는 지 ?
정답은 findOne 메서드를 호출된 Member 엔티티(row) 이다. @Column({select:false}) 설정으로 인해서 findOne 메서드를 호출하면 password 컬럼이 hide상태로 즉 udserId | address | name | address | memberRole | lastActivityAt | isDormant | verified 이런 entity의 원본이 항상 유지된다.
따라서 this.password는 undefined가 된다는 것을 예상할 수 있다.
*Column({select: false})의 이해: Defineds whether or not to hide column by default when making
queries ( " find메서드를 작성할 때 기본적으로 ' 이열을 숨길 지 여부를 정의' )
false이므로 hide
[member.entity.ts]
import { CoreEntity } from 'src/common/entites/core.entity';
import { BeforeInsert, BeforeUpdate, Column, Entity } from 'typeorm';
import * as bcrypt from "bcrypt";
import { InternalServerErrorException } from '@nestjs/common';
import { registerEnumType } from '@nestjs/graphql';
registerEnumType(MemberRole, { name: 'MemberRole'});
@Entity()
export class Member extends CoreEntity {
@Column()
userId: string;
@Column({select: false})
password: string;
@Column({nullable : true})
name: string;
@Column({nullable : true})
address: string;
@Column({nullable:true})
memberRole: MemberRole;
@Column({nullable : true})
lastActivityAt:Date;
@Column({nullable : true})
isDormant:boolean;
@Column({nullable : true})
verified: boolean;
@BeforeInsert() //@explain:최초 삽입 시, (값이 없을 때) 아래의 method를 호출
@BeforeUpdate() //@explain: 최초 삽입 후 두 번째 Update부터 아래의 method를 호출이다.
async hashingPw(): Promise<void> {
//여기서 this 바인딩을 생각해야된다!
✅if(this.password){
try {
this.password = await bcrypt.hash(this.password, 10)
} catch (e) {
console.log(e)
throw new InternalServerErrorException()
}
}
}
async checkingPw(reqPassword : string) : Promise<boolean> {
try {
const ok = await bcrypt.compare(reqPassword, ✅this.password); //this => member 변수, select로 password를 가져옴
return ok;
} catch(e) {
throw new InternalServerErrorException('The password is wrong!');
}
}
}
그런데 위 checkingPw 함수에서 this.password에서 this에 바인딩 되는 객체는 바로 아래의 member 변수이다. 따라서 member 변수는 select: ['password'] 가 명시되어 this.password의 경우 어느 유저의
entity에서의 password값이 정상적으로 들어온다.
[member.service.ts]
@Injectable()
export class MemberService {
constructor(
@InjectRepository(Member)
private readonly members: Repository<Member>,✅
@InjectRepository(Verification)
private readonly verification: Repository<Verification>,
private readonly jwtService: JwtService,
) {}
async login({ userId, password }: LoginInput): Promise<LoginOutput> {
try {
const ✅member = await this.members.findOne({
where: { userId:userId },
select: ['userId', 'password'], //Specifies what columns should be retrieved.
});
const confirmPw = await member.checkingPw(password);✅
} catch (e) {
console.error(e)
}
}
728x90
'Typescript & React' 카테고리의 다른 글
Typscript 문법 오류 (0) | 2024.06.14 |
---|---|
React에서 react-hook-form 새로고침 문제 해결 방법은? (0) | 2024.06.12 |
SyntaxError: Unexpected end of JSON input (0) | 2024.02.15 |
useHistory에서 새로고침이 되지 않을 때 해결방안 (0) | 2024.02.03 |
never type (0) | 2024.01.02 |