<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dan N</title>
    <description>The latest articles on DEV Community by Dan N (@dance_nguyen).</description>
    <link>https://dev.to/dance_nguyen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F113262%2F325a0403-2f80-43f4-bd92-d2f824348ec9.png</url>
      <title>DEV Community: Dan N</title>
      <link>https://dev.to/dance_nguyen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dance_nguyen"/>
    <language>en</language>
    <item>
      <title>Next.js: getStaticProps, getServerSideProps, useEffect???</title>
      <dc:creator>Dan N</dc:creator>
      <pubDate>Fri, 30 May 2025 23:01:33 +0000</pubDate>
      <link>https://dev.to/dance_nguyen/nextjs-getstaticprops-getserversideprops-useeffect-47jo</link>
      <guid>https://dev.to/dance_nguyen/nextjs-getstaticprops-getserversideprops-useeffect-47jo</guid>
      <description>&lt;p&gt;I'm creating a Next.js web app where users can create private logs and attach tags to them. These logs are displayed initally on the main page, and when a new one is added, the page updates automatically. I ran into the question; how do I fetch all of the existing data from the database and display them to the user with Next.js? &lt;/p&gt;

&lt;p&gt;Next offered a couple of function options (getStaticProps, getServerSideProps) and I finally landed on a regular React one (useEffect) after some trial and error.&lt;/p&gt;

&lt;p&gt;I started with getStaticProps first just to make sure my fetching funcationality was working.&lt;/p&gt;

&lt;p&gt;getStaticProps from next docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;The data required to render the page is available at build time ahead of a user’s request&lt;/li&gt;
&lt;li&gt;The data comes from a headless CMS &lt;/li&gt;
&lt;li&gt;The page must be pre-rendered (for SEO) and be very fast — &lt;code&gt;getStaticProps&lt;/code&gt; generates &lt;code&gt;HTML&lt;/code&gt; and &lt;code&gt;JSON&lt;/code&gt; files, both of which can be cached by a CDN for performance&lt;/li&gt;
&lt;li&gt;The data can be publicly cached. &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I realized that the data I was working with isn't something that I'd like publicly cached. The logs I'm working with aren't like tweets or blog posts, but rather private to whoever's posting them.&lt;/p&gt;

&lt;p&gt;So, I looked to getServerSideProps next.&lt;br&gt;
getServerSideProps from next docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You should use &lt;code&gt;getServerSideProps&lt;/code&gt; if you need to render a page that relies on personalized user data, or information that can only be known at request time. For example, &lt;code&gt;authorization&lt;/code&gt; headers or a geolocation. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It seemed to fit the use case. It runs on the server, and when a user visits a page, getServerSideProps will be used to fetch data at request time. The data is used to render the initial HTML of the page. &lt;/p&gt;

&lt;p&gt;It's also fast! This seemed to fit my use case. However, I realized I’d need to be able to run whatever logic I put in there again to update the logs page if someone made a new log. getServerSideProps will do a ONE TIME fetch on the server before rendering your page. It will no longer do anything until a full page refresh.&lt;/p&gt;

&lt;p&gt;I finally found what fit my use case, useEffect!&lt;br&gt;
useEffect:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;useEffect is a React Hook that lets you synchronize a component with an external system&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's a lifecycle method that activates whenever your component rerenders, based on the criteria you pass it. &lt;br&gt;
Think of an app that refetches new data based on a user clicking a button; useEffect can wait for that click then do a new fetch.&lt;/p&gt;

&lt;p&gt;Yes, it's slower than getServerSideProps, but I could get it to run again if a user submits a new log to display the new entry!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Adding, Updating, and Removing Subdocuments with Mongoose</title>
      <dc:creator>Dan N</dc:creator>
      <pubDate>Fri, 11 Dec 2020 17:31:00 +0000</pubDate>
      <link>https://dev.to/dance_nguyen/adding-updating-and-removing-subdocuments-with-mongoose-1dj5</link>
      <guid>https://dev.to/dance_nguyen/adding-updating-and-removing-subdocuments-with-mongoose-1dj5</guid>
      <description>&lt;p&gt;I was building an application when I ran into a problem; how do I use subdocuments?&lt;/p&gt;

