<?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: Nhan Nguyen</title>
    <description>The latest articles on DEV Community by Nhan Nguyen (@nhannguyenuri).</description>
    <link>https://dev.to/nhannguyenuri</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%2F644107%2Fc3f302d9-2891-436a-ae4c-3897d9485922.jpg</url>
      <title>DEV Community: Nhan Nguyen</title>
      <link>https://dev.to/nhannguyenuri</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nhannguyenuri"/>
    <language>en</language>
    <item>
      <title>Conditional Validation in Angular 21 Signal Forms: `when` vs `applyWhen`</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Thu, 11 Dec 2025 04:10:34 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/conditional-validation-in-angular-21-signal-forms-when-vs-applywhen-4mhc</link>
      <guid>https://dev.to/nhannguyenuri/conditional-validation-in-angular-21-signal-forms-when-vs-applywhen-4mhc</guid>
      <description>&lt;p&gt;Angular 21's Signal Forms introduce a powerful, declarative approach to conditional validation that makes complex form logic much cleaner. Let's break down the two main approaches: &lt;code&gt;when&lt;/code&gt; and &lt;code&gt;applyWhen&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;when&lt;/code&gt; Property: Single Rule Conditions
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;when&lt;/code&gt; property allows you to conditionally apply a &lt;strong&gt;single validation rule&lt;/strong&gt; based on other field values. Perfect for simple conditional requirements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;schemaPath&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;message&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 is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;valueOf&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;schemaPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendViaEmail&lt;/span&gt;&lt;span class="p"&gt;)&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the email field is only required when the &lt;code&gt;sendViaEmail&lt;/code&gt; checkbox is checked. The &lt;code&gt;valueOf()&lt;/code&gt; function gives you reactive access to any field's current value.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;applyWhen&lt;/code&gt; Function: Multiple Rule Conditions
&lt;/h2&gt;

&lt;p&gt;When you need to apply &lt;strong&gt;multiple validation rules&lt;/strong&gt; conditionally, reach for &lt;code&gt;applyWhen&lt;/code&gt;. It takes three arguments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The field path to validate&lt;/li&gt;
&lt;li&gt;A predicate function (your condition)&lt;/li&gt;
&lt;li&gt;A schema function containing all the rules to apply
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;applyWhen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;schemaPath&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="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;valueOf&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;schemaPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sendViaEmail&lt;/span&gt;&lt;span class="p"&gt;)&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emailPath&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="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emailPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&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 is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emailPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter a valid email address&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This groups related validation logic together and keeps your schema clean and readable.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Which?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;when&lt;/code&gt;&lt;/strong&gt;: For single validation rules that need a condition&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;applyWhen&lt;/code&gt;&lt;/strong&gt;: For multiple related rules that share the same condition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both approaches leverage Signal Forms' reactive nature—validation updates automatically as field values change, with no manual subscription management needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Signal Forms' conditional validation features make complex form logic declarative and maintainable. Whether you're validating a single field or orchestrating multiple dependent rules, the &lt;code&gt;when&lt;/code&gt; property and &lt;code&gt;applyWhen&lt;/code&gt; function give you the flexibility to express your form's business logic clearly and concisely.&lt;/p&gt;

&lt;p&gt;Ready to try Signal Forms? Remember it's currently experimental in Angular 21, but it's already showing promise as the future of Angular forms!&lt;/p&gt;

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

&lt;p&gt;

&lt;iframe src="https://stackblitz.com/edit/stackblitz-starters-1l1qturg?embed=1&amp;amp;file=src%2Fmain.ts" width="100%" height="500"&gt;
&lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope you found it helpful. Thanks for reading!&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium&lt;/strong&gt;: &lt;a href="https://medium.com/@nhannguyenuri/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyenuri/"&gt;https://dev.to/nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/nhannguyenuri/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support Me&lt;/strong&gt;: &lt;a href="https://buymeacoffee.com/nhannguyenuri" rel="noopener noreferrer"&gt;https://buymeacoffee.com/nhannguyenuri&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building a Reactive Login Form with Angular Signal Forms</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Mon, 24 Nov 2025 04:36:36 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/building-a-reactive-login-form-with-angular-signal-forms-1b55</link>
      <guid>https://dev.to/nhannguyenuri/building-a-reactive-login-form-with-angular-signal-forms-1b55</guid>
      <description>&lt;p&gt;Signal-based forms are one of the coolest new additions to Angular’s ecosystem.&lt;/p&gt;

&lt;p&gt;Let’s walk through what the sample login form above is doing and why it’s nice to work with.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Modeling the form with signals&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, we define a simple data model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;LoginData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;Then we create a signal that holds that model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;loginModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LoginData&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This signal is our single source of truth for the form’s state. Instead of separate controls, we bind the whole object and let the form() helper take care of wiring it up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Creating a signal form&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;loginForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&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;loginModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;login&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="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;login&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&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 is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;login&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter a valid email address&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;((?=\S&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;?[&lt;/span&gt;&lt;span class="sr"&gt;A-Z&lt;/span&gt;&lt;span class="se"&gt;])(?=\S&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;?[&lt;/span&gt;&lt;span class="sr"&gt;a-z&lt;/span&gt;&lt;span class="se"&gt;])(?=\S&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;?[&lt;/span&gt;&lt;span class="sr"&gt;0-9&lt;/span&gt;&lt;span class="se"&gt;])&lt;/span&gt;&lt;span class="sr"&gt;.&lt;/span&gt;&lt;span class="se"&gt;{6,})\S&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Password must be at least 6 characters long and include at least one uppercase letter, one lowercase letter, and one number, with no spaces.&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What’s going on here?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;form(this.loginModel, …) creates a signal form bound to the loginModel signal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inside the callback, login exposes field-level signals like login.email and login.password.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We attach validation rules using helpers like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;required(field, { message })&lt;/li&gt;
&lt;li&gt;email(field, { message })&lt;/li&gt;
&lt;li&gt;pattern(field, regex, { message })&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Each field now knows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Its current value (as a signal)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Its validation status&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Its list of errors (if any)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Binding to the template with  and [field]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the template, we don’t deal with [(ngModel)] or formControlName. Instead, we use the Field standalone component and bind the field signal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;[field]=&lt;/span&gt;&lt;span class="s"&gt;"loginForm.email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s enough for Angular to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set the input’s value&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the field when the user types&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Trigger validation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To show validation errors, we just read from the field’s errors() signal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@for (err of loginForm.email().errors(); track err.kind) {
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color: red; font-size: smaller"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;*{{ err.message }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same for the password field.&lt;/p&gt;

