Post Author不显示(AngularJS, $http, MongoDB) - Thinkster MEAN S

Post Author not displaying (AngularJS, $http, MongoDB) - Thinkster MEAN Stack Tutorial

本文关键字:MongoDB Thinkster MEAN http Author 显示 AngularJS Post      更新时间:2023-09-26

我是MEAN Stack Web开发的初学者,并且一直在学习MEAN Stack教程。我已经完成了对用户进行身份验证的最后一节,但是,在索引中的MainCtrl中,一切似乎都工作得很好(没有控制台错误,并且功能齐全)。Ejs文件,post。作者表达式不评估,即使当我登录并提交一个帖子(相反,ng-show="post.author"阻止它显示)。

angularApp.js -我已经编辑了这些帖子。MainCtrl中的create函数在这里包含一个作者。auth.currentUser()确实在该控制器中评估正确(在MainCtrl$scope.incrementUpvotes函数中用console.log(auth.currentUser());进行测试)

var app = angular.module('flapperNews', ['ui.router']);
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('home', {
      url: '/home',
      templateUrl: '/home.html',
      controller: 'MainCtrl',
      resolve: {
        postPromise: ['posts', function(posts) {
          return posts.getAll();
        }]
      }
    })
    .state('posts', {
        url: '/posts/{id}',
      templateUrl: '/posts.html',
      controller: 'PostsCtrl',
      resolve: {
        post: ['$stateParams', 'posts', function($stateParams, posts) {
          return posts.get($stateParams.id);
        }]
      }
    })
    .state('login', {
      url: '/login',
      templateUrl: '/login.html',
      controller: 'AuthCtrl',
      onEnter: ['$state', 'auth', function($state, auth){
        if(auth.isLoggedIn()){
          $state.go('home');
        }
      }]
    })
    .state('register', {
      url: '/register',
      templateUrl: '/register.html',
      controller: 'AuthCtrl',
      onEnter: ['$state', 'auth', function($state, auth){
        if(auth.isLoggedIn()){
          $state.go('home');
        }
      }]
    });
  $urlRouterProvider.otherwise('home');
}])
.factory('auth', ['$http', '$window', function($http, $window){
   var auth = {};
   auth.saveToken = function(token) {
    $window.localStorage['flapper-news-token'] = token;
   };
   auth.getToken = function (){
    return $window.localStorage['flapper-news-token'];
  };
  auth.isLoggedIn = function(){
    var token = auth.getToken();
    if(token){
      var payload = JSON.parse($window.atob(token.split('.')[1]));
      return payload.exp > Date.now() / 1000;
    } else {
      return false;
    }
  };
  auth.currentUser = function(){
    if(auth.isLoggedIn()){
      var token = auth.getToken();
      var payload = JSON.parse($window.atob(token.split('.')[1]));
      return payload.username;
    }
  };
  auth.register = function(user) {
    return $http.post('/register', user).success(function(data) {
      auth.saveToken(data.token);
    });
  };
  auth.logIn = function(user){
    return $http.post('/login', user).success(function(data){
      auth.saveToken(data.token);
    });
  };
  auth.logOut = function(){
    $window.localStorage.removeItem('flapper-news-token');
  };
  return auth;
}])
.controller('AuthCtrl', [
'$scope',
'$state',
'auth',
  function($scope, $state, auth){
      $scope.user = {};
      $scope.register = function(){
        auth.register($scope.user).error(function(error){
          $scope.error = error;
        }).then(function(){
          $state.go('home');
        });
      };
      $scope.logIn = function(){
        auth.logIn($scope.user).error(function(error){
          $scope.error = error;
        }).then(function(){
          $state.go('home');
          console.log(auth.currentUser());
        });
      };
}])
app.factory('posts', ['$http', 'auth', function($http, auth){
  var o = {
    posts: []
  };
   o.getAll = function() {
    return $http.get('/posts').success(function(data){
      angular.copy(data, o.posts);
    });
  };
  o.get = function(id) {
    return $http.get('/posts/' + id).then(function(res){
      return res.data;
    });
  };
  o.create = function(post) {
  return $http.post('/posts', post, {
    headers: {Authorization: 'Bearer '+auth.getToken()}
  }).success(function(data){
    o.posts.push(data);
    });
  };
  o.upvote = function(post) {
  return $http.put('/posts/' + post._id + '/upvote', null, {
    headers: {Authorization: 'Bearer '+auth.getToken()}
    }).success(function(data){
      post.upvotes += 1;
    });
  };
  o.addComment = function(id, comment) {
    return $http.post('/posts/' + id + '/comments', comment, {
      headers: {Authorization: 'Bearer '+auth.getToken()}
    });
  };
  o.upvoteComment = function(post, comment) {
    return $http.put('/posts/' + post._id + '/comments/'+ comment._id + '/upvote', null, {
    headers: {Authorization: 'Bearer '+auth.getToken()}
    }).success(function(data){
        comment.upvotes += 1;
      });
  };
  return o;
}]);
app.controller('MainCtrl', [
'$scope', 'posts', 'auth',
function($scope, posts, auth){
  $scope.test = 'Hello world!';
  $scope.posts = posts.posts;
  $scope.isLoggedIn = auth.isLoggedIn;
    $scope.addPost = function() {
    if(!$scope.title || $scope.title === '') { return; }
        posts.create({
      title: $scope.title,
      author: auth.currentUser(),
      link: $scope.link,
      });
    $scope.title = '';
    $scope.link = '';
  };
    $scope.incrementUpvotes = function(post) {
    posts.upvote(post);
    console.log(auth.currentUser())
  };
}])
app.controller('PostsCtrl', [
'$scope',
'$stateParams',
'posts',
'post',
'auth',
function($scope, $stateParams, posts, post, auth){
  $scope.post=post;
  $scope.isLoggedIn = auth.isLoggedIn;
  $scope.addComment = function(){
    if($scope.body === '') { return; }
    posts.addComment(post._id, {
      body: $scope.body,
      author: 'user',
    }).success(function(comment) {
      $scope.post.comments.push(comment);
    });
    }
    $scope.addUpvote = function(comment){
      posts.upvoteComment(post, comment);
    };
    $scope.body = '';
  }
])
.controller('NavCtrl', [
'$scope',
'auth',
function($scope, auth){
  $scope.isLoggedIn = auth.isLoggedIn;
  $scope.currentUser = auth.currentUser;
  $scope.logOut = auth.logOut;
}]);

