<?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: Justin J Daniel</title>
    <description>The latest articles on DEV Community by Justin J Daniel (@justinjdaniel).</description>
    <link>https://dev.to/justinjdaniel</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%2F1336193%2F3763097e-7161-4db4-9f84-a933f873040e.jpg</url>
      <title>DEV Community: Justin J Daniel</title>
      <link>https://dev.to/justinjdaniel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/justinjdaniel"/>
    <language>en</language>
    <item>
      <title>How a .gitattributes File Fixed Broken Images (and Why You Should Use One Too!)</title>
      <dc:creator>Justin J Daniel</dc:creator>
      <pubDate>Tue, 20 May 2025 16:24:56 +0000</pubDate>
      <link>https://dev.to/justinjdaniel/how-a-gitattributes-file-fixed-my-broken-images-and-why-you-should-use-one-too-55fb</link>
      <guid>https://dev.to/justinjdaniel/how-a-gitattributes-file-fixed-my-broken-images-and-why-you-should-use-one-too-55fb</guid>
      <description>&lt;p&gt;Recently, I ran into an issue where images in a documentation repository wouldn't render locally. After some digging, I realized the problem was that Git wasn't treating image files as binary, causing them to break, even in VSCode. The fix? Adding a &lt;code&gt;.gitattributes&lt;/code&gt; file!&lt;/p&gt;

&lt;p&gt;This post explains why &lt;code&gt;.gitattributes&lt;/code&gt; matters, what problems it solves, and how you can use it to avoid file mishandling in your own projects.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;What is a &lt;code&gt;.gitattributes&lt;/code&gt; File?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;.gitattributes&lt;/code&gt; file is a simple text file you add to your repository to tell Git how to handle specific files or patterns. Each line specifies a pattern (like &lt;code&gt;*.png&lt;/code&gt;) and one or more attributes (like marking a file as binary).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*.png binary
*.jpg binary
*.md text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Why is &lt;code&gt;.gitattributes&lt;/code&gt; Important?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prevents Broken Images and Binaries:&lt;/strong&gt;
Without proper attributes, Git might treat images or other binaries as text, corrupting them during commits or merges.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent Line Endings:&lt;/strong&gt;
Handles differences between Windows (CRLF) and Unix (LF) systems, avoiding annoying diffs and merge conflicts caused by inconsistent line endings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improves Diffs and Merges:&lt;/strong&gt;
You can tell Git to ignore diffs for generated files, or use custom merge strategies for complex file types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Collaboration:&lt;/strong&gt;
Ensures everyone on your team, regardless of OS or editor, works with files in the correct format.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What Files Should You Add to &lt;code&gt;.gitattributes&lt;/code&gt;?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Images and Binaries:&lt;/strong&gt;
Mark all image, audio, video, and compiled files as &lt;code&gt;binary&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  *.png binary
  *.jpg binary
  *.gif binary
  *.pdf binary
  *.zip binary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text Files:&lt;/strong&gt;
Enforce consistent line endings:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  *.js eol=lf
  *.jsx eol=lf
  *.md text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large Files:&lt;/strong&gt;
