首页 > 解决方案 > 在 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!

标签: node.jsangularangular2-observablesexpress-router

解决方案


此函数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;
      });
    }
  });
}

推荐阅读