&lt;p&gt;I found a way that worked for what I needed; I'll use an example where the application has users and each user can have one or more posts. &lt;/p&gt;

&lt;p&gt;Here's what the model for the posts could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require("mongoose");

const postSchema = new mongoose.Schema({
  title: { type: String, required: true },
  text: { type: String },  
});

const Post = mongoose.model("Post", postSchema);

module.exports = Post;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here's the model for the user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require("mongoose");
const postSchema = require("./post.js").schema; //or wherever post.js is

const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  details: { type: String },
  userid: { type: String, required: true,
    index: {
      unique: true,
    }
  },
  posts: [postSchema]
});

const User = mongoose.model("User", userSchema);

module.exports = User;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing to note here is that the each user will have an array of posts and that each of those is an array of post schemas, not the post model itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding subdocuments
&lt;/h2&gt;

&lt;p&gt;Now let's get to adding the subdocuments!&lt;/p&gt;

&lt;p&gt;For adding posts, I have this where I have this where I have my routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Project = require("../models/project.js");

router.put("/addpost/:id", (req, res) =&amp;gt; {

  //find the user first, then add the post to it
  User.findById(req.params.id, function(err, result) {
    if (!err) {
      if (!result){
        res.sendStatus(404).send('User was not found').end();
      }
      else{
        result.posts.push(req.body);
        result.markModified('posts'); 
        result.save(function(saveerr, saveresult) {
          if (!saveerr) {
            res.status(200).send(saveresult);
          } else {
            res.status(400).send(saveerr.message);
          }
        });
      }
    } else {
      res.status(400).send(err.message);
    }
  });
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, I look for the existing user first (There's more than one way to do this; I did it by using findById() and passing in the id from the route parameter). The part that tripped me up here was, what do I do after finding the user? It turns out that I can edit the result in the callback of the find directly - by adding the new post to the user's post array, and then using the save() function to save those changes to the user in MongoDB! If I go to my database on MongoDB and navigate to the user I just edited, I'll be able to find the post I created for that particular user under the "posts" array. If I expand that post, I should be able to see that MongoDB created a unique id for it. This will be important later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating subdocuments
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.put("/updatepost/:id", (req, res) =&amp;gt; {
  //find user by its id, update its post with what's in req.body
  User.findById(req.params.id, function(err, result) {
    if (!err) {
      if (!result){
        res.status(404).send('User was not found');
      }
      else{
        result.posts.id(req.body._id).title = req.body.title;
        result.posts.id(req.body._id).text = req.body.text;
        result.markModified('posts'); 
        result.save(function(saveerr, saveresult) {
          if (!saveerr) {
            res.status(200).send(saveresult);
          } else {
            res.status(400).send(saveerr.message);
          }
        });
      }
    } else {
      res.status(400).send(err.message);
    }
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, I find the user like I did before. This time, since I'm looking for an existing post, I can use id() to find that post in the posts array identified by its unique id. I set the fields that I want to change and then use save() to save the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Removing subdocuments
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.put("/removepost/:id", (req, res) =&amp;gt; {
  //find the user by the id parameter first, then locate and remove the post specified by the id in req.body 
  User.findById(req.params.id, function(err, result) {
    if (!err) {
      if (!result){
        res.status(404).send('User was not found');
      }
      else{
        result.posts.id(req.body._id).remove(function(removeerr, removresult) {
          if (removeerr) {
            res.status(400).send(removeerr.message);
          }
        });
        result.markModified('posts'); 
        result.save(function(saveerr, saveresult) {
          if (!saveerr) {
            res.status(200).send(saveresult);
          } else {
            res.status(400).send(saveerr.message);
          }
        });
      }
    } else {
      res.status(400).send(err.message);
    }
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this last part, I again first located the user. Then I found the specific post I wanted to delete by its id using id() and then removed it by calling remove(). Again, I used save() to save the changes.&lt;/p&gt;

&lt;p&gt;For reference: &lt;a href="https://mongoosejs.com/docs/subdocs.html" rel="noopener noreferrer"&gt;https://mongoosejs.com/docs/subdocs.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mongoose</category>
      <category>mongodb</category>
    </item>
    <item>
      <title>Deploying a Django Blog App on Heroku</title>
      <dc:creator>Dan N</dc:creator>
      <pubDate>Sun, 13 Sep 2020 16:35:47 +0000</pubDate>
      <link>https://dev.to/dance_nguyen/deploying-a-django-blog-app-on-heroku-ja</link>
      <guid>https://dev.to/dance_nguyen/deploying-a-django-blog-app-on-heroku-ja</guid>
      <description>&lt;p&gt;(For personal reference, this is what worked for me) &lt;/p&gt;

&lt;p&gt;I tried a couple ways to deploy a Django blog app to Heroku and finally found a way that worked for me! &lt;/p&gt;

&lt;p&gt;I used the django-heroku library. It helps automatically configure &lt;code&gt;DATABASE_URL&lt;/code&gt;, &lt;code&gt;ALLOWED_HOSTS&lt;/code&gt;, WhiteNoise (for static assets), Logging, and Heroku CI for the application so we don’t have to ourselves. For reference, &lt;a href="https://github.com/heroku/django-heroku" rel="noopener noreferrer"&gt;https://github.com/heroku/django-heroku&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also used gunicorn, which is a Python WSGI HTTP Server for UNIX. (I don't install this locally since I'm working in a windows environment but since Heroku needs gunicorn for deployment, I have it as something Heroku itself needs to download)&lt;/p&gt;

&lt;p&gt;Here’re the things that I added/steps that I took:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;requirements.txt&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let Heroku know what packages it needs to download in a requirements.txt file in the main directory. In here we have Django, django-heroku, and gunicorn&lt;/p&gt;

&lt;p&gt;&lt;em&gt;maindirectory/requirements.txt:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Django~=&amp;lt;version number&amp;gt;
gunicorn
django-heroku
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Procfile&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Set up a Procfile in the main directory (important: it needs to be titled as Procfile, not Procfile.txt!) A Procfile declares what commands should be run by Heroku in order to start up the website.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;maindirectory/Procfile:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: gunicorn &amp;lt;mysite&amp;gt;.wsgi --log-file -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line means that we're deploying a web application and that it should be started by running gunicorn mysite.wsgi&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;settings.py&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Configure the app using django-heroku somewhere in settings.py &lt;/p&gt;

&lt;p&gt;&lt;em&gt;maindirectory//settings.py:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Configure Django App for Heroku.
import django_heroku
django_heroku.settings(locals())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Install Heroku&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;*This step can be skipped if it's already done&lt;/p&gt;

&lt;p&gt;Install the Heroku CLI from here: &lt;a href="https://devcenter.heroku.com/articles/heroku-cli" rel="noopener noreferrer"&gt;https://devcenter.heroku.com/articles/heroku-cli&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Authenticate the Heroku account on the computer by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ heroku login&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Deploy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now to deploy to Heroku! Create a heroku application on the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ heroku create &amp;lt;app name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;commit changes and push&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git add .
$ git commit -m "some message"
$ git push heroku
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ve deployed your code to Heroku, and specified the process types in the &lt;code&gt;Procfile&lt;/code&gt; (we chose a &lt;code&gt;web&lt;/code&gt; process type earlier). We can now tell Heroku to start this &lt;code&gt;web process&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To do that, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ heroku ps:scale web=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now visit the app in our browser with &lt;code&gt;heroku open&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ heroku open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>django</category>
      <category>heroku</category>
    </item>
  </channel>
</rss>
