node.js - 在 Angular+NodeJS 程序中编写注册方法的问题
问题描述
我正在尝试编写一个简单的注册方法,以下是我使用的代码:
ClientSide_codes,auth.servise.ts:
checkUserExistence(user : User) : any {
this.http.get<UserResponse>(baseURL + 'users/findUser')
.subscribe(res => {
if(res.success){
console.log('user founded!');
return true;
}
},
err => {
console.log('A problem happened: ', err);
this.destroyUserCredentials();
return false;
});
}
signUp(user: any): Observable<any> {
if (this.checkUserExistence(user) === false) {
return this.http.post<RegResponse>(baseURL + 'users/signup',
{'username': user.username, 'password': user.password, 'firstname' : user.firstname, 'lastname': user.lastname})
.pipe( map(res => {
this.storeUser({username: user.username});
return {'success': true, 'username': user.username };
}),
catchError(error => this.processHTTPMsgService.handleError(error)));
}
else{
console.log('This user already exists!');
return ;
}
}
注册组件.ts:
export class SignupComponent implements OnInit {
user = {username: '', password: '', firstname: '', lastname: '', remember: false};
errMess: string;
constructor(public dialogRef: MatDialogRef<SignupComponent>,
private authService: AuthService) { }
ngOnInit() {
}
onSubmit() {
console.log('User: ', this.user);
this.authService.signUp(this.user)
.subscribe(res => {
if (res.success) {
this.dialogRef.close(res.success);
} else {
console.log(res);
}
},
error => {
console.log(error);
this.errMess = error;
});
}
}
后端代码,usersRouter.js:
usersRouter.post('/signup', cors.corsWithOptions, (req, res, next) => {
User.register(new User({username: req.body.username}),
req.body.password, (err, user) => {
if(err) {
res.statusCode = 500;
res.setHeader('Content-Type', 'application/json');
res.json({err: err});
}
else {
user.password = req.body.password;
if (req.body.firstname)
user.firstname = req.body.firstname;
if (req.body.lastname)
user.lastname = req.body.lastname;
if (req.body.admin)
user.admin = req.body.admin;
user.save((err, user) => {
if (err) {
res.statusCode = 500;
res.setHeader('Content-Type', 'application/json');
res.json({err: err});
return next(err);
}
passport.authenticate('local')(req, res, () => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json({success: true, status: 'Registration Successful!'});
});
});
}
});
});
当我尝试注册一个新用户并且我知道该用户不存在时,它会给我以下错误:
This user already exists!
core.js:5873 ERROR TypeError: Cannot read property 'subscribe' of undefined
at SignupComponent.onSubmit (signup.component.ts:34)
at SignupComponent_Template_form_ngSubmit_7_listener (signup.component.html:13)
at executeListenerWithErrorHandling (core.js:21685)
at wrapListenerIn_markDirtyAndPreventDefault (core.js:21727)
at SafeSubscriber.schedulerFn [as _next] (core.js:36900)
at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
at SafeSubscriber.next (Subscriber.js:122)
at Subscriber._next (Subscriber.js:72)
at Subscriber.next (Subscriber.js:49)
at EventEmitter.next (Subject.js:39)
defaultErrorLogger @ core.js:5873
handleError @ core.js:5926
handleError @ core.js:13548
executeListenerWithErrorHandling @ core.js:21688
wrapListenerIn_markDirtyAndPreventDefault @ core.js:21727
schedulerFn @ core.js:36900
__tryOrUnsub @ Subscriber.js:183
next @ Subscriber.js:122
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:36819
onSubmit @ forms.js:6253
NgForm_submit_HostBindingHandler @ forms.js:6294
executeListenerWithErrorHandling @ core.js:21685
wrapListenerIn_markDirtyAndPreventDefault @ core.js:21727
(anonymous) @ platform-browser.js:934
invokeTask @ zone-evergreen.js:400
onInvokeTask @ core.js:41235
invokeTask @ zone-evergreen.js:399
runTask @ zone-evergreen.js:168
invokeTask @ zone-evergreen.js:481
invokeTask @ zone-evergreen.js:1596
globalZoneAwareCallback @ zone-evergreen.js:1622
auth.service.ts:54 user founded!
解决方案
此函数checkUserExistence(user)
正在执行一些异步任务,您正在检查从它返回的结果
所以,这个 if 条件if (this.checkUserExistence(user) === false)
没有被正确检查,转到 else 部分,它有一个 return 语句,但没有返回一个要在 signUp 组件中订阅的 observable
我建议你定义一个 BehaviorSubject 类型的新属性,它应该返回一个布尔值,并给它一个初始值 =false
isUserExist = new BehaviorSubject<Boolean>(false);
checkUserExistence(user : User) : any {
this.http.get<UserResponse>(baseURL + 'users/findUser')
.subscribe(res => {
if (res.success) {
console.log('user founded!');
// return true;
this.isUserExist.next(true);
}
},
err => {
console.log('A problem happened: ', err);
this.destroyUserCredentials();
// return false;
this.isUserExist.next(false);
});
}
signUp(user: any): Observable<any> {
return this.http.post<RegResponse>(baseURL + 'users/signup',
{'username': user.username, 'password': user.password, 'firstname' : user.firstname, 'lastname': user.lastname})
.pipe( map(res => {
this.storeUser({username: user.username});
return {'success': true, 'username': user.username };
}),
catchError(error => this.processHTTPMsgService.handleError(error)));
}
并在从服务调用注册方法之前检查用户是否存在于组件中,因此只有在用户不存在时才会调用它,这样,您将摆脱从服务返回不可观察的响应,因此只有在用户不存在时才进行注册(并且此检查将在组件中完成)
onSubmit() {
console.log('User: ', this.user);
// subscribe to the behavior subject we defined and emitted in the service, If it's false, then do the signup
this.authService.isUserExist.subscribe((userExists: Boolean) => {
// call the signup method only if the userExists is not true
if (!userExists) {
this.authService.signUp(this.user)
.subscribe(res => {
if (res.success) {
this.dialogRef.close(res.success);
} else {
console.log(res);
}
}, error => {
console.log(error);
this.errMess = error;
});
}
});
}
推荐阅读
- next.js - 为静态站点部署大型工件
- python - 通过 PIL/Python 将元素添加到 OLED 显示器而不擦除其余部分
- ruby-on-rails - Rails:thread_mattr_accessor 在开发中随机变为“nil”
- swift - mlmodel NNClassifier 的输出形状是 Multiarray,VNClassificationObservation 不起作用?
- kotlin - 我可以将视图模型工厂与 hilt 依赖注入一起使用吗?
- javascript - 如何返回在 Javascript/Node 中填充了 ASYNC 函数的数组的值?
- c - 是否有可能使用 HAL_UART_RxCpltCallback 创建与 uart 的双向通信?
- go - 什么决定了 goroutine 的执行顺序?
- python - 给定字符串的 ngrams 重构输入字符串
- java - 在 Android 中隐藏 AWS Cogniton 用户池客户端 ID/秘密