Posts.js -我在这里编辑了猫鼬模型,包括一个作者。

var mongoose = require('mongoose');
var PostSchema = new mongoose.Schema({
    title: String,
    link: String,
    author: String,
    upvotes: {type: Number, default: 0},
    comments: [{type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});
PostSchema.methods.upvote = function(cb) {
    this.upvotes += 1;
    this.save(cb);
};
mongoose.model('Post', PostSchema);

index.js

var express = require('express');
var jwt = require('express-jwt');
var router = express.Router();
var auth = jwt({secret: 'SECRET', userProperty: 'payload'});
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});
var mongoose = require('mongoose');
var passport = require('passport');
var Post = mongoose.model('Post');
var Comment = mongoose.model('Comment');
var User = mongoose.model('User');
router.post('/register', function(req, res, next){
  if(!req.body.username || !req.body.password){
    return res.status(400).json({message: 'Please fill out all fields'});
  }
  var user = new User();
  user.username = req.body.username;
  user.setPassword(req.body.password)
  user.save(function (err){
    if(err){ return next(err); }
    return res.json({token: user.generateJWT()})
  });
});
router.post('/login', function(req, res, next){
  if(!req.body.username || !req.body.password){
    return res.status(400).json({message: 'Please fill out all fields'});
  }
  passport.authenticate('local', function(err, user, info){
    if(err){ return next(err); }
    if(user){
      return res.json({token: user.generateJWT()});
    } else {
      return res.status(401).json(info);
    }
  })(req, res, next);
});
router.get('/posts', function(req, res, next) {
    Post.find(function(err, posts) {
        if (err) { return next(err);}
        res.json(posts);
    });

});
router.post('/posts', auth, function(req, res, next) {
  var post = new Post(req.body);
  post.author = req.payload.username;
  post.save(function(err, post){
    if(err){ return next(err); }
    res.json(post);
  });
});
router.param('post', function(req,res,next,id) {
  var query = Post.findById(id);
  query.exec(function (err, post) {
    if (err) { return next(err);}
    if (!post) { return next(new Error('can''t find post')); }
    req.post = post;
    return next();
  });
});
router.param('comment', function(req,res,next,id) {
  var query = Comment.findById(id);
  query.exec(function (err, comment) {
    if (err) { return next(err);}
    if (!comment) { return next(new Error('can''t find comment')); }
    req.comment = comment;
    return next();
  });
});
router.get('/posts/:post', function(req,res) {
  req.post.populate('comments', function(err,post) {
    if (err) { return next(err); }
    res.json(post);
  });
});
router.put('/posts/:post/upvote', auth, function(req, res, next) {
  req.post.upvote(function(err, post){
    if (err) { return next(err); }
    res.json(post);
  });
});
router.post('/posts/:post/comments', auth, function(req, res, next) {
  var comment = new Comment(req.body);
  comment.post = req.post;
  comment.author = req.payload.username;
  comment.save(function(err, comment){
    if(err){ return next(err); }
    req.post.comments.push(comment);
    req.post.save(function(err, post) {
      if(err){ return next(err); }
      res.json(comment);
    });
  });
});
router.put('/posts/:post/comments/:comment/upvote', auth, function(req, res, next) {
  req.comment.upvote(function(err, comment){
    if (err) { return next(err); }
    res.json(comment);
  });
});
module.exports = router;

