当前位置: 首页 > 面试题库 >

getCurrentUser()。role在DaftMonk / generator-angular-fullstack中未定义

公羊浩阔
2023-03-14
问题内容

我们将DaftMonk / AngularJS Full-
Stack生成器用于projet。生成的代码包含用于管理用户(注册,登录,角色等)的逻辑,这很棒。但是,使用代码时会出现问题,并且当前用户的角色有时是不确定的。

我们想要实现一个简单的功能时遇到了这个问题:登录/注册后,应该将用户重定向到一个取决于其角色的URL。例如,'teacher'应将用户重定向到/teacherHome,将'student'用户重定向到/studentHome。由于Auth.getCurrentUser()。role未定义,因此逻辑不起作用。

如何重现问题

要重现此问题,请编辑client/app/account/login/login.controller.js文件并添加语句以记录Auth.getCurrentUser()。role的值,如下所示:

...
  if(form.$valid) {
    Auth.login({
      email: $scope.user.email,
      password: $scope.user.password
    })
    .then( function() {
      // Logged in, redirect to home
      console.log("Current user role: " + Auth.getCurrentUser().role);
      $location.path('/');
    })
    .catch( function(err) {
      $scope.errors.other = err.message;
    });
  }
};
...

测试此代码时,您会发现在此阶段未定义用户角色。但是,稍后会为其分配一个值。这表明该问题可能与异步REST调用有关。


问题答案:

实际上,存在一些相关的问题和解决方法。

解决方案1:使用提供的Auth.isLoggedInAsync功能

Auth模块是生成的代码的一部分,提供了一种方法来检查登录过程是否已完成(在这种情况下,并调用回调函数)。因此,解决此问题的一种方法是在客户端代码中使用此功能,如下所示:

  if(form.$valid) {
    Auth.login({
      email: $scope.user.email,
      password: $scope.user.password
    })
    .then( function() {
      // Logged in, redirect to home
      console.log("Current user role: " + Auth.getCurrentUser().role);
      Auth.isLoggedInAsync(function(success) {
        console.log("Current user role: " + Auth.getCurrentUser().role);
      });
      $location.path('/');
    })
    .catch( function(err) {
      $scope.errors.other = err.message;
    });
  }
};

在这种情况下,您将在控制台中看到两个语句。第一个将显示Auth.getCurrentUser()。role仍未定义。第二个将显示它现在具有值。因此,如果您有要在登录时html" target="_blank">执行的逻辑,并且该逻辑取决于用户角色(或其他用户属性),请将此逻辑放入传递给的回调函数中Auth.isLoggedInAsync()

解决方案2:解决根本原因auth.service.js

User.get();会触发一个异步HTTP调用,并且currentUser`不会立即设置(这是一个非阻塞调用)。由于立即兑现了承诺,因此客户被引导相信登录过程已完成,并且所有用户数据均可用,而实际上仍在进行中。

在建议的修复程序中,通过传递给的回调函数解决了promise User.get()

  /**
   * Authenticate user and save token
   *
   * @param  {Object}   user     - login info
   * @param  {Function} callback - optional
   * @return {Promise}
   */
  login: function (user, callback) {
    var cb = callback || angular.noop;
    var deferred = $q.defer();

    $http.post('/auth/local', {
      email: user.email,
      password: user.password
    }).
    /* ORIGINAL CODE -- promise is resolved too early
    success(function (data) {
      $cookieStore.put('token', data.token);
      currentUser = User.get();
      deferred.resolve(data);
      return cb();
    }).
    */
    /* PROPOSED FIX -- promise is resolved once HTTP call has returned */
    success(function (data) {
      $cookieStore.put('token', data.token);
      currentUser = User.get(function() {
        deferred.resolve(data);
        return cb();
      });
    }).
    error(function (err) {
      this.logout();
      deferred.reject(err);
      return cb(err);
    }.bind(this));

    return deferred.promise;
  },

相关问题和修复

建议的代码解决了一个问题。现在可以在成功登录后将用户重定向到特定页面。但是,在注册过程之后也会出现类似的问题。在这种情况下,Auth.getCurrentUser().role一段时间也未定义(足够长的时间使重定向逻辑失败)。

在这种情况下,代码固定如下:

  /**
   * Create a new user
   *
   * @param  {Object}   user     - user info
   * @param  {Function} callback - optional
   * @return {Promise}
   */
  createUser: function (user, callback) {
    var cb = callback || angular.noop;

     /* ORIGINAL CODE ---------------------
     return User.save(user,
      function(data) {
        $cookieStore.put('token', data.token);
        currentUser = User.get();
        return cb(user);
      },
      function(err) {
        this.logout();
        return cb(err);
      }.bind(this)).$promise;
       --------------------- */

    /* PROPOSED FIX --------------------- */
    var deferred = $q.defer();
    User.save(user,
      function (data) {
        $cookieStore.put('token', data.token);
        currentUser = User.get(function () {
          console.log('User.save(), user role: ' + currentUser.role);
          deferred.resolve(data);
          return cb(currentUser);
        });
      },
      function (err) {
        this.logout();
        return cb(err);
        deferred.reject(err);
      });
    return deferred.promise;

  },


 类似资料:
  • The Angular Full-Stack Generator Yeoman generator for creating MEAN/SEAN stack applications, using ES2017, MongoDB/SQL, Express, Angular, and Node - lets you quickly set up a project following best pr

  • ng-fullstack is a yeoman generator that allows you to rapidly get started with prototyping web applications with the newest technologies available. It allows you to choose between a client app, a serv

  • generator-angular-pro Web/mobile Angular project generator for scalable, enterprise-grade applications. Includes modern (and stable) tools and workflow, best practices, base template and an exhaustive

  • generator-angular-webpack-es6 Yeoman generator for AngularJS + Webpack with ES6 and SASS. Latest Webpack with Tree Shaking feature enabled Babel 6 with ES2017 features included Perfectly compatible wi

  • 看了几个论坛,好像找不到这个问题。 我有一个身份验证服务,应该使用令牌进行响应。 这是我的身份验证服务呼叫。 在我的登录组件中,我有以下调用: 我在控制台收到以下错误- TypeError: 无法读取 HttpXsrfInterceptor.push 上未定义的属性 'toLowerCase'。/node_modules/@angular/common/fesm5/http.js.HttpXsrf

  • 升级到角4.0后,我得到RxJs变量的错误。一切都很好。但当我加载页面我得到这个错误 错误错误:未捕获(promise中):类型错误:无法读取未定义类型的属性“forkJoin”错误:无法读取未定义类型的属性“forkJoin” 我在init函数中使用forkJoin 我在顶部导入了可观察的,它看起来像这样 从'rxjs/Rx'导入{可观察、观察者、主体、行为主体}; 所做的改变会突然导致这些问题