Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获取错误bundle.js:39454未捕获类型错误:无法读取属性';电子邮件';使用MERN堆栈定义未定义的_Javascript_Node.js_Mongodb_Reactjs - Fatal编程技术网

Javascript 获取错误bundle.js:39454未捕获类型错误:无法读取属性';电子邮件';使用MERN堆栈定义未定义的

Javascript 获取错误bundle.js:39454未捕获类型错误:无法读取属性';电子邮件';使用MERN堆栈定义未定义的,javascript,node.js,mongodb,reactjs,Javascript,Node.js,Mongodb,Reactjs,我正在使用MERN堆栈,似乎不明白为什么会发生这种情况。我有一个显示得很好的帖子列表。当我点击帖子时,我在控制台中得到无法读取未定义的属性“email”。但是如果我点击“刷新”,一切正常,那篇文章会显示所有的工作问题 我能够确定我的renderComments()函数的错误。这就是一切都显示为未定义的地方 编辑:我想我知道发生了什么,但我不知道为什么会发生。在渲染之前,在array.map函数中创建的注释仅为注释ID。仅当组件渲染注释时,注释才为实际完整对象及其所有属性。我将发布后端,以显示我是

我正在使用MERN堆栈,似乎不明白为什么会发生这种情况。我有一个显示得很好的帖子列表。当我点击帖子时,我在控制台中得到
无法读取未定义的属性“email”
。但是如果我点击“刷新”,一切正常,那篇文章会显示所有的工作问题

我能够确定我的
renderComments()
函数的错误。这就是一切都显示为未定义的地方

编辑:我想我知道发生了什么,但我不知道为什么会发生。在渲染之前,在array.map函数中创建的注释仅为注释ID。仅当组件渲染注释时,注释才为实际完整对象及其所有属性。我将发布后端,以显示我是如何获得帖子上的评论以帮助解决问题的

它被要求在array.map函数之前显示post的console.log。由于这确实指出了我在编辑中所说的话,我将继续并在下面展示以提供帮助

发布管理员评论:

exports.getOnePost = function(req, res, next) {
  Posts.findById(req.params.id).populate("comments").exec(function(err, foundPost) {
    if(err) {
      return next(err);
    } else {
      res.json(foundPost);
    }
  });
}
var mongoose = require("mongoose");
const Schema = mongoose.Schema;

var postsSchema = new Schema({
    title: String,
    createdAt: {type: Date, default: Date.now},
    content: String,
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "user"
        },
        email: String
    },
    comments: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: "comments"
        }
    ]
});

var Posts = mongoose.model("posts", postsSchema);

module.exports = Posts;
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { bindActionCreators } from 'redux';
import * as actions from '../../actions/posts_actions';
import * as actionsIndex from '../../actions/index';
import * as actionsComments from '../../actions/comments_actions';

class ShowPosts extends Component {
  constructor(props) {
    super(props);

    this.onDeleteClick = this.onDeleteClick.bind(this);
    this.deleteComment = this.deleteComment.bind(this);
  }

  componentDidMount() {
    const {id} = this.props.match.params;
    this.props.getOnePost(id);

    if(this.props.auth) {
      this.props.getUser();
    }
  }

  renderButtons() {
    const { post } = this.props;

    if(!this.props.user) {
      return ( <div></div> );
    }

    if(this.props.auth) {
      if(this.props.user._id === post.author.id) {
        return (
          <div>
            <button
              onClick={this.onDeleteClick}
              className="btn btn-danger"
              >
              Delete
            </button>
            <Link
              to={`/posts/${post._id}/edit`}
              className="btn btn-success"
              >
              Edit
            </Link>
          </div>
        )
      }
    } else {
      return (
        <div></div>
      )
    }
  }

  renderCommentsButtons(comment) {
    const { post, user, auth } = this.props;

    if(!user) {
      return (<div></div>);
    }

    if(auth) {
      if(user._id === comment.author.id) {
        return (
          <div>
            <button
              onClick={() => this.deleteComment(comment)}
              className="btn btn-xs btn-danger">
              Delete
            </button>
            <Link
              to={`/posts/${post._id}/comments/${comment._id}/edit`}
              className="btn btn-xs btn-warning">
              Edit
            </Link>
          </div>
        )
      }
    }
  }