&lt;p&gt;And because everything is signal-based, we can easily display live values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hello {{ loginForm.email().value() }}!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Password length: {{ loginForm.password().value().length }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No async pipes, no manual subscription management—just reading signal values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Reacting to form changes with RxJS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Signals are great, but sometimes you still want an RxJS stream—for example, to debounce user input before saving or logging.&lt;/p&gt;

&lt;p&gt;That’s what this part does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;toObservable&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="nf"&gt;loginForm&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="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;debounceTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;distinctUntilChanged&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nf"&gt;takeUntilDestroyed&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;destroyRef&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="nf"&gt;subscribe&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="o"&gt;=&amp;gt;&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;value&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breakdown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;this.loginForm().value is a signal representing the full form value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;toObservable(...) converts that signal into an Observable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We apply RxJS operators:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;debounceTime(500) – wait 500ms after the last change.&lt;/li&gt;
&lt;li&gt;distinctUntilChanged() – only react when the value actually changes.&lt;/li&gt;
&lt;li&gt;takeUntilDestroyed(this.destroyRef) – automatically clean up when the component is destroyed.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Finally, we subscribe and log the result.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This gives you the best of both worlds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Signals for template binding and simple reactivity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RxJS for more advanced reactive pipelines.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Why signal forms feel so good&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A few nice properties of this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Type-safe by default: The form is built from a typed model (LoginData).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No manual subscriptions for validation or display — signals handle it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Template stays clean: [field] is easier to reason about than mixing ngModel, FormControl, and validators.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easy interoperability with existing RxJS-based code via toObservable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Wrap-up&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This small login example shows how signal-based forms can simplify form handling in Angular:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Define a typed model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wrap it with form() and attach validation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bind fields with [field].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use signals directly in the template.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Convert to observables when you need RxJS power.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;

&lt;iframe src="https://stackblitz.com/edit/stackblitz-starters-uq2numei?embed=1&amp;amp;file=src%2Fmain.ts" width="100%" height="500"&gt;
&lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope you found it helpful. Thanks for reading!&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyenuri/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyenuri/"&gt;https://dev.to/nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyenuri/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>programming</category>
    </item>
    <item>
      <title>Modern Angular State Management with Signals and Dependency Injection</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Tue, 21 Oct 2025 07:11:13 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/modern-angular-state-management-with-signals-and-dependency-injection-391p</link>
      <guid>https://dev.to/nhannguyenuri/modern-angular-state-management-with-signals-and-dependency-injection-391p</guid>
      <description>&lt;p&gt;In this post, we’ll explore how to combine Angular’s Signals with Dependency Injection to create predictable, reactive, and reusable component state.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Signal&lt;/strong&gt; is a reactive value that notifies dependents when it changes.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt; &lt;span class="p"&gt;}&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;@angular/core&lt;/span&gt;&lt;span class="dl"&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&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;Managing State via Dependency Injection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a StateService that holds signals.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide it at the component or root level.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CounterState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&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;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&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="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;Scoped State with Component Providers&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-parrent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CounterState&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./parent.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ParentComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CounterState&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;Using the State in child Components&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-child&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;button (click)="state.increment()"&amp;gt;+&amp;lt;/button&amp;gt;
    &amp;lt;p&amp;gt;Count: {{ state.count() }}&amp;lt;/p&amp;gt;
  `&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChildComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CounterState&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;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep services pure and focused on state logic.&lt;/li&gt;
&lt;li&gt;Avoid too much global state.&lt;/li&gt;
&lt;li&gt;Use computed for derived state.&lt;/li&gt;
&lt;li&gt;Prefer DI scoping over manual signal creation in many components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A complete example is here&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;

&lt;iframe src="https://stackblitz.com/edit/stackblitz-starters-bzien9bf?embed=1&amp;amp;file=src%2Fmain.ts" width="100%" height="500"&gt;
&lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reactive updates with zero boilerplate&lt;/li&gt;
&lt;li&gt;Clean state isolation using DI&lt;/li&gt;
&lt;li&gt;Easier debugging and reasoning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Try integrating Signals in existing projects&lt;/li&gt;
&lt;li&gt;Explore &lt;strong&gt;computed()&lt;/strong&gt; and &lt;strong&gt;effect()&lt;/strong&gt; for advanced patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;I hope you found it helpful. Thanks for reading!&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyenuri/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyenuri/"&gt;https://dev.to/nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyenuri/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>angular</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Setup TailwindCSS v4 on Angular 19</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Wed, 19 Feb 2025 15:17:33 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/how-to-upgrade-tailwindcss-from-v3-to-v4-on-angular-19-with-scss-3bp4</link>
      <guid>https://dev.to/nhannguyenuri/how-to-upgrade-tailwindcss-from-v3-to-v4-on-angular-19-with-scss-3bp4</guid>
      <description>&lt;p&gt;&lt;strong&gt;TailwindCSS&lt;/strong&gt; is a powerful utility-first CSS framework that enhances styling efficiency in modern web development. If you're working with &lt;strong&gt;Angular 19&lt;/strong&gt; and using SCSS, here's a step-by-step guide to upgrading and configuring TailwindCSS properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Upgrade TailwindCSS
&lt;/h2&gt;

&lt;p&gt;Run the following command to upgrade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @tailwindcss/upgrade@next
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Install TailwindCSS and Required Dependencies
&lt;/h2&gt;

&lt;p&gt;Now, install TailwindCSS and its necessary dependencies using npm. Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;tailwindcss @tailwindcss/postcss postcss &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;--force&lt;/strong&gt; flag ensures that all required dependencies are installed correctly, even if there are existing conflicts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Add PostCSS Configuration
&lt;/h2&gt;

&lt;p&gt;Create a &lt;strong&gt;.postcssrc.json&lt;/strong&gt; file in the root directory of your project and add the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@tailwindcss/postcss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file ensures that PostCSS processes TailwindCSS correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Create the TailwindCSS Entry File
&lt;/h2&gt;

&lt;p&gt;Inside your &lt;strong&gt;src/&lt;/strong&gt; directory, create a new file called &lt;strong&gt;tailwind.css&lt;/strong&gt; and add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"tailwindcss"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file serves as the main entry point for TailwindCSS styles.&lt;/p&gt;

&lt;p&gt;Step 5: Update Your Global Styles File&lt;/p&gt;

&lt;p&gt;Modify your global &lt;strong&gt;src/styles.scss&lt;/strong&gt; file to include TailwindCSS by adding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s1"&gt;"./tailwind"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that SCSS processes TailwindCSS correctly and integrates it into your Angular project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Fix Tailwind IntelliSense in VS Code
&lt;/h2&gt;

&lt;p&gt;If you are using the &lt;strong&gt;TailwindCSS IntelliSense&lt;/strong&gt; extension in &lt;strong&gt;VS Code&lt;/strong&gt;, and it’s not auto-completing class names, following this setup can help resolve the issue.&lt;/p&gt;

&lt;p&gt;Adding Tailwind through &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt;&lt;/strong&gt; in SCSS rather than &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/import"&gt;@import&lt;/a&gt;&lt;/strong&gt; aligns better with Angular's SCSS handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Following these steps, you can successfully upgrade TailwindCSS in your Angular 19 project while maintaining SCSS styling. This approach not only improves maintainability but also ensures smooth integration with Angular’s SCSS-based architecture.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;




&lt;p&gt;I hope you found it helpful. Thanks for reading. 🙏&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyenuri/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyenuri/"&gt;https://dev.to/nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyenuri/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (formerly Twitter)&lt;/strong&gt;: &lt;a href="https://twitter.com/nhannguyenuri/" rel="noopener noreferrer"&gt;https://twitter.com/nhannguyenuri/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://www.buymeacoffee.com/nhannguyenuri" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/nhannguyenuri&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>angular</category>
    </item>
    <item>
      <title>Angular Dynamic Service Instantiation Using Injector</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Thu, 23 Jan 2025 07:04:59 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/angular-dynamic-service-instantiation-using-injector-2a22</link>
      <guid>https://dev.to/nhannguyenuri/angular-dynamic-service-instantiation-using-injector-2a22</guid>
      <description>&lt;p&gt;Dynamic service instantiation can be a powerful technique for creating flexible and scalable solutions in modern Angular applications. One use case is selecting a specific implementation of a service at runtime based on user input or application state. This post will explore how to achieve this using Angular's &lt;strong&gt;Injector&lt;/strong&gt; and provide a practical example of dynamically initializing payment services.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Imagine an application that supports multiple payment methods, such as &lt;strong&gt;PayPal&lt;/strong&gt;, &lt;strong&gt;Stripe&lt;/strong&gt;, and &lt;strong&gt;Venmo&lt;/strong&gt;. Each payment method has its own implementation but adheres to a common interface. Based on the user's selection, the appropriate service needs to be instantiated dynamically at runtime. Angular's &lt;strong&gt;Injector&lt;/strong&gt; provides a seamless way to accomplish this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example Setup
&lt;/h2&gt;

&lt;p&gt;Below is a sample implementation of dynamic service instantiation:&lt;/p&gt;

&lt;h3&gt;
  
  
  Service Definitions
&lt;/h3&gt;

&lt;p&gt;First, define a base class PaymentBaseService and create specific services for each payment method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&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;@angular/core&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentBaseService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;pay&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaypalService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PaymentBaseService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PaypalService!&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;override&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;()&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Paypal payment!&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StripeService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PaymentBaseService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StripeService!&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;override&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;()&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Stripe payment!&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VenmoService&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;PaymentBaseService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;VenmoService!&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;override&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;()&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Venmo payment!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Component Implementation
&lt;/h3&gt;

&lt;p&gt;Create a component where users can select a payment method and dynamically initialize the corresponding service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Injector&lt;/span&gt; &lt;span class="p"&gt;}&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;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FormsModule&lt;/span&gt; &lt;span class="p"&gt;}&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;@angular/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bootstrapApplication&lt;/span&gt; &lt;span class="p"&gt;}&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;@angular/platform-browser&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="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FormsModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;label for="payment"&amp;gt;Choose a payment method:&amp;lt;/label&amp;gt;
    &amp;lt;select name="payments" id='payments' [(ngModel)]="paymentMethod"&amp;gt;
      &amp;lt;option value=""&amp;gt;None&amp;lt;/option&amp;gt;
      &amp;lt;option value="paypal"&amp;gt;Paypal&amp;lt;/option&amp;gt;
      &amp;lt;option value="stripe"&amp;gt;Stripe&amp;lt;/option&amp;gt;
      &amp;lt;option value="venmo"&amp;gt;Venmo&amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;
    &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
    &amp;lt;button (click)="updatePaymentService()"&amp;gt;Submit&amp;lt;/button&amp;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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;injector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Injector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nl"&gt;paymentMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;paypal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stripe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;venmo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PaymentBaseService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;updatePaymentService&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch &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;paymentMethod&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;paypal&lt;/span&gt;&lt;span class="dl"&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;paymentService&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="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;injector&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="nx"&gt;PaypalService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stripe&lt;/span&gt;&lt;span class="dl"&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;paymentService&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="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;injector&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="nx"&gt;StripeService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;venmo&lt;/span&gt;&lt;span class="dl"&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;paymentService&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="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;injector&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="nx"&gt;VenmoService&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Unknown payment type: &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;paymentMethod&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paymentService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pay&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="nf"&gt;bootstrapApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Points
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Injector Usage&lt;/strong&gt;: The Injector fetches the appropriate service dynamically. This avoids directly injecting all possible services into the component, keeping the design clean and efficient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic Initialization&lt;/strong&gt;: The updatePaymentService method determines the selected payment type and initializes the corresponding service at runtime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;: The implementation includes a fallback for unknown payment types, ensuring robustness.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits of Using Injector
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: Adding a new payment method requires only defining a new service and updating the switch case in the component.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;: Services are instantiated only when needed, reducing memory usage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clean Design&lt;/strong&gt;: This approach adheres to the dependency inversion principle, ensuring a loosely coupled architecture.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Dynamic service instantiation using Angular's &lt;strong&gt;Injector&lt;/strong&gt; is a powerful feature for building flexible and scalable applications. Following the example outlined above, you can easily implement runtime-based service selection. This approach is especially useful in scenarios where the application's behavior depends on user input or dynamic configurations.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;




&lt;p&gt;I hope you found it helpful. Thanks for reading. 🙏&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyendevjs/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyendevjs/"&gt;https://dev.to/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (formerly Twitter)&lt;/strong&gt;: &lt;a href="https://twitter.com/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://twitter.com/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://www.buymeacoffee.com/nhannguyendevjs" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/nhannguyendevjs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Deploying Your Angular v19 Site to Vercel</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Tue, 21 Jan 2025 01:37:30 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/deploying-your-angular-v19-site-to-vercel-1e20</link>
      <guid>https://dev.to/nhannguyenuri/deploying-your-angular-v19-site-to-vercel-1e20</guid>
      <description>&lt;p&gt;&lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel's free hosting platform&lt;/a&gt; provides an easy way to host your website. This guide focuses on deploying a personal Angular v19 site using only a &lt;strong&gt;vercel.json&lt;/strong&gt; file for configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Prepare Your Angular Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start by ensuring your Angular project is production-ready:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run the following command to generate a production build:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng build &lt;span class="nt"&gt;--configuration&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The build will output files to the &lt;strong&gt;dist/&amp;lt;project-name&amp;gt;&lt;/strong&gt; directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Set Up a vercel.json File&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;vercel.json&lt;/strong&gt; file defines your Angular project's build and routing configurations. Create this file in the root of your project with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;version"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;builds"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;
    &lt;span class="pi"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;src"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;package.json"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;use"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@vercel/static-build"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;config"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;distDir"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dist/&amp;lt;project-name&amp;gt;/browser"&lt;/span&gt;
      &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;],&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;routes"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;
    &lt;span class="pi"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;src"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/(.*)"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dest"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/index.html"&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="pi"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;strong&gt;&lt;/strong&gt; with the name of your Angular project as it appears in the &lt;strong&gt;dist&lt;/strong&gt; directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Deploy Your Project&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Push your Angular project to a Git repository (e.g., GitHub, GitLab, or Bitbucket).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to Vercel's website and log in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new project and link it to your repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vercel will automatically detect and use the &lt;strong&gt;vercel.json&lt;/strong&gt; file for the deployment configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the deployment is complete, Vercel will provide a live URL for your application (e.g., &lt;strong&gt;&lt;a href="https://your-project.vercel.app" rel="noopener noreferrer"&gt;https://your-project.vercel.app&lt;/a&gt;&lt;/strong&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Sample Deployed Angular Site&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is an example of my Angular site deployed to Vercel: &lt;a href="//angularcrosstabchat.vercel.app"&gt;angularcrosstabchat.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use this as inspiration for your deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Handle Angular’s Routing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;vercel.json&lt;/strong&gt; file ensures that all unknown routes are redirected to index.html, making Angular’s client-side routing work seamlessly. This is achieved with the routes configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;routes"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;
  &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;src"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/(.*)"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dest"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/index.html"&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup ensures that your Angular Router handles the routing for all paths.&lt;/p&gt;

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

&lt;p&gt;Leveraging the &lt;strong&gt;vercel.json&lt;/strong&gt; file can simplify the deployment of your Angular v19 site to Vercel. This file handles build configurations and routing, ensuring a smooth deployment process. Once set up, your site will be live and ready to use with minimal effort!&lt;/p&gt;




&lt;p&gt;I hope you found it helpful. Thanks for reading. 🙏&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyendevjs/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyendevjs/"&gt;https://dev.to/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (formerly Twitter)&lt;/strong&gt;: &lt;a href="https://twitter.com/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://twitter.com/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://www.buymeacoffee.com/nhannguyendevjs" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/nhannguyendevjs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>angular</category>
      <category>vercel</category>
    </item>
    <item>
      <title>Exploring Vitest 3.0: The Future of Testing in JavaScript</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Mon, 20 Jan 2025 07:31:57 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/exploring-vitest-30-the-future-of-testing-in-javascript-2b9h</link>
      <guid>https://dev.to/nhannguyenuri/exploring-vitest-30-the-future-of-testing-in-javascript-2b9h</guid>
      <description>&lt;p&gt;With the rapid evolution of JavaScript testing frameworks, developers are always looking for tools that simplify workflows, enhance performance, and offer robust features. Enter Vitest 3.0, the latest version of the popular testing framework designed to redefine how developers approach testing in modern JavaScript applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Vitest?
&lt;/h2&gt;

&lt;p&gt;Vitest is a blazing-fast unit testing framework that seamlessly integrates with Vite, the modern build tool. Designed with speed and simplicity, Vitest leverages Vite's efficient bundling and hot module replacement (HMR) capabilities to deliver a testing experience that feels native to modern JavaScript development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features of Vitest 3.0
&lt;/h2&gt;

&lt;p&gt;Vitest 3.0 brings many new features and improvements that make it stand out in the crowded landscape of testing frameworks. Here are some of the highlights:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Enhanced Performance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Performance has always been a core strength of Vitest, and version 3.0 takes it to the next level. Leveraging Vite’s optimized caching mechanisms and improved dependency tracking, Vitest 3.0 ensures tests run faster, even in large-scale projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Native Support for TypeScript&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TypeScript is now a first-class citizen in Vitest 3.0. The framework offers out-of-the-box support for TypeScript, allowing developers to write tests in their preferred type-safe environment without additional configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Improved Watch Mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The new watch mode in Vitest 3.0 is smarter and more responsive. It can detect changes more accurately, ensuring only the relevant tests are re-executed. This significantly reduces development time when working on iterative updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Expanded Plugin Ecosystem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vitest 3.0 introduces a richer plugin ecosystem, enabling developers to extend the framework's functionality effortlessly. The possibilities are vast, from custom matches to integration plugins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Advanced Mocking Capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mocking dependencies has never been easier. Vitest 3.0 allows developers to mock modules dynamically with fine-grained control, making it ideal for testing complex applications with external integrations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Snapshot Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vitest 3.0 makes snapshot testing more powerful, with better tools for managing and updating snapshots. Developers can expect improved diffing capabilities and intuitive commands to maintain consistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Seamless CI/CD Integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vitest 3.0 recognizes the importance of continuous integration and has built-in support for popular CI/CD pipelines. Its lightweight nature ensures that test suites can run efficiently on cloud-based environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose Vitest 3.0?
&lt;/h2&gt;

&lt;p&gt;With its focus on performance, developer experience, and modern JavaScript features, Vitest 3.0 is well-positioned to become the go-to testing framework for projects using Vite. Here are some reasons to consider adopting it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speed:&lt;/strong&gt; By leveraging Vite’s efficient bundling, Vitest 3.0 runs lightning-speed tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicity:&lt;/strong&gt; Minimal configuration means you can get started quickly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; Vitest 3.0 supports everything, whether working with JavaScript, TypeScript, or JSX/TSX.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community:&lt;/strong&gt; Backed by an active community, there are numerous plugins, guides, and examples to help you.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started with Vitest 3.0
&lt;/h2&gt;

&lt;p&gt;Ready to dive in? Here’s how you can get started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Vitest:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;vitest &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add a test script to your package.json:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vitest"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Write your first test:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a file named &lt;strong&gt;example.test.js&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&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;vitest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Basic Test Suite&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;adds numbers correctly&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run your tests:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Vitest 3.0 is more than just a testing framework; it’s a step forward in creating faster, more reliable, and developer-friendly workflows. With its seamless integration with Vite and modern JavaScript features, Vitest 3.0 is poised to become an indispensable tool for developers in 2025 and beyond.&lt;/p&gt;

&lt;p&gt;Whether you’re building a new project or looking to upgrade your testing framework, Vitest 3.0 deserves a place in your toolkit. Try it today and experience the future of JavaScript testing firsthand.&lt;/p&gt;




&lt;p&gt;I hope you found it helpful. Thanks for reading. 🙏&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyendevjs/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyendevjs/"&gt;https://dev.to/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (formerly Twitter)&lt;/strong&gt;: &lt;a href="https://twitter.com/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://twitter.com/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://www.buymeacoffee.com/nhannguyendevjs" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/nhannguyendevjs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>testing</category>
      <category>vitest</category>
    </item>
    <item>
      <title>Applying GraphQL to Backend with Node.js and PostgreSQL</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Sun, 19 Jan 2025 01:30:43 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/applying-graphql-to-backend-with-nodejs-and-postgresql-eni</link>
      <guid>https://dev.to/nhannguyenuri/applying-graphql-to-backend-with-nodejs-and-postgresql-eni</guid>
      <description>&lt;h2&gt;
  
  
  What is GraphQL?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.graphql-js.org/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt; is a query language for APIs and a runtime for executing those queries by using a type system you define for your data. It provides a more flexible and efficient alternative to REST APIs by enabling clients to request only the data they need, making it ideal for modern applications.&lt;/p&gt;

&lt;p&gt;Key Features of GraphQL:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Single Endpoint:&lt;/strong&gt; Instead of multiple endpoints, GraphQL uses a single endpoint to handle all queries and mutations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Client-Defined Queries:&lt;/strong&gt; Clients can specify exactly what data they need, reducing over-fetching or under-fetching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Strongly Typed Schema:&lt;/strong&gt; GraphQL APIs are defined by a schema that describes the types of data and relationships between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Real-Time Data:&lt;/strong&gt; Supports subscriptions for real-time updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here’s how to build a GraphQL API with Node.js and PostgreSQL:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Set Up Your Project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialize a Node.js project:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;graphql-node-postgres
&lt;span class="nb"&gt;cd &lt;/span&gt;graphql-node-postgres
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install dependencies:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express graphql express-graphql pg prisma dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Configure PostgreSQL&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a PostgreSQL database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define your tables. Example SQL for a users table:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="nb"&gt;INT&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;3. Set Up Prisma (Optional for ORM)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialize Prisma:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx prisma init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Update the prisma/schema.prisma file to define your data model:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id    Int    @id @default(autoincrement())
  name  String
  email String @unique
  age   Int
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Migrate the schema to your database:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx prisma migrate dev &lt;span class="nt"&gt;--name&lt;/span&gt; init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Build the GraphQL Schema&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define the GraphQL schema using &lt;strong&gt;graphql&lt;/strong&gt; package:
&lt;/li&gt;
&lt;/ul&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GraphQLObjectType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GraphQLSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GraphQLString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GraphQLInt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GraphQLList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GraphQLNonNull&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;graphql&lt;/span&gt;&lt;span class="dl"&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;PrismaClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@prisma/client&lt;/span&gt;&lt;span class="dl"&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;prisma&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;PrismaClient&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;UserType&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;GraphQLObjectType&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GraphQLInt&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GraphQLString&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GraphQLString&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GraphQLInt&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RootQuery&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;GraphQLObjectType&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RootQueryType&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GraphQLList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserType&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;resolve&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&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;findMany&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GraphQLInt&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;resolve&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;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&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;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Mutation&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;GraphQLObjectType&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mutation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GraphQLNonNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GraphQLString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GraphQLNonNull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GraphQLString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GraphQLInt&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;resolve&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;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&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;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&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="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&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="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&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;schema&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;GraphQLSchema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RootQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Mutation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;schema&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;5. Set Up Express and GraphQL Middleware&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an &lt;strong&gt;index.js&lt;/strong&gt; file to run the server:
&lt;/li&gt;
&lt;/ul&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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&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;graphqlHTTP&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express-graphql&lt;/span&gt;&lt;span class="dl"&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;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./schema&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;graphqlHTTP&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;graphiql&lt;/span&gt;&lt;span class="p"&gt;:&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;// Enable GraphiQL for testing&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;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&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="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="s2"&gt;`Server running on http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/graphql`&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;6. Run the Server&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start the server:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Open &lt;strong&gt;&lt;a href="http://localhost:4000/graphql" rel="noopener noreferrer"&gt;http://localhost:4000/graphql&lt;/a&gt;&lt;/strong&gt; to test your GraphQL API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example GraphQL Queries
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fetch all users:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Fetch a user by ID:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;query&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a new user:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;I hope you found it helpful. Thanks for reading. 🙏&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyendevjs/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyendevjs/"&gt;https://dev.to/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (formerly Twitter)&lt;/strong&gt;: &lt;a href="https://twitter.com/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://twitter.com/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://www.buymeacoffee.com/nhannguyendevjs" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/nhannguyendevjs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>node</category>
      <category>postgres</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Setting Up PostgreSQL in Docker: A Step-by-Step Guide</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Sat, 18 Jan 2025 03:30:51 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/setting-up-postgresql-in-docker-a-step-by-step-guide-3gc4</link>
      <guid>https://dev.to/nhannguyenuri/setting-up-postgresql-in-docker-a-step-by-step-guide-3gc4</guid>
      <description>&lt;p&gt;PostgreSQL is a powerful, open-source object-relational database system. Running PostgreSQL in a Docker container is an efficient way to set up and manage your database. This guide will walk you through setting up PostgreSQL in Docker, from installation to configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin, ensure that you have the following installed on your system:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Docker:&lt;/strong&gt; You can download Docker from the official website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Docker Compose (optional but recommended):&lt;/strong&gt; This tool simplifies multi-container Docker setups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Basic knowledge of the command line.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Pull the PostgreSQL Docker Image
&lt;/h2&gt;

&lt;p&gt;To get started, pull the official PostgreSQL Docker image from Docker Hub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command fetches the latest PostgreSQL image. If you need a specific version, specify it, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull postgres:15.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Run the PostgreSQL Container
&lt;/h2&gt;

&lt;p&gt;Run a PostgreSQL container using the docker run command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; postgres-container &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;myuser &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mypassword &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mydatabase &lt;span class="nt"&gt;-p&lt;/span&gt; 5432:5432 &lt;span class="nt"&gt;-d&lt;/span&gt; postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a breakdown of the flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;--name postgres-container:&lt;/strong&gt; Names the container for easy reference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-e POSTGRES_USER=myuser:&lt;/strong&gt; Sets the PostgreSQL username.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-e POSTGRES_PASSWORD=mypassword:&lt;/strong&gt; Sets the PostgreSQL password.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-e POSTGRES_DB=mydatabase:&lt;/strong&gt; Creates a database named &lt;strong&gt;mydatabase&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-p 5432:5432:&lt;/strong&gt; Maps port &lt;strong&gt;5432&lt;/strong&gt; on your host to port &lt;strong&gt;5432&lt;/strong&gt; in the container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;-d postgres:&lt;/strong&gt; Runs the container in detached mode.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Verify the Setup
&lt;/h2&gt;

&lt;p&gt;To ensure the container is running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see your &lt;strong&gt;postgres-container&lt;/strong&gt; in the list of running containers.&lt;/p&gt;

&lt;p&gt;To connect to the database from your host machine, use a PostgreSQL client or a tool like &lt;strong&gt;psql&lt;/strong&gt;. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-U&lt;/span&gt; myuser &lt;span class="nt"&gt;-d&lt;/span&gt; mydatabase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be prompted for the password you set earlier (&lt;strong&gt;mypassword&lt;/strong&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Persisting Data
&lt;/h2&gt;

&lt;p&gt;By default, any data stored in the container will be lost if the container is removed. To persist data, you need to mount a volume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; postgres-container &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;myuser &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mypassword &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mydatabase &lt;span class="nt"&gt;-p&lt;/span&gt; 5432:5432 &lt;span class="nt"&gt;-v&lt;/span&gt; pgdata:/var/lib/postgresql/data &lt;span class="nt"&gt;-d&lt;/span&gt; postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;strong&gt;pgdata&lt;/strong&gt; is a Docker volume that stores your database data on your host system. You can verify the volume is created with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker volume &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Using Docker Compose (Optional)
&lt;/h2&gt;

&lt;p&gt;For more complex setups, such as defining multiple containers, use Docker Compose. Create a &lt;strong&gt;docker-compose.yml&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres-container&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myuser&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mypassword&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mydatabase&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5432:5432"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pgdata:/var/lib/postgresql/data&lt;/span&gt;
&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pgdata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the container with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Managing the PostgreSQL Container
&lt;/h2&gt;

&lt;p&gt;Here are some useful commands for managing your PostgreSQL container:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stop the container:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stop postgres-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start the container:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker start postgres-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Remove the container:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;rm &lt;/span&gt;postgres-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7: Security and Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use strong passwords:&lt;/strong&gt; Avoid default or weak passwords.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network isolation:&lt;/strong&gt; Use Docker networks to limit access to the database container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backups:&lt;/strong&gt; Regularly back up your database using tools like &lt;strong&gt;pg_dump&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Environment files:&lt;/strong&gt; Store sensitive information in .env files instead of hardcoding them in &lt;strong&gt;docker-compose.yml&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Running PostgreSQL in Docker simplifies setup and management, making it easier to integrate into your development workflow. By following this guide, you’ll have a PostgreSQL instance running in no time. With Docker's flexibility, you can scale and configure your database to suit your needs. Happy coding!&lt;/p&gt;




&lt;p&gt;I hope you found it helpful. Thanks for reading. 🙏&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyendevjs/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyendevjs/"&gt;https://dev.to/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (formerly Twitter)&lt;/strong&gt;: &lt;a href="https://twitter.com/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://twitter.com/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://www.buymeacoffee.com/nhannguyendevjs" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/nhannguyendevjs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>postgres</category>
      <category>docker</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why You Should Consider Moving from MongoDB to PostgreSQL</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Sat, 18 Jan 2025 03:17:12 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/why-you-should-consider-moving-from-mongodb-to-postgresql-1693</link>
      <guid>https://dev.to/nhannguyenuri/why-you-should-consider-moving-from-mongodb-to-postgresql-1693</guid>
      <description>&lt;p&gt;&lt;strong&gt;MongoDB&lt;/strong&gt; and &lt;strong&gt;PostgreSQL&lt;/strong&gt; are popular database systems with strengths and ideal use cases. However, as your application grows and your requirements evolve, you may find that PostgreSQL offers distinct advantages over MongoDB. In this blog, we’ll explore why transitioning to PostgreSQL might be the right decision for your business.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Robust Data Integrity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of PostgreSQL’s standout features is its adherence to the ACID (Atomicity, Consistency, Isolation, Durability) principles, ensuring robust data integrity. While MongoDB does support ACID transactions, its implementation is relatively new and may not match the maturity of PostgreSQL. This makes PostgreSQL a better choice for applications where data consistency and reliability are critical, such as financial systems or healthcare databases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Advanced Query Capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL’s SQL support is among the most advanced in the database world. It offers powerful features like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Window functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Common Table Expressions (CTEs)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Full-text search&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced indexing techniques (e.g., GIN, GiST, BRIN)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features allow for more complex queries and efficient data retrieval, giving PostgreSQL a significant edge for analytical workloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Schema Evolution and Enforced Constraints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL combines flexibility with structure by supporting dynamic JSON data and enforced schema constraints. While MongoDB’s schemaless design is great for quick prototyping, it can lead to inconsistent data if not carefully managed. PostgreSQL allows you to define schemas with constraints (e.g., foreign keys, unique constraints), ensuring data quality without sacrificing the ability to store unstructured data via JSONB columns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Performance at Scale&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL is well-optimized for both read and write operations. It handles complex joins and aggregations efficiently, making it ideal for transactional and analytical workloads. With features like parallel query execution and indexing improvements, PostgreSQL can outperform MongoDB in scenarios involving large datasets and complex queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Built-in Extensions and Ecosystem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL boasts an extensive ecosystem of extensions that enhance its functionality. Popular extensions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PostGIS&lt;/strong&gt;: Adds spatial and geographic data support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;pg_partman&lt;/strong&gt;: Facilitates efficient partitioning for large tables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TimescaleDB: Optimizes PostgreSQL for time-series data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These extensions allow PostgreSQL to adapt to specialized use cases, something MongoDB may require additional tooling or workarounds to achieve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Strong Community and Open-Source Credibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL has a long-standing reputation as a reliable and truly open-source database. Its vibrant community actively contributes to its development, ensuring continual innovation and stability. MongoDB’s open-source status has been questioned following its licensing changes (SSPL), which may concern businesses seeking fully open solutions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Cost Efficiency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For self-hosted deployments, PostgreSQL can often be more cost-effective than MongoDB. MongoDB’s architecture often leads to higher storage requirements due to data duplication in its document model. PostgreSQL’s relational model and advanced indexing options help reduce storage overhead and improve efficiency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Compliance and Security&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL provides advanced security features such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Role-based access control (RBAC)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Row-level security&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data encryption at rest and in transit&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features make it easier to comply with regulatory requirements like GDPR, HIPAA, and PCI-DSS. While MongoDB offers security features, PostgreSQL’s mature implementations and granular control options often make it the preferred choice for highly regulated industries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Evolving Beyond NoSQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MongoDB’s NoSQL design is a double-edged sword. While it’s great for certain use cases, the lack of enforced relationships can complicate application logic as the system grows. PostgreSQL’s hybrid capabilities—offering both relational and document-based storage—let you enjoy the best of both worlds without the pitfalls of an entirely schemaless system.&lt;/p&gt;

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

&lt;p&gt;While MongoDB has its merits, PostgreSQL’s versatility, performance, and adherence to standards make it a superior choice for many applications. If your use case demands robust data integrity, advanced querying, or specialized features, moving to PostgreSQL can significantly benefit your application’s scalability and maintainability.&lt;/p&gt;

&lt;p&gt;Transitioning from MongoDB to PostgreSQL might seem daunting, but the long-term benefits often outweigh the effort. With the right migration strategy and tools, you can leverage PostgreSQL’s full potential to future-proof your database infrastructure.&lt;/p&gt;

&lt;p&gt;If you’re considering a migration or want to learn more about how PostgreSQL can meet your needs, feel free to reach out or explore the extensive resources available within the PostgreSQL community.&lt;/p&gt;




&lt;p&gt;I hope you found it helpful. Thanks for reading. 🙏&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyendevjs/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyendevjs/"&gt;https://dev.to/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (formerly Twitter)&lt;/strong&gt;: &lt;a href="https://twitter.com/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://twitter.com/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://www.buymeacoffee.com/nhannguyendevjs" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/nhannguyendevjs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>postgres</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting Started with PostgreSQL: A Beginner's Guide</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Sat, 18 Jan 2025 03:01:41 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/getting-started-with-postgresql-a-beginners-guide-2dc2</link>
      <guid>https://dev.to/nhannguyenuri/getting-started-with-postgresql-a-beginners-guide-2dc2</guid>
      <description>&lt;p&gt;&lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt;, often referred to as Postgres, is one of the most popular open-source relational database management systems (RDBMS) worldwide. Known for its robustness, extensibility, and standards compliance, it’s an excellent choice for developers and businesses. This guide will help you set up and get started with PostgreSQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose PostgreSQL?
&lt;/h2&gt;

&lt;p&gt;Before diving into the technical setup, let’s explore why PostgreSQL might be the correct database for your needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open Source&lt;/strong&gt;: It’s free to use and has a vibrant community that continuously enhances its features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-Platform&lt;/strong&gt;: Runs on all major operating systems like Linux, Windows, and macOS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Feature-Rich&lt;/strong&gt;: Supports advanced features like JSON/JSONB, full-text search, and advanced indexing techniques.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Standards-Compliant&lt;/strong&gt;: Adheres to the SQL standard while offering additional functionalities.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installing PostgreSQL
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Installation on Linux&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ubuntu/Debian&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;postgresql postgresql-contrib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fedora/CentOS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;postgresql-server postgresql-contrib
&lt;span class="nb"&gt;sudo &lt;/span&gt;postgresql-setup &lt;span class="nt"&gt;--initdb&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start postgresql
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Installation on macOS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew update
brew &lt;span class="nb"&gt;install &lt;/span&gt;postgresql
brew services start PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Installation on Windows&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the installer from &lt;a href="https://www.postgresql.org/download/" rel="noopener noreferrer"&gt;PostgreSQL Downloads&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Run the installer and follow the wizard steps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Once PostgreSQL is installed, follow these steps to configure it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Access the PostgreSQL Command-Line Interface (CLI)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL ships with a powerful command-line tool called psql.&lt;/p&gt;

&lt;p&gt;To start &lt;strong&gt;psql&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres
psql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create a New User and Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To create a new user and database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;CREATE USER myuser WITH PASSWORD &lt;span class="s1"&gt;'mypassword'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
CREATE DATABASE mydb&lt;span class="p"&gt;;&lt;/span&gt;
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Connect to Your Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Exit &lt;strong&gt;psql&lt;/strong&gt; and reconnect using your new user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-U&lt;/span&gt; myuser &lt;span class="nt"&gt;-d&lt;/span&gt; mydb &lt;span class="nt"&gt;-W&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic Commands
&lt;/h2&gt;

&lt;p&gt;Here are some essential PostgreSQL commands to get you started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List all databases:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="se"&gt;\l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Switch to a database:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\c mydb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;List all tables:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="se"&gt;\d&lt;/span&gt;t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a table:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;CREATE TABLE &lt;span class="nb"&gt;users&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;id &lt;/span&gt;SERIAL PRIMARY KEY,
    name VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;100&lt;span class="o"&gt;)&lt;/span&gt;,
    email VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;100&lt;span class="o"&gt;)&lt;/span&gt; UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Insert data into a table:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;INSERT INTO &lt;span class="nb"&gt;users&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;name, email&lt;span class="o"&gt;)&lt;/span&gt; VALUES &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Alice'&lt;/span&gt;, &lt;span class="s1"&gt;'alice@example.com'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Retrieve data from a table:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SELECT &lt;span class="k"&gt;*&lt;/span&gt; FROM &lt;span class="nb"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using PostgreSQL with Applications
&lt;/h2&gt;

&lt;p&gt;PostgreSQL can be integrated with various programming languages and frameworks. Popular libraries include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;: Use &lt;strong&gt;psycopg2&lt;/strong&gt; or &lt;strong&gt;SQLAlchemy&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Node.js&lt;/strong&gt;: Use &lt;strong&gt;pg&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt;: Use &lt;strong&gt;JDBC&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ruby&lt;/strong&gt;: Use &lt;strong&gt;ActiveRecord&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, connecting to PostgreSQL in Python using &lt;strong&gt;psycopg2&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;

&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;dbname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mydb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;myuser&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mypassword&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;localhost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tips for Beginners
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use a GUI Tool&lt;/strong&gt;: Tools like pgAdmin, DBeaver, or DataGrip make it easier to visualize and manage your database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Read the Documentation&lt;/strong&gt;: PostgreSQL has extensive documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Practice SQL&lt;/strong&gt;: Familiarize yourself with SQL commands to get the most out of PostgreSQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backup Regularly&lt;/strong&gt;: Use pg_dump or pg_basebackup for backups.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;PostgreSQL is a powerful and versatile database system that can handle everything from small projects to enterprise-scale applications. This guide will give you a solid foundation for exploring its capabilities further. Happy coding!&lt;/p&gt;




&lt;p&gt;I hope you found it helpful. Thanks for reading. 🙏&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyendevjs/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyendevjs/"&gt;https://dev.to/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (formerly Twitter)&lt;/strong&gt;: &lt;a href="https://twitter.com/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://twitter.com/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://www.buymeacoffee.com/nhannguyendevjs" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/nhannguyendevjs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>database</category>
      <category>postgres</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting Started with Supabase</title>
      <dc:creator>Nhan Nguyen</dc:creator>
      <pubDate>Sat, 18 Jan 2025 02:01:44 +0000</pubDate>
      <link>https://dev.to/nhannguyenuri/getting-started-with-supabase-d1p</link>
      <guid>https://dev.to/nhannguyenuri/getting-started-with-supabase-d1p</guid>
      <description>&lt;p&gt;If you're new to building web or mobile applications and looking for an easy way to handle your backend, Supabase is a platform you’ll want to explore. Often called an "open-source Firebase alternative," Supabase offers a simple yet powerful suite of tools for database management, authentication, and real-time communication—without the need to build everything from scratch.&lt;/p&gt;

&lt;p&gt;This guide will explain the basics of Supabase and how to get started, even if you’re a beginner.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Supabase?
&lt;/h2&gt;

&lt;p&gt;Supabase is an open-source backend-as-a-service (BaaS) that provides developers with:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Database Management:&lt;/strong&gt; A PostgreSQL database that’s powerful and scalable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Authentication:&lt;/strong&gt; Easy-to-set-up user authentication with providers like Google, GitHub, and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Real-Time Features:&lt;/strong&gt; Listen to database changes in real-time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Storage:&lt;/strong&gt; Manage and serve files such as images and videos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Edge Functions:&lt;/strong&gt; Serverless functions for custom backend logic.&lt;/p&gt;

&lt;p&gt;The best part? Supabase is open-source, so you can self-host it if you want full control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose Supabase?
&lt;/h2&gt;

&lt;p&gt;Supabase stands out for a few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicity&lt;/strong&gt;: You don’t need extensive backend knowledge to get started.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open-Source&lt;/strong&gt;: Unlike proprietary platforms, you’re not locked into Supabase’s ecosystem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalable&lt;/strong&gt;: As your app grows, so does your backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community-Driven&lt;/strong&gt;: Being open-source means there's a vibrant community ready to help.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Get Started with Supabase
&lt;/h2&gt;

&lt;p&gt;Let’s break it down step-by-step:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a Supabase Account&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; and create a free account. Once you’re signed in, you’ll land on the dashboard where you can create your first project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Set Up Your Project&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Click on &lt;strong&gt;"New Project"&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter a name, select a region, and create a strong password for your database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once your project is ready, you’ll get access to a PostgreSQL database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Explore the Supabase Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The dashboard provides a user-friendly interface to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Manage your database tables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up authentication providers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create storage buckets for file management.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitor real-time logs and events.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Use Supabase Client in Your Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To connect your application to Supabase, you need the Supabase JavaScript client:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the client:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @supabase/supabase-js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initialize it in your project:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&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;@supabase/supabase-js&lt;/span&gt;&lt;span class="dl"&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;supabaseUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://your-project.supabase.co&lt;/span&gt;&lt;span class="dl"&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;supabaseKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-anon-key&lt;/span&gt;&lt;span class="dl"&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;supabase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;supabaseUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;supabaseKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use the client to interact with your backend:
&lt;/li&gt;
&lt;/ul&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="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;error&lt;/span&gt; &lt;span class="p"&gt;}&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;supabase&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_table_name&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="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&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;data&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;5. Add Authentication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Supabase makes it easy to add authentication to your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Enable providers (e.g., Google, GitHub) in the dashboard.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the Supabase client to sign users in:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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="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;error&lt;/span&gt; &lt;span class="p"&gt;}&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;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signInWithOAuth&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;google&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;ul&gt;
&lt;li&gt;Manage logged-in users with &lt;strong&gt;supabase.auth&lt;/strong&gt; methods.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Leverage Real-Time Features&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Want real-time updates in your app? Supabase has you covered:&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;mySubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_table_name&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="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INSERT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&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;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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New record:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;new&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="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// To unsubscribe:&lt;/span&gt;
&lt;span class="nx"&gt;mySubscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tips for Newbies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start Small&lt;/strong&gt;: Begin with a single feature, like authentication or a basic database query.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use the Docs&lt;/strong&gt;: Supabase’s documentation is beginner-friendly and packed with examples.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Experiment&lt;/strong&gt;: The free tier is generous—use it to experiment and learn.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Join the Community&lt;/strong&gt;: Connect with other developers on forums, Discord, or GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Supabase is an excellent choice for developers who want a quick, scalable, and easy-to-use backend. Whether you’re building a side project, launching a startup, or learning to code, Supabase simplifies the backend so you can focus on creating amazing applications.&lt;/p&gt;

&lt;p&gt;Ready to dive in? Head over to Supabase and start building today!&lt;/p&gt;




&lt;p&gt;I hope you found it helpful. Thanks for reading. 🙏&lt;br&gt;
Let's get connected! You can find me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Medium:&lt;/strong&gt; &lt;a href="https://medium.com/@nhannguyendevjs/" rel="noopener noreferrer"&gt;https://medium.com/@nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev&lt;/strong&gt;: &lt;a href="https://dev.to/nhannguyendevjs/"&gt;https://dev.to/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linkedin:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X (formerly Twitter)&lt;/strong&gt;: &lt;a href="https://twitter.com/nhannguyendevjs/" rel="noopener noreferrer"&gt;https://twitter.com/nhannguyendevjs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy Me a Coffee:&lt;/strong&gt; &lt;a href="https://www.buymeacoffee.com/nhannguyendevjs" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/nhannguyendevjs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
