title: POST http://localhost:8000/comment/saveComment 404 (Not Found)
body: <p>New to react here. I am using a mern stack with express mongoose and node js. I am trying to create a comment functionality for a youtube clone, and I have been following a youtube video but for some reason I can't get it to work. I do not know if the routes are the problem, if it's the post axios method or the models.
  Here is the post.js</p>
  <pre><code>import { Avatar, IconButton } from &quot;@material-ui/core&quot;;
  import FavoriteIcon from &quot;@material-ui/icons/Favorite&quot;;
  import SmsIcon from &quot;@material-ui/icons/Sms&quot;;
  import SpaIcon from &quot;@material-ui/icons/Spa&quot;;
  import React, { useRef, useState, useEffect } from &quot;react&quot;;
  import minime from &quot;../images/me.jpg&quot;;
  import vid from &quot;../videos/ed.MP4&quot;;
  import GpsFixedIcon from &quot;@material-ui/icons/GpsFixed&quot;;
  import FormatListBulletedIcon from &quot;@material-ui/icons/FormatListBulleted&quot;;
  import GamepadIcon from &quot;@material-ui/icons/Gamepad&quot;;
  import &quot;../styles/Post.css&quot;;
  import EmojiEmotionsIcon from &quot;@material-ui/icons/EmojiEmotions&quot;;
  import VideoModal from &quot;./VideoModal&quot;;
  import PostMotivationModal from &quot;../components/modals/PostMotivationModal&quot;;
  import PostHappinessModal from &quot;../components/modals/PostHappinessModal&quot;;
  import Comments from &quot;./post/Comments&quot;;
  import axios from &quot;../axios&quot;;
  
  const Post = ({
    avatar,
    name,
    caption,
    filePath,
    motivation,
    goals,
    happiness,
  }) =&gt; {
    const [isOpen, setIsOpen] = useState(false);
    const [motivationIsOpen, setMotivationIsOpen] = useState(false);
    const [happinessIsOpen, setHappinessIsOpen] = useState(false);
    const [playing, setPlaying] = useState(false);
    const vidRef = useRef(null);
    const [commentList, setCommentList] = useState([]);
  
    const handleVideoPress = () =&gt; {
      //If video is playing... stop it
      if (playing) {
        vidRef.current.pause();
        setPlaying(false);
      } else {
        vidRef.current.play();
        setPlaying(true);
      }
  
      //otherwise... play it
    };
    const [videos, setVideos] = useState([]);
    const [vid, setVid] = useState([]);
    useEffect(() =&gt; {
      async function fetchPosts() {
        const res = await axios.get(&quot;video/getVideos&quot;);
        setVideos(res.data.videos);
        let video = res.data.videos.find((video) =&gt; video._id);
        console.log(video);
        setVid(video);
  
        return res;
      }
      fetchPosts();
    }, []);
  
    // useEffect(() =&gt; {
    //   async function fetchPosts() {
    //     const res = await axios.get(&quot;video/getVideo&quot;);
    //     setVid(res.data.video);
    //     let video = res.data.videos.find((video) =&gt; video._id);
    //     console.log(video);
    //     setVid(video);
  
    //     return res;
    //   }
    //   fetchPosts();
    // }, []);
  
    const videoId = vid._id;
  
    const variable = {
      videoId: videoId,
    };
  
    // useEffect(() =&gt; {
    //   axios.post(&quot;/video/getVideo&quot;, variable).then((response) =&gt; {
    //     console.log(response.data);
    //     if (response.data.success) {
    //       setVid(response.data.video);
    //     } else {
    //       console.log(response.data);
    //       alert(&quot;Failed to get video Info&quot;);
    //     }
    //   });
    // }, []);
  
    const updateComment = (newComment) =&gt; {
      setCommentList(commentList.push(newComment));
    };
  
    return (
      &lt;div className=&quot;post&quot;&gt;
        &lt;div className=&quot;post-head&quot;&gt;
          &lt;div className=&quot;post-header&quot;&gt;
            &lt;Avatar src={avatar} /&gt;
            &lt;h3&gt;{name}&lt;/h3&gt;
          &lt;/div&gt;
          &lt;div className=&quot;caption&quot;&gt;
            &lt;p&gt;{caption}&lt;/p&gt;
          &lt;/div&gt;
        &lt;/div&gt;
  
        &lt;div className=&quot;video-container&quot;&gt;
          &lt;div className=&quot;flex-container&quot;&gt;
            &lt;div className=&quot;video-card&quot;&gt;
              &lt;video
                ratiowidth=&quot;calc(0.56 * (400px + (100vw - 768px) / 1152 * 100))&quot;
                ratioheight=&quot;calc(400px + (100vw - 768px) / 1152 * 100)&quot;
                musicinfomaxwidth=&quot;250.56&quot;
                style={{
                  width: &quot;calc(0.56 * (400px + ((100vw - 768px) / 1152) * 100))&quot;,
                }}
                loop
                onClick={handleVideoPress}
                ref={vidRef}
                src={`http://localhost:8000/${filePath}`}
              &gt;&lt;/video&gt;
              &lt;div className=&quot;post__personalItems&quot;&gt;
                &lt;div title=&quot;Goals&quot; className=&quot;personalIcon&quot;&gt;
                  &lt;GpsFixedIcon
                    onClick={() =&gt; setIsOpen(true)}
                    style={{ cursor: &quot;pointer&quot; }}
                  /&gt;
                &lt;/div&gt;
  
                &lt;div title=&quot;Motivation&quot; className=&quot;personalIcon&quot;&gt;
                  &lt;GamepadIcon
                    onClick={() =&gt; setMotivationIsOpen(true)}
                    style={{ cursor: &quot;pointer&quot; }}
                  /&gt;
                &lt;/div&gt;
                &lt;div title=&quot;Happiness&quot; className=&quot;personalIcon&quot;&gt;
                  &lt;EmojiEmotionsIcon
                    onClick={() =&gt; setHappinessIsOpen(true)}
                    style={{ cursor: &quot;pointer&quot; }}
                  /&gt;
                &lt;/div&gt;
              &lt;/div&gt;
              &lt;VideoModal
                open={isOpen}
                onClose={() =&gt; setIsOpen(false)}
                goals={goals}
              &gt;&lt;/VideoModal&gt;
  
              &lt;PostMotivationModal
                open={motivationIsOpen}
                onClose={() =&gt; setMotivationIsOpen(false)}
                motivation={motivation}
              &gt;&lt;/PostMotivationModal&gt;
  
              &lt;PostHappinessModal
                open={happinessIsOpen}
                onClose={() =&gt; setHappinessIsOpen(false)}
                happiness={happiness}
              &gt;&lt;/PostHappinessModal&gt;
            &lt;/div&gt;
  
            &lt;div className=&quot;post-icons&quot;&gt;
              &lt;div className=&quot;post-icon&quot; title=&quot;like&quot;&gt;
                &lt;IconButton&gt;
                  &lt;FavoriteIcon /&gt;
                &lt;/IconButton&gt;
                &lt;div className=&quot;icon-detail&quot;&gt;
                  &lt;p&gt;112&lt;/p&gt;
                &lt;/div&gt;
              &lt;/div&gt;
              &lt;div className=&quot;post-icon&quot; title=&quot;hug&quot;&gt;
                &lt;IconButton&gt;
                  &lt;SpaIcon /&gt;
                &lt;/IconButton&gt;
                &lt;div className=&quot;icon-detail&quot;&gt;
                  &lt;p&gt;300&lt;/p&gt;
                &lt;/div&gt;
              &lt;/div&gt;
              &lt;div className=&quot;post-icon&quot; title=&quot;comment&quot;&gt;
                &lt;IconButton&gt;
                  &lt;SmsIcon /&gt;
                &lt;/IconButton&gt;
                &lt;div className=&quot;icon-detail&quot;&gt;
                  &lt;p&gt;30&lt;/p&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
  
        &lt;Comments
          commentList={commentList}
          postId={videoId}
          refreshFunction={updateComment}
        /&gt;
      &lt;/div&gt;
    );
  };
  
  export default Post;
  </code></pre>
  <p>here is the comment.js</p>
  <pre><code>import React, { useState } from &quot;react&quot;;
  import { Input } from &quot;antd&quot;;
  import &quot;../../styles/Comments.css&quot;;
  import axios from &quot;../../axios&quot;;
  const { TextArea } = Input;
  
  const Comments = (props) =&gt; {
    const [user, setUser] = useState(JSON.parse(localStorage.getItem(&quot;profile&quot;)));
    const [submitOn, setSubmitOn] = useState(false);
    const [comment, setComment] = useState(&quot;&quot;);
    const btnSwap = () =&gt; {
      if (submitOn === false) {
        setSubmitOn(true);
      }
    };
    const handleChange = (e) =&gt; {
      setComment(e.currentTarget.value);
    };
    //   console.log(user?.result.googleId);
    //   console.log(props);
    const onSubmit = (e) =&gt; {
      e.preventDefault();
  
      const variables = {
        content: comment,
        name: user?.result.name,
        avatar: user?.result.imageUrl,
        postId: props.postId,
      };
  
      axios.post(&quot;/comment/saveComment&quot;, variables).then((res) =&gt; {
        if (res.data.success) {
          setComment(&quot;&quot;);
          props.refreshFunction(res.data.result);
        } else {
          alert(&quot;Failed to save comment&quot;);
        }
      });
    };
    return (
      &lt;div className=&quot;comments-section&quot;&gt;
        &lt;p className=&quot;replies-txt&quot;&gt;Replies&lt;/p&gt;
  
        &lt;hr /&gt;
        {/*Comment Lists */}
        {console.log(props.commentList)}
        {/* Root comment form */}
        &lt;form className=&quot;comment-form1&quot; onSubmit={onSubmit}&gt;
          &lt;input
            className=&quot;txtarea-comments&quot;
            style={{ width: &quot;100%&quot; }}
            onChange={handleChange}
            value={comment}
            placeholder=&quot;Type your comments here...&quot;
            onClick={btnSwap}
          /&gt;
          &lt;div className=&quot;comment-submit-div&quot;&gt;
            &lt;button
              className={submitOn ? &quot;txt-true&quot; : &quot;comment-submit-btn&quot;}
              onClick={onSubmit}
            &gt;
              Submit
            &lt;/button&gt;
          &lt;/div&gt;
        &lt;/form&gt;
      &lt;/div&gt;
    );
  };
  
  export default Comments;
  
  </code></pre>
  <p>here is the models/comment.js</p>
  <pre><code>import mongoose from &quot;mongoose&quot;;
  const Schema = mongoose.Schema;
  
  const commentSchema = mongoose.Schema(
    {
      name: { type: String },
      avatar: { type: String },
      postId: { type: String },
      responseTo: { type: String },
      content: {
        type: String,
      },
    },
    { timestamps: true }
  );
  
  export default mongoose.model(&quot;Comment&quot;, commentSchema);
  </code></pre>
  <p>here is the comment router</p>
  <pre><code>import express from &quot;express&quot;;
  import Comment from &quot;../models/Comment.js&quot;;
  
  const router = express.Router();
  
  router.post(&quot;/saveComment&quot;, (req, res) =&gt; {
    const comment = new Comment(req.body);
  
    comment.save((err, comment) =&gt; {
      if (err) return res.json({ success: false, err });
      Comment.find({ _id: comment._id })
        .populate(&quot;name&quot;, &quot;avatar&quot;)
        .exec((err, result) =&gt; {
          if (err) return res.json({ success: false, err });
          return res.status(200).json({ success: true, result });
        });
    });
  });
  
  export default router;
  
  </code></pre>
  <p>here is the videos router</p>
  <pre><code>import express from &quot;express&quot;;
  import multer from &quot;multer&quot;;
  import Upload from &quot;../models/Upload.js&quot;;
  
  const router = express.Router();
  
  var storage = multer.diskStorage({
    destination: (req, file, cb) =&gt; {
      cb(null, &quot;uploads/&quot;);
    },
    filename: (req, file, cb) =&gt; {
      cb(null, `${Date.now()}_${file.originalname}`);
    },
    fileFilter: (req, file, cb) =&gt; {
      const ext = path.extname(file.originalname);
      if (ext !== &quot;.mp4&quot;) {
        return cb(res.status(400).end(&quot;only video format is allowed&quot;), false);
      }
      cb(null, true);
    },
  });
  
  let upload = multer({ storage: storage }).single(&quot;file&quot;);
  
  //=================================
  //             Video
  //=================================
  
  router.post(&quot;/uploadfiles&quot;, (req, res) =&gt; {
    upload(req, res, (err) =&gt; {
      if (err) {
        return res.json({ success: false, err });
      }
      return res.json({
        success: true,
        filePath: res.req.file.path,
        fileName: res.req.file.filename,
      });
    });
  });
  
  router.post(&quot;/uploadVideo&quot;, (req, res) =&gt; {
    const video = new Upload(req.body);
  
    video.save((err, video) =&gt; {
      if (err) return res.status(400).json({ success: false, err });
      return res.status(200).json({
        success: true,
      });
    });
  });
  
  router.get(&quot;/getVideos&quot;, (req, res) =&gt; {
    Upload.find()
      .sort({ createdAt: -1 })
      .exec((err, videos) =&gt; {
        if (err) return res.status(400).send(err);
        res.status(200).json({ success: true, videos });
      });
  });
  
  router.post(&quot;/getVideo&quot;, (req, res) =&gt; {
    Upload.findOne({ _id: req.body.videoId })
      .populate(&quot;name&quot;, &quot;avatar&quot;)
      .exec((err, video) =&gt; {
        if (err) return res.status(400).send(err);
        res.status(200).json({ success: true, video });
      });
  });
  
  export default router;
  </code></pre>
  <p>here is the server.js</p>
  <pre><code>import express from &quot;express&quot;;
  import mongoose from &quot;mongoose&quot;;
  import cors from &quot;cors&quot;;
  import data from &quot;./data.js&quot;;
  import Videos from &quot;./dbModel.js&quot;;
  import postRoutes from &quot;./routes/posts.js&quot;;
  import userRouter from &quot;./routes/user.js&quot;;
  import commentRouter from &quot;./routes/comment.js&quot;;
  
  import uploadRouter from &quot;./routes/upload.js&quot;;
  
  const app = express();
  const port = process.env.PORT || 8000;
  
  //Middlewares
  app.use(express.json());
  app.use(cors());
  app.use(&quot;/posts&quot;, postRoutes);
  app.use(&quot;/user&quot;, userRouter);
  
  app.use(&quot;/video&quot;, uploadRouter);
  
  app.use(&quot;/uploads&quot;, express.static(&quot;uploads&quot;));
  
  if (process.env.NODE_ENV === &quot;production&quot;) {
    // Set static folder
    app.use(express.static(&quot;client/build&quot;));
  
    // index.html for all page routes
    app.get(&quot;*&quot;, (req, res) =&gt; {
      res.sendFile(path.resolve(__dirname, &quot;client&quot;, &quot;build&quot;, &quot;index.html&quot;));
    });
  }
  
  app.use(&quot;/comment&quot;, commentRouter);
  
  //db config
  const CONNECTION_URL =
    &quot;mongodb+srv://dimerson:9zRHuVcHLh5fSznu@cluster0.5n5rb.mongodb.net/KweebleDatabase?retryWrites=true&amp;w=majority&quot;;
  mongoose.connect(CONNECTION_URL, {
    useNewUrlParser: true,
    useCreateIndex: true,
    useUnifiedTopology: true,
  });
  
  app.get(&quot;/&quot;, (req, res) =&gt; res.status(200).send(&quot;hello world&quot;));
  
  app.get(&quot;/v1/posts&quot;, (req, res) =&gt; res.status(200).send(data));
  app.post(&quot;/v2/posts&quot;, (req, res) =&gt; {
    const dbVideos = req.body;
    Videos.create(dbVideos, (err, data) =&gt; {
      if (err) {
        res.status(500).send(err);
      } else {
        res.status(201).send(data);
      }
    });
  });
  
  app.get(&quot;/v2/posts&quot;, (req, res) =&gt; {
    Videos.find((err, data) =&gt; {
      if (err) {
        res.status(500).send(err);
      } else {
        res.status(200).send(data);
      }
    });
  });
  
  app.listen(port, () =&gt; console.log(`listening on localhost:${port}`));
  
  </code></pre>