  renderComments() {
    const { post } = this.props;

    return post.comments.map((comment) => {
      return (
        <li className="list-group-item" key={comment._id}>
          <div>
            {comment.text} : {comment.author.email}
          </div>
          {this.renderCommentsButtons(comment)}
        </li>
      );
    });
  }

  deleteComment(comment) {
    const {id} = this.props.match.params;
    const {user, post, auth} = this.props;

    if(!user) {
      return (<div></div>);
    }

    if(auth) {
      if(user._id === comment.author.id){
        console.log(comment._id, '-', post._id);
        // this.props.deleteComments(id, comment._id, () => {
        //   this.props.history.push(`/posts/${post._id}`);
        // });
      }
    }
  }

  onDeleteClick() {
    const {id} = this.props.match.params;

    if(!this.props.user) {
      return (<div></div>);
    }

    if(this.props.auth) {
      if(this.props.user._id === this.props.post.author.id) {
        this.props.deletePost(id, () => {
          this.props.history.push("/posts");
        });
      }
    }
  }

  render() {
    const { post } = this.props;

    if (!post) {
      return <div> Loading...No Post</div>;
    }

    return (
      <div>
        <Link className="btn btn-primary" to="/posts">Back To Post</Link>
        <h3>{post.title}</h3>
        <p>{post.content}</p>
        <p>created by: {post.author.email}</p>
        <ul className="list-group">
          {this.renderComments()}
        </ul>
        {this.renderButtons()}
        <Link
          className="btn btn-warning"
          to={`/posts/${post._id}/comments/new`}>
            Comment
        </Link>
      </div>
    );
  }
}

function mapStateToProps({ posts, auth, user }, ownProps) {
  return {
    post: posts[ownProps.match.params.id],
    user: user,
    auth: auth.authenticated
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({...actions, ...actionsIndex, ...actionsComments}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(ShowPosts);
exports.getAllPosts = function(req, res, next) {
  Posts.find({}, function(err, posts) {
    if(err) {
      return next(err);
    } else {
      res.json(posts);
    }
  });
}
exports.getAllPosts = function(req, res, next) {
  Posts.find({}).populate("comments").exec(function(err, posts) {
    if(err) {
      return next(err);
    } else {
      res.json(posts);
    }
  });
}
var mongoose = require("mongoose");
const Schema = mongoose.Schema;

var postsSchema = new Schema({
    title: String,
    createdAt: {type: Date, default: Date.now},
    content: String,
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "user"
        },
        email: String
    },
    comments: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: "comments"
        }
    ]
});

var Posts = mongoose.model("posts", postsSchema);

module.exports = Posts;
发布和评论模式:

exports.getOnePost = function(req, res, next) {
  Posts.findById(req.params.id).populate("comments").exec(function(err, foundPost) {
    if(err) {
      return next(err);
    } else {
      res.json(foundPost);
    }
  });
}
var mongoose = require("mongoose");
const Schema = mongoose.Schema;

var postsSchema = new Schema({
    title: String,
    createdAt: {type: Date, default: Date.now},
    content: String,
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "user"
        },
        email: String
    },
    comments: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: "comments"
        }
    ]
});

var Posts = mongoose.model("posts", postsSchema);

module.exports = Posts;
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { bindActionCreators } from 'redux';
import * as actions from '../../actions/posts_actions';
import * as actionsIndex from '../../actions/index';
import * as actionsComments from '../../actions/comments_actions';

class ShowPosts extends Component {
  constructor(props) {
    super(props);

    this.onDeleteClick = this.onDeleteClick.bind(this);
    this.deleteComment = this.deleteComment.bind(this);
  }

  componentDidMount() {
    const {id} = this.props.match.params;
    this.props.getOnePost(id);

    if(this.props.auth) {
      this.props.getUser();
    }
  }

  renderButtons() {
    const { post } = this.props;

    if(!this.props.user) {
      return ( <div></div> );
    }

    if(this.props.auth) {
      if(this.props.user._id === post.author.id) {
        return (
          <div>
            <button
              onClick={this.onDeleteClick}
              className="btn btn-danger"
              >
              Delete
            </button>
            <Link
              to={`/posts/${post._id}/edit`}
              className="btn btn-success"
              >
              Edit
            </Link>
          </div>
        )
      }
    } else {
      return (
        <div></div>
      )
    }
  }