index.ejs

<html>
<head>
  <title>Flapper News</title>
  <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
  <script src="/javascripts/angularApp.js"></script>
  <style> .glyphicon-thumbs-up { cursor:pointer } </style>
</head>
<body ng-app="flapperNews">
  <nav class="navbar navbar-default pull-right" ng-controller="NavCtrl">
    <ul class="nav navbar-nav">
      <li ng-show="isLoggedIn()"><a>{{ currentUser() }}</a></li>
      <li ng-show="isLoggedIn()"><a href="" ng-click="logOut()">Log Out</a></li>
      <li ng-hide="isLoggedIn()"><a href="/#/login">Log In</a></li>
      <li ng-hide="isLoggedIn()"><a href="/#/register">Register</a></li>
    </ul>
  </nav>
  <div class="row">
    <div class="col-md-6 col-md-offset-3">
        <ui-view></ui-view>
    </div>
  </div>      
      <script type="text/ng-template" id="/home.html">
      <div class="page-header">
        <h1>Flapper News</h1>
      </div>
      <div ng-repeat="post in posts | orderBy:'-upvotes'">
        <span class="glyphicon glyphicon-thumbs-up"
          ng-click="incrementUpvotes(post)"></span>
        {{post.upvotes}}
        <span style="font-size:20px; margin-left:10px;">
          <a ng-show="post.link" href="{{post.link}}">
            {{post.title}}
          </a>
          <span ng-hide="post.link">
            {{post.title}}
          </span>
          <span ng-show="post.author">
            posted by <a>{{post.author}}</a> |
          </span>
        </span>
        <span>
            <a href="#/posts/{{post._id}}">Comments</a>
        </span>
      </div>
      <div ng-hide="isLoggedIn()">
        <h3>You need to <a href="/#/login">Log In</a> or <a href="/#/register">Register</a> before you can add a post.</h3>
      </div>
      <form ng-submit="addPost()" ng-show="isLoggedIn()" style="margin-top:30px;">
        <h3>Add a new post</h3>
        <div class="form-group">
          <input type="text"
            class="form-control"
            placeholder="Title"
            ng-model="title"></input>
        </div>
        <div class="form-group">
          <input type="text"
          class="form-control"
          placeholder="Link"
          ng-model="link"></input>
        </div>
        <button type="submit" class="btn btn-primary">Post</button>
      </form>
    </script>
    <script type="text/ng-template" id="/posts.html">
        <div class="page-header">
            <h3>
            <a ng-show="post.link" href="{{post.link}}">
                {{post.title}}
            </a>
            <span ng-hide="post.link">
                {{post.title}}
            </span>
            </h3>
        </div>
        <div ng-repeat="comment in post.comments | orderBy:'-upvotes'">
            <span class="glyphicon glyphicon-thumbs-up" ng-click="addUpvote(comment)"></span>
                {{comment.upvotes}} - by {{comment.author}}
            <span style="font-size:20px; margin-left:10px;">
                {{comment.body}}
            </span>
        </div>
      <div ng-hide="isLoggedIn()">
        <h3>You need to <a href="/#/login">Log In</a> or <a href="/#/register">Register</a> before you can comment.</h3>
      </div>
        <form ng-submit="addComment()" ng-show="isLoggedIn()" style="margin-top:30px;">
            <h3>Add a new comment</h3>
            <div class="form-group">
            <input type="text" class="form-control" placeholder="Comment" ng-model="body"></input>
            </div>
            <button type="submit" class="btn btn-primary">Post</button>
        </form>
    </script>
  <script type="text/ng-template" id="/register.html">
    <div class="page-header">
      <h1>Flapper News</h1>
    </div>
    <div ng-show="error" class="alert alert-danger row">
      <span>{{ error.message }}</span>
    </div>
    <form ng-submit="register()"
      style="margin-top:30px;">
      <h3>Register</h3>
      <div class="form-group">
        <input type="text"
        class="form-control"
        placeholder="Username"
        ng-model="user.username"></input>
      </div>
      <div class="form-group">
        <input type="password"
        class="form-control"
        placeholder="Password"
        ng-model="user.password"></input>
      </div>
      <button type="submit" class="btn btn-primary">Register</button>
    </form>
  </script>
  <script type="text/ng-template" id="/login.html">
    <div class="page-header">
      <h1>Flapper News</h1>
    </div>
    <div ng-show="error" class="alert alert-danger row">
      <span>{{ error.message }}</span>
    </div>
    <form ng-submit="logIn()"
      style="margin-top:30px;">
      <h3>Log In</h3>
      <div class="form-group">
        <input type="text"
        class="form-control"
        placeholder="Username"
        ng-model="user.username"></input>
      </div>
      <div class="form-group">
        <input type="password"
        class="form-control"
        placeholder="Password"
        ng-model="user.password"></input>
      </div>
      <button type="submit" class="btn btn-primary">Log In</button>
    </form>
    </script>
</body>
</html>

教程指示不包含post。作者在帖子。MainCtrl中的create函数,也不更新猫鼬模型。在此设置下,{{post.author}}也不显示。

任何帮助都非常感谢。

编辑:这也不是浏览器缓存错误

作者是唯一不显示的字段,然后我认为问题是你没有在mongoDB的Post模型中正确存储作者字段,你可以存储一个未定义的值。

这可能是因为req.payload.username可能被评估为未定义,因为您的jwt没有被正确解码而不是

router.post('/posts', auth, function(req, res, next) {
  var post = new Post(req.body);
  post.author = req.payload.username;
  post.save(function(err, post){

router.post('/posts', auth, function(req, res, next) {
      var post = new Post(req.body);
      post.save(function(err, post){

您的req.body已经有username属性附加到它从o.create在你的posts工厂。重新分配是没有意义的。我也完成了教程,并有作者属性正常工作,如果你觉得倾向,你可以看看我的github在flapper文件夹。