For large assets, consider using Git LFS and mark them in &lt;code&gt;.gitattributes&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  *.psd filter=lfs diff=lfs merge=lfs -text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Generated or Vendor Files:&lt;/strong&gt;
Hide from diffs or language stats:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  /dist/* linguist-generated=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Sample &lt;code&gt;.gitattributes&lt;/code&gt; for a Documentation Repo&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Treat images as binary
*.png binary
*.jpg binary
*.gif binary
*.svg binary # SVGs are text-based (XML) but often treated as binary to prevent line-ending/merge issues.

# Treat markdown as text
*.md text

# Enforce LF for code files
*.js eol=lf
*.jsx eol=lf
*.json eol=lf

# Hide build files from diffs and stats
/dist/* linguist-generated=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;How to Add and Commit a &lt;code&gt;.gitattributes&lt;/code&gt; File&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;.gitattributes&lt;/code&gt; file in your repo's root.&lt;/li&gt;
&lt;li&gt;Add the patterns and attributes you need.&lt;/li&gt;
&lt;li&gt;Commit the file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   git add .gitattributes
   git commit -m "Add .gitattributes for correct file handling"
   git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Extra Tips&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;.gitattributes&lt;/code&gt; to set custom merge strategies or encoding for special file types.&lt;/li&gt;
&lt;li&gt;For existing repos, you may need to re-add files with &lt;code&gt;git add --renormalize .&lt;/code&gt; to apply new attributes.&lt;/li&gt;
&lt;li&gt;For really big files (like Photoshop files), look into &lt;a href="https://git-lfs.github.com/" rel="noopener noreferrer"&gt;Git LFS&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Useful Links&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/docs/gitattributes" rel="noopener noreferrer"&gt;Official Git documentation: .gitattributes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings" rel="noopener noreferrer"&gt;GitHub Docs: Configuring Git to handle line endings&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading, and have a beautiful day! ❤️&lt;/p&gt;

</description>
      <category>git</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Effortless Token Refresh in React Using Axios Interceptors</title>
      <dc:creator>Justin J Daniel</dc:creator>
      <pubDate>Mon, 19 May 2025 04:26:05 +0000</pubDate>
      <link>https://dev.to/justinjdaniel/effortless-token-refresh-in-react-using-axios-interceptors-4n3j</link>
      <guid>https://dev.to/justinjdaniel/effortless-token-refresh-in-react-using-axios-interceptors-4n3j</guid>
      <description>&lt;p&gt;Keeping users logged in securely is essential for any modern web app. One way to achieve this is with &lt;strong&gt;token rotation&lt;/strong&gt;, a method that automatically refreshes expired access tokens using a refresh token, all without interrupting the user experience. In this beginner-friendly guide, you'll learn how to implement token rotation in a React app using Axios interceptors, without interfering with your server logic. We'll also compare common token storage options so you can choose what's best for your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What is Token Rotation?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Token rotation is a technique where, instead of keeping a refresh token forever, you get a new refresh token each time you use it. This makes your app more secure because even if a refresh token is stolen, it can only be used once before it becomes invalid.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Does Axios Interceptor Help?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Axios interceptors let you run logic before a request is sent or after a response is received. Here, we'll use a &lt;strong&gt;response interceptor&lt;/strong&gt; to detect when an access token has expired and automatically fetch a new one using the refresh token-without the user noticing.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step-by-Step Example: Token Rotation with Axios&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Below is a simple implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// api.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create an Axios instance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://your-api-url.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your backend URL&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Function to get tokens from storage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;accessToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;refreshToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Function to save tokens to storage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;accessToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;refreshToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Add the access token to every request&lt;/span&gt;
&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;interceptors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getTokens&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Authorization&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Handle token expiration and rotation&lt;/span&gt;
&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;interceptors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;originalRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// If the access token has expired, try to refresh&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;originalRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_retry&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;originalRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_retry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getTokens&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Request new access token&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/auth/refresh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
          &lt;span class="c1"&gt;// Save new tokens&lt;/span&gt;
          &lt;span class="nf"&gt;setTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="c1"&gt;// Retry the original request with new token&lt;/span&gt;
          &lt;span class="nx"&gt;originalRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Authorization&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;originalRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refreshError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Refresh token invalid, force logout or redirect to login&lt;/span&gt;
          &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Any other error&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Visual Flow

User clicks "Profile" →
  Access token expired →
    401 error →
      Interceptor calls refresh endpoint →
        Success? →
          Retry original request →
            User sees profile (no error)
        Failure? →
          Show login prompt (user sees error)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Every request includes the access token.&lt;/li&gt;
&lt;li&gt;If the server returns 401 (Unauthorized), the interceptor tries to refresh the token using the refresh token.&lt;/li&gt;
&lt;li&gt;If successful, it retries the original request with the new access token.&lt;/li&gt;
&lt;li&gt;If refresh fails, it logs the user out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Token Storage Options: Pros &amp;amp; Cons&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Storage Option&lt;/th&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local Storage&lt;/td&gt;
&lt;td&gt;Easy to use, persists after reload&lt;/td&gt;
&lt;td&gt;Vulnerable to XSS attacks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session Storage&lt;/td&gt;
&lt;td&gt;Safer than localStorage, cleared on tab close&lt;/td&gt;
&lt;td&gt;Still vulnerable to XSS, not persistent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HttpOnly Cookies&lt;/td&gt;
&lt;td&gt;Protected from XSS, sent automatically&lt;/td&gt;
&lt;td&gt;More complex setup, vulnerable to CSRF&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local Storage:&lt;/strong&gt; Simple, but less secure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session Storage:&lt;/strong&gt; Slightly safer, but data is lost on tab close.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HttpOnly Cookies:&lt;/strong&gt; Most secure, but requires backend changes and CSRF protection.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With Axios interceptors, you can easily implement token rotation in your React app. This keeps users logged in seamlessly and securely, without extra hassle. Remember to choose the token storage method that best fits your security needs and app requirements.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and have a beautiful day! ❤️&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>react</category>
      <category>security</category>
    </item>
    <item>
      <title>Unleash Your Inner Musician with AI-Powered Music Creation: Suno.ai</title>
      <dc:creator>Justin J Daniel</dc:creator>
      <pubDate>Fri, 29 Mar 2024 18:30:00 +0000</pubDate>
      <link>https://dev.to/justinjdaniel/unleash-your-inner-musician-with-ai-powered-music-creation-sunoai-14im</link>
      <guid>https://dev.to/justinjdaniel/unleash-your-inner-musician-with-ai-powered-music-creation-sunoai-14im</guid>
      <description>&lt;p&gt;Have you ever dreamt of creating your own song, but felt held back by a lack of musical training or equipment? The world of music creation is undergoing a revolutionary shift thanks to Artificial Intelligence. Today, I'd like to introduce you to Suno.ai, a platform that empowers anyone to create music using AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Suno.ai: Your AI Music Creation Playground
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://suno.ai"&gt;Suno.ai&lt;/a&gt;, a revolutionary AI-powered music creation platform, that turns your imagination into reality. With the release of their latest version, v3, users can now produce radio-quality music in mere seconds. This remarkable capability to generate full, two-minute songs almost instantaneously is a testament to the rapid advancements in AI technology and its application in creative fields.&lt;/p&gt;

&lt;p&gt;Remember when Microsoft integrated the Suno plugin into their Copilot system last year? It opened the door to creating songs through simple prompts, a feature that continues to captivate users worldwide. The ease of transforming a musical idea into a tangible tune is simply magical.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond the Basics: Exploring, Learning, and Refining Your Music
&lt;/h2&gt;

&lt;p&gt;As a seasoned Suno.ai user, I've witnessed the platform's incredible evolution. One of the most praised features is the ability to seamlessly continue a song with a new prompt or even remix existing creations. This flexibility allows you to experiment and refine your tracks, pushing the boundaries of traditional music production.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here's a deeper look at some of Suno.ai's powerful features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://suno-ai.notion.site/Supported-Languages-16550b00a3f04ee6bab541d135eaf713"&gt;Multilingual Support&lt;/a&gt;:&lt;/strong&gt; Unleash your creativity in over 50 languages!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://suno-ai.notion.site/Subscriptions-f33c81dcee7a4069986e737b4b0dcc36"&gt;Free and Paid Plans&lt;/a&gt;:&lt;/strong&gt; Choose from the free Basic plan (with 50 daily credits for 10 songs) or explore the Pro and Premier options for even more features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://suno-ai.notion.site/Using-Metatags-34944efe09ec41d693e314f13af44695"&gt;Advanced Song Crafting&lt;/a&gt;:&lt;/strong&gt; Take your music creation to the next level with Suno.ai's meta tags, allowing for precise control over the style and direction of your song.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://suno-ai.notion.site/Tips-Tricks-Chirp-v1-969852c74c644c6b8262ec5c5be2325c"&gt;Seamless Song Development&lt;/a&gt;:&lt;/strong&gt; Craft unique sonic journeys by using subsequent prompts to create continuations or remixes of your existing tracks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suno.ai's &lt;a href="https://suno-ai.notion.site/Docs-Guides-Resources-38e5ba5856d249a89dcea31655f4fb74"&gt;documentation&lt;/a&gt; offers valuable insights on optimizing song creation using &lt;a href="https://suno-ai.notion.site/Using-Metatags-34944efe09ec41d693e314f13af44695"&gt;metatags&lt;/a&gt;. These guidelines unlock the platform's full potential, helping you craft tunes that resonate with your target audience.&lt;/p&gt;

&lt;p&gt;Speaking of global appeal, Suno.ai's support for over 50 languages makes it a truly inclusive tool, accessible to a diverse user base. Additionally, their subscription plans cater to various needs, from the free Basic plan (perfect for beginners) that provides 50 credits daily for creating up to 10 songs, to Pro and Premier plans for more serious creators.&lt;/p&gt;

&lt;p&gt;The "&lt;a href="https://app.suno.ai"&gt;Explore&lt;/a&gt;" section on Suno.ai's website showcases an array of songs crafted using the platform, serving as both inspiration and a testament to the creative possibilities unleashed by AI in music.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future of Music is Here: AI and Creativity in Harmony
&lt;/h2&gt;

&lt;p&gt;As we look towards the horizon, it's clear that AI will continue to play a transformative role in the arts. Platforms like Suno.ai aren't just tools; they're collaborators, empowering artists and enthusiasts to explore uncharted territories in the realm of music. The melody of innovation is undeniable, and it sings of a world where technology and creativity come together in perfect symphony.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and have a beautiful day! ❤️&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tooling</category>
      <category>music</category>
    </item>
    <item>
      <title>Unlocking the Power of Mongoose Schemas: Enhancements for Better Data Handling</title>
      <dc:creator>Justin J Daniel</dc:creator>
      <pubDate>Thu, 07 Mar 2024 17:17:34 +0000</pubDate>
      <link>https://dev.to/justinjdaniel/unlocking-the-power-of-mongoose-schemas-enhancements-for-better-data-handling-l1g</link>
      <guid>https://dev.to/justinjdaniel/unlocking-the-power-of-mongoose-schemas-enhancements-for-better-data-handling-l1g</guid>
      <description>&lt;p&gt;In the world of MongoDB and Node.js, Mongoose stands as a powerful Object Data Modeling (ODM) library that simplifies the interaction with MongoDB. It provides a straightforward, schema-based solution to model your application data, ensuring validation, type casting, query building, and business logic encapsulation. But what if we could take it a step further? What if we could leverage Mongoose's features to not only model our data but also to enhance our application's functionality, security, and maintainability? Let's dive into the enhancements that can be made in Mongoose schemas to unlock their full potential.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Power of Indexes
&lt;/h2&gt;

&lt;p&gt;First on our list is the power of indexes. Indexes are like the backbone of any database, providing a way to speed up data retrieval. In Mongoose, you can define indexes on your schema fields to optimize query performance. For instance, if you frequently query users based on their last login time, adding an index on the &lt;code&gt;lastLogin&lt;/code&gt; field can significantly reduce the time it takes to fetch the most recently logged-in users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;lastLogin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Usage in Controller:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recentUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;lastLogin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple line of code tells MongoDB to create an index on the &lt;code&gt;lastLogin&lt;/code&gt; field, sorted in descending order. Now, when you perform a query to find the most recently logged-in users, MongoDB can quickly locate the documents without scanning the entire collection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validation: The Cornerstone of Data Integrity
&lt;/h2&gt;

&lt;p&gt;Next, let's talk about validation. In any application, data integrity is paramount. Mongoose allows you to define validation rules directly in your schema. This ensures that only valid data is saved to the database, preventing potential bugs and security vulnerabilities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;// Custom validation logic here&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// or false, depending on the validation result&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email validation failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Usage in Controller:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ValidationError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle validation error&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup, Mongoose will automatically validate the &lt;code&gt;email&lt;/code&gt; field before saving a document. If the validation fails, Mongoose will throw a validation error, allowing you to handle it gracefully in your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtuals: Computed Properties for Enhanced Readability
&lt;/h2&gt;

&lt;p&gt;Virtuals are a powerful feature in Mongoose that allows you to define computed properties on your documents. These properties are not stored in the database but are computed on the fly when accessed. This is particularly useful for combining fields or formatting data in a way that's more readable or useful for your application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;virtual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fullName&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Usage in Controller:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Outputs the full name of the user&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this virtual property, you can easily access the full name of a user without having to concatenate the &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; fields every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods and Static Methods: Encapsulating Business Logic
&lt;/h2&gt;

&lt;p&gt;Mongoose schemas allow you to define methods that can be executed on instances of your models. This is perfect for encapsulating business logic that operates on individual documents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasRole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Static methods, on the other hand, are defined on the model itself and can be used for operations that don't require an instance of the model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findByUsername&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Usage in Controller:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByUsername&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;johndoe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;// Perform admin-specific actions&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Hooks: Automating Actions at Key Lifecycle Stages
&lt;/h2&gt;

&lt;p&gt;Hooks, or middleware, are functions that are executed at various stages of a document's lifecycle. They can be used to perform actions automatically, such as data transformation, validation, or logging.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;save&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;// Perform actions before saving&lt;/span&gt;
 &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Usage in Controller:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;// Handle any errors that occurred during the save operation&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hooks can be defined for a wide range of events, including &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;findOne&lt;/code&gt;, &lt;code&gt;findOneAndUpdate&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt;, and &lt;code&gt;validate&lt;/code&gt;. They provide a powerful way to automate actions and enforce business logic across your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By leveraging these enhancements in Mongoose schemas, you can significantly improve the functionality, security, and maintainability of your MongoDB-based applications. From optimizing query performance with indexes to ensuring data integrity with validation, and from encapsulating business logic with methods and static methods to automating actions with hooks, Mongoose offers a comprehensive set of tools to build robust and efficient applications.&lt;/p&gt;

&lt;p&gt;In the ever-evolving landscape of web development, staying ahead of the curve is crucial. By mastering these advanced features of Mongoose, you're not just enhancing your schemas; you're unlocking the full potential of your application, ensuring it's not just functional but also efficient, secure, and maintainable.&lt;/p&gt;

&lt;p&gt;Have a beautiful day! ❤️&lt;/p&gt;

&lt;p&gt;Feel free to connect with me on &lt;a href="https://www.linkedin.com/in/justin-j-daniel/"&gt;LinkedIn&lt;/a&gt; and &lt;a href="https://github.com/justinjdaniel"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>mongoose</category>
      <category>schema</category>
      <category>mongodb</category>
    </item>
  </channel>
</rss>