  renderCommentsButtons(comment) {
    const { post, user, auth } = this.props;

    if(!user) {
      return (<div></div>);
    }

    if(auth) {
      if(user._id === comment.author.id) {
        return (
          <div>
            <button
              onClick={() => this.deleteComment(comment)}
              className="btn btn-xs btn-danger">
              Delete
            </button>
            <Link
              to={`/posts/${post._id}/comments/${comment._id}/edit`}
              className="btn btn-xs btn-warning">
              Edit
            </Link>
          </div>
        )
      }
    }
  }

  renderComments() {
    const { post } = this.props;

    return post.comments.map((comment) => {
      return (
        <li className="list-group-item" key={comment._id}>
          <div>
            {comment.text} : {comment.author.email}
          </div>
          {this.renderCommentsButtons(comment)}
        </li>
      );
    });
  }

  deleteComment(comment) {
    const {id} = this.props.match.params;
    const {user, post, auth} = this.props;

    if(!user) {
      return (<div></div>);
    }

    if(auth) {
      if(user._id === comment.author.id){
        console.log(comment._id, '-', post._id);
        // this.props.deleteComments(id, comment._id, () => {
        //   this.props.history.push(`/posts/${post._id}`);
        // });
      }
    }
  }

  onDeleteClick() {
    const {id} = this.props.match.params;

    if(!this.props.user) {
      return (<div></div>);
    }

    if(this.props.auth) {
      if(this.props.user._id === this.props.post.author.id) {
        this.props.deletePost(id, () => {
          this.props.history.push("/posts");
        });
      }
    }
  }

  render() {
    const { post } = this.props;

    if (!post) {
      return <div> Loading...No Post</div>;
    }

    return (
      <div>
        <Link className="btn btn-primary" to="/posts">Back To Post</Link>
        <h3>{post.title}</h3>
        <p>{post.content}</p>
        <p>created by: {post.author.email}</p>
        <ul className="list-group">
          {this.renderComments()}
        </ul>
        {this.renderButtons()}
        <Link
          className="btn btn-warning"
          to={`/posts/${post._id}/comments/new`}>
            Comment
        </Link>
      </div>
    );
  }
}

function mapStateToProps({ posts, auth, user }, ownProps) {
  return {
    post: posts[ownProps.match.params.id],
    user: user,
    auth: auth.authenticated
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({...actions, ...actionsIndex, ...actionsComments}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(ShowPosts);
exports.getAllPosts = function(req, res, next) {
  Posts.find({}, function(err, posts) {
    if(err) {
      return next(err);
    } else {
      res.json(posts);
    }
  });
}
exports.getAllPosts = function(req, res, next) {
  Posts.find({}).populate("comments").exec(function(err, posts) {
    if(err) {
      return next(err);
    } else {
      res.json(posts);
    }
  });
}
var mongoose = require("mongoose");
const Schema = mongoose.Schema;

var postsSchema = new Schema({
    title: String,
    createdAt: {type: Date, default: Date.now},
    content: String,
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "user"
        },
        email: String
    },
    comments: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: "comments"
        }
    ]
});

var Posts = mongoose.model("posts", postsSchema);

module.exports = Posts;

展示后页面:

exports.getOnePost = function(req, res, next) {
  Posts.findById(req.params.id).populate("comments").exec(function(err, foundPost) {
    if(err) {
      return next(err);
    } else {
      res.json(foundPost);
    }
  });
}
var mongoose = require("mongoose");
const Schema = mongoose.Schema;

var postsSchema = new Schema({
    title: String,
    createdAt: {type: Date, default: Date.now},
    content: String,
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "user"
        },
        email: String
    },
    comments: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: "comments"
        }
    ]
});

var Posts = mongoose.model("posts", postsSchema);

module.exports = Posts;
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { bindActionCreators } from 'redux';
import * as actions from '../../actions/posts_actions';
import * as actionsIndex from '../../actions/index';
import * as actionsComments from '../../actions/comments_actions';

class ShowPosts extends Component {
  constructor(props) {
    super(props);

    this.onDeleteClick = this.onDeleteClick.bind(this);
    this.deleteComment = this.deleteComment.bind(this);
  }

  componentDidMount() {
    const {id} = this.props.match.params;
    this.props.getOnePost(id);

    if(this.props.auth) {
      this.props.getUser();
    }
  }

  renderButtons() {
    const { post } = this.props;

    if(!this.props.user) {
      return ( <div></div> );
    }

    if(this.props.auth) {
      if(this.props.user._id === post.author.id) {
        return (
          <div>
            <button
              onClick={this.onDeleteClick}
              className="btn btn-danger"
              >
              Delete
            </button>
            <Link
              to={`/posts/${post._id}/edit`}
              className="btn btn-success"
              >
              Edit
            </Link>
          </div>
        )
      }
    } else {
      return (
        <div></div>
      )
    }
  }

  renderCommentsButtons(comment) {
    const { post, user, auth } = this.props;

    if(!user) {
      return (<div></div>);
    }

    if(auth) {
      if(user._id === comment.author.id) {
        return (
          <div>
            <button
              onClick={() => this.deleteComment(comment)}
              className="btn btn-xs btn-danger">
              Delete
            </button>
            <Link
              to={`/posts/${post._id}/comments/${comment._id}/edit`}
              className="btn btn-xs btn-warning">
              Edit
            </Link>
          </div>
        )
      }
    }
  }

  renderComments() {
    const { post } = this.props;

    return post.comments.map((comment) => {
      return (
        <li className="list-group-item" key={comment._id}>
          <div>
            {comment.text} : {comment.author.email}
          </div>
          {this.renderCommentsButtons(comment)}
        </li>
      );
    });
  }

  deleteComment(comment) {
    const {id} = this.props.match.params;
    const {user, post, auth} = this.props;

    if(!user) {
      return (<div></div>);
    }

    if(auth) {
      if(user._id === comment.author.id){
        console.log(comment._id, '-', post._id);
        // this.props.deleteComments(id, comment._id, () => {
        //   this.props.history.push(`/posts/${post._id}`);
        // });
      }
    }
  }

  onDeleteClick() {
    const {id} = this.props.match.params;

    if(!this.props.user) {
      return (<div></div>);
    }

    if(this.props.auth) {
      if(this.props.user._id === this.props.post.author.id) {
        this.props.deletePost(id, () => {
          this.props.history.push("/posts");
        });
      }
    }
  }

  render() {
    const { post } = this.props;

    if (!post) {
      return <div> Loading...No Post</div>;
    }

    return (
      <div>
        <Link className="btn btn-primary" to="/posts">Back To Post</Link>
        <h3>{post.title}</h3>
        <p>{post.content}</p>
        <p>created by: {post.author.email}</p>
        <ul className="list-group">
          {this.renderComments()}
        </ul>
        {this.renderButtons()}
        <Link
          className="btn btn-warning"
          to={`/posts/${post._id}/comments/new`}>
            Comment
        </Link>
      </div>
    );
  }
}

function mapStateToProps({ posts, auth, user }, ownProps) {
  return {
    post: posts[ownProps.match.params.id],
    user: user,
    auth: auth.authenticated
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({...actions, ...actionsIndex, ...actionsComments}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(ShowPosts);
exports.getAllPosts = function(req, res, next) {
  Posts.find({}, function(err, posts) {
    if(err) {
      return next(err);
    } else {
      res.json(posts);
    }
  });
}
exports.getAllPosts = function(req, res, next) {
  Posts.find({}).populate("comments").exec(function(err, posts) {
    if(err) {
      return next(err);
    } else {
      res.json(posts);
    }
  });
}
var mongoose = require("mongoose");
const Schema = mongoose.Schema;

var postsSchema = new Schema({
    title: String,
    createdAt: {type: Date, default: Date.now},
    content: String,
    author: {
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "user"
        },
        email: String
    },
    comments: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: "comments"
        }
    ]
});

var Posts = mongoose.model("posts", postsSchema);

module.exports = Posts;
import React,{Component}来自'React';
从'react redux'导入{connect};
从'react router dom'导入{Link};
从“redux”导入{bindActionCreators};
从“../../actions/posts_actions”导入*作为操作;
从“../../actions/index”导入*作为actionsIndex;
从“../../actions/comments_actions”导入*作为actions注释;
类ShowPosts扩展组件{
建造师(道具){
超级(道具);
this.onDeleteClick=this.onDeleteClick.bind(this);
this.deleteComent=this.deleteComent.bind(this);
}
componentDidMount(){
const{id}=this.props.match.params;
this.props.getOnePost(id);
if(this.props.auth){
this.props.getUser();
}
}
renderButtons(){
const{post}=this.props;
如果(!this.props.user){
返回();
}
if(this.props.auth){
if(this.props.user.\u id==post.author.id){
返回(
删除
编辑
)
}
}否则{
返回(
)
}
}
renderCommentsButtons(注释){
const{post,user,auth}=this.props;
如果(!用户){
返回();
}
if(auth){
if(user.\u id==comment.author.id){
返回(
this.deleteComment(comment)}
className=“btn btn xs btn危险”>
删除
编辑
)
}
}
}
renderComments(){
const{post}=this.props;
返回post.comments.map((comment)=>{
返回(
  • {comment.text}:{comment.author.email} {this.renderCommentsButtons(comment)}
  • ); }); } 删除评论(评论){ const{id}=this.props.match.params; const{user,post,auth}=this.props; 如果(!用户){ 返回(); } if(auth){ if(user.\u id==comment.author.id){ 日志(comment.\u id,'-',post.\u id); //this.props.deleteComments(id,comment.\u id,()=>{ //this.props.history.push(`/posts/${post.\u id}`); // }); } } } onDeleteClick(){ const{id}=this.props.match.params; 如果(!this.props.user){ 返回(); } if(this.props.auth){ if(this.props.user.\u id==this.props.post.author.id){ this.props.deletePost(id,()=>{ this.props.history.push(“/posts”); }); } } } render(){ const{post}=this.props; 如果(!post){ 返回加载…没有职位; } 返回( 回到岗位 {post.title} {post.content}

    创建人:{post.author.email}

      {this.renderComments()}
    {this.renderButtons()} 评论 ); } } 函数mapStateToProps({posts,auth,user},ownProps){ 返回{ post:posts[ownProps.match.params.id], 用户:用户,, auth:auth.authenticated }; } 功能图DispatchToprops(调度){ 返回bindActionCreators({…操作,…操作索引,…操作注释},调度); } 导出默认连接(mapStateToProps、mapDispatchToProps)(ShowPosts);
    发布

    import React , { Component } from 'react';
    import * as actions from '../../actions/posts_actions';
    import {connect} from 'react-redux';
    import {Link} from 'react-router-dom';
    import _ from 'lodash';
    
    
    class Posts extends Component {
      componentDidMount() {
        this.props.getAllPosts();
      }
    
      renderPosts() {
        return _.map(this.props.posts, post => {
          return (
            <Link to={`/posts/${post._id}`} key={post._id}>
              <li className="list-group-item">
                {post.title}
              </li>
            </Link>
          )
        });
      }
    
      render() {
        return (
          <div>
            <div className="text-xs-right">
              <Link className="btn btn-primary" to="/posts/new">
                Add a Post
              </Link>
            </div>
            <h3>Posts</h3>
            <ul className="list-group">
              {this.renderPosts()}
            </ul>
          </div>
        );
      }
    }
    
    
    function mapStateToProps(state) {
      return {
        posts: state.posts
      };
    }
    
    export default connect(mapStateToProps, actions)(Posts);
    
    import React,{Component}来自'React';
    从“../../actions/posts_actions”导入*作为操作;
    从'react redux'导入{connect};
    从'react router dom'导入{Link};
    从“lodash”进口;
    类Posts扩展组件{
    componentDidMount(){
    this.props.getAllPosts();
    }
    renderPosts(){
    return>map(this.props.posts,post=>{
    返回(
    
  • {post.title}
  • ) }); } render(){ 返回( 添加帖子 帖子
      {this.renderPosts()}
    ); } } 函数MapStateTops(状态){ 返回{ 职位:state.posts }; } 导出默认连接(MapStateTrops、actions)(POST);
    这是一个后端问题。如编辑中所述,第一次呈现的帖子只有注释ID,而不是完整的注释对象。我相信最初的帖子来自于
    posts[ownProps.match.params.id]
    ,而我们所做的只是从客户端的帖子中获取单一的帖子

    如果您查看后端,我会将注释存储为objectid,然后再填充t