<?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: Prasanna Vijayan</title>
    <description>The latest articles on DEV Community by Prasanna Vijayan (@prasannavijayan).</description>
    <link>https://dev.to/prasannavijayan</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%2F229792%2F80d11499-b7d8-444f-a7c4-d002f5a1c605.jpg</url>
      <title>DEV Community: Prasanna Vijayan</title>
      <link>https://dev.to/prasannavijayan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prasannavijayan"/>
    <language>en</language>
    <item>
      <title>The Container-Presenter Pattern in React: A Smart Approach to Component Design</title>
      <dc:creator>Prasanna Vijayan</dc:creator>
      <pubDate>Mon, 17 Mar 2025 14:04:55 +0000</pubDate>
      <link>https://dev.to/prasannavijayan/the-container-presenter-pattern-in-react-a-smart-approach-to-component-design-423m</link>
      <guid>https://dev.to/prasannavijayan/the-container-presenter-pattern-in-react-a-smart-approach-to-component-design-423m</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As front-end applications grow in complexity, maintaining a clean and scalable architecture becomes essential. One of the most effective design patterns to achieve this is the Container-Presenter Pattern, also known as the Smart-Dumb Components Pattern. This pattern helps separate business logic from UI rendering, making components more reusable, maintainable, and easier to test.&lt;/p&gt;

&lt;p&gt;In this blog, we'll explore the Container-Presenter Pattern, why it's beneficial, and how to implement it in React.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What is the Container-Presenter Pattern?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Container-Presenter Pattern is a design approach that splits components into two distinct types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Container Components (Smart Components): Responsible for state management, business logic, and API calls. They do not handle UI rendering.&lt;/li&gt;
&lt;li&gt;Presenter Components (Dumb Components): Focus purely on displaying UI and receiving data via props. They do not handle state or side effects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This pattern ensures that UI components remain pure and reusable, while logic-heavy components manage data efficiently.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why Use the Container-Presenter Pattern?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ Separation of Concerns&lt;br&gt;
Keeps UI and business logic separate, making the codebase cleaner and easier to maintain.&lt;/p&gt;

&lt;p&gt;✅ Reusability&lt;br&gt;
Presenter components are independent of state, so they can be reused across multiple parts of the application.&lt;/p&gt;

&lt;p&gt;✅ Better Testing&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Presenter components are easier to test as they are pure functions of their props.&lt;/li&gt;
&lt;li&gt;Containers can be tested separately for state management and API calls.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Scalability&lt;br&gt;
Makes it easier to scale large applications without cluttering UI components with logic.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Implementing the Container-Presenter Pattern in React&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's break down the pattern with a real-world example: Fetching and displaying a list of todo items.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 1: Create the Presenter (Dumb) Component&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This component only renders the list of todo items and receives data via props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";

const TodoList = ({ items }) =&amp;gt; {
  return (
    &amp;lt;ul&amp;gt;
      {items.map((item) =&amp;gt; (
        &amp;lt;li key={item.id}&amp;gt;{item.title}&amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;
  );
};

export default TodoList;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Step 2: Create the Container (Smart) Component&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This component fetches data and passes it down to the Presenter component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from "react";
import TodoList from "./TodoList";

const TodoListContainer = () =&amp;gt; {
  const [items, setItems] = useState([]);

  useEffect(() =&amp;gt; {
    fetch("https://api.json.com/checklist")
      .then((response) =&amp;gt; response.json())
      .then((data) =&amp;gt; setItems(data));
  }, []);

  return &amp;lt;TodoList items={items} /&amp;gt;;
};

export default TodoListContainer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Step 3: Use the Container Component in Your App&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import TodoListContainer from "./TodoListContainer";

const App = () =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Todo List&amp;lt;/h1&amp;gt;
      &amp;lt;TodoListContainer /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;When to Use the Container-Presenter Pattern?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;✔️ Good Use Cases:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When separating UI from business logic makes sense.&lt;/p&gt;

&lt;p&gt;When the UI component is used in multiple places.&lt;/p&gt;

&lt;p&gt;When you need better testability.&lt;/p&gt;

&lt;p&gt;When working on scalable applications.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;❌ When NOT to Use It:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When the component is small and simple (splitting adds unnecessary complexity).&lt;/p&gt;

&lt;p&gt;When using hooks-based state management that keeps logic within reusable hooks.&lt;/p&gt;

&lt;p&gt;When the framework already manages state elegantly (e.g., Vue’s reactivity system).&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Alternative Approaches&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Besides the Container-Presenter Pattern, here are some other useful patterns in React:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hooks-Based Pattern (Using useState, useEffect, and useReducer to manage logic separately).&lt;/li&gt;
&lt;li&gt;State Machines (XState) (For managing complex UI states).&lt;/li&gt;
&lt;li&gt;Context API / Redux (For global state management).&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Container-Presenter Pattern is a powerful way to separate concerns and keep your React components modular, testable, and maintainable. While it’s an excellent approach for larger applications, you should assess whether it adds value to your specific use case.&lt;/p&gt;

&lt;p&gt;By structuring your components with clear responsibilities, you ensure a scalable and maintainable front-end architecture.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>ui</category>
    </item>
    <item>
      <title>🚀 Building a Notification System in React Using the Pub-Sub Pattern</title>
      <dc:creator>Prasanna Vijayan</dc:creator>
      <pubDate>Sat, 15 Mar 2025 00:46:57 +0000</pubDate>
      <link>https://dev.to/prasannavijayan/building-a-notification-system-in-react-using-the-pub-sub-pattern-58jd</link>
      <guid>https://dev.to/prasannavijayan/building-a-notification-system-in-react-using-the-pub-sub-pattern-58jd</guid>
      <description>&lt;p&gt;Say Goodbye to Prop Drilling &amp;amp; Context! 🎉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
Every React app needs notifications—whether it's a success message, an error alert, or a warning toast. But how do we manage notifications globally without Redux, Context, or prop drilling?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The answer&lt;/strong&gt;: The Publish-Subscribe (Pub-Sub) Pattern!&lt;/p&gt;

&lt;p&gt;In this post, we'll build a notification system that:&lt;br&gt;
✅ Uses Pub-Sub instead of Context or Redux&lt;br&gt;
✅ Works globally without prop drilling&lt;br&gt;
✅ Automatically dismisses notifications&lt;br&gt;
✅ Stacks notifications on top of each other&lt;/p&gt;



&lt;p&gt;🧠 &lt;strong&gt;What is the Pub-Sub Pattern?&lt;/strong&gt;&lt;br&gt;
The Publish-Subscribe (Pub-Sub) Pattern is a messaging system where:&lt;/p&gt;

&lt;p&gt;Publishers send out events.&lt;br&gt;
Subscribers listen for those events and react accordingly.&lt;br&gt;
This makes it perfect for notifications because any part of the app can trigger an event, and the notification system will handle it automatically—without requiring direct dependencies!&lt;/p&gt;



&lt;p&gt;🛠️ &lt;strong&gt;Step 1: Create an Event Bus (Pub-Sub Utility)&lt;/strong&gt;&lt;br&gt;
Since JavaScript lacks a built-in Pub-Sub system, we'll create a lightweight event bus.&lt;/p&gt;

&lt;p&gt;🔹 Create a new file: eventBus.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const eventBus = {
  events: {},

  subscribe(eventName, callback) {
    if (!this.events[eventName]) {
      this.events[eventName] = [];
    }
    this.events[eventName].push(callback);

    // Return unsubscribe function
    return () =&amp;gt; {
      this.events[eventName] = this.events[eventName].filter(fn =&amp;gt; fn !== callback);
    };
  },

  publish(eventName, data) {
    if (this.events[eventName]) {
      this.events[eventName].forEach(callback =&amp;gt; callback(data));
    }
  }
};

export default eventBus;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔍 &lt;strong&gt;How This Works&lt;/strong&gt;:&lt;br&gt;
✅ subscribe(eventName, callback): Adds a listener for an event.&lt;br&gt;
✅ publish(eventName, data): Triggers all callbacks listening to an event.&lt;br&gt;
✅ Returns an unsubscribe function so we can clean up listeners when needed.&lt;/p&gt;



&lt;p&gt;📌 &lt;strong&gt;Step 2: Create the Notification List Component&lt;/strong&gt;&lt;br&gt;
The NotificationList will:&lt;br&gt;
✅ Listen for notify events from the eventBus&lt;br&gt;
✅ Store notifications in local state&lt;br&gt;
✅ Automatically remove notifications after 3 seconds&lt;/p&gt;

&lt;p&gt;🔹 Create a new file: NotificationList.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from "react";
import eventBus from "./eventBus";
import "./Notifications.css";

const NotificationList = () =&amp;gt; {
  const [notifications, setNotifications] = useState([]);

  useEffect(() =&amp;gt; {
    // Subscribe to "notify" event
    const unsubscribe = eventBus.subscribe("notify", (notification) =&amp;gt; {
      const id = Date.now();
      setNotifications((prev) =&amp;gt; [...prev, { id, ...notification }]);

      // Auto-remove notification after 3 seconds
      setTimeout(() =&amp;gt; {
        setNotifications((prev) =&amp;gt; prev.filter((n) =&amp;gt; n.id !== id));
      }, 3000);
    });

    return () =&amp;gt; unsubscribe(); // Cleanup on unmount
  }, []);

  return (
    &amp;lt;div className="notifications-container"&amp;gt;
      {notifications.map((notif) =&amp;gt; (
        &amp;lt;div key={notif.id} className={`notification ${notif.type}`}&amp;gt;
          {notif.message}
        &amp;lt;/div&amp;gt;
      ))}
    &amp;lt;/div&amp;gt;
  );
};

export default NotificationList;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🎨 &lt;strong&gt;Step 3: Add Some Styles for Notifications&lt;/strong&gt;&lt;br&gt;
🔹 Create a new file: Notifications.css&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.notifications-container {
  position: fixed;
  top: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 1000;
}

.notification {
  padding: 10px 15px;
  color: white;
  font-weight: bold;
  border-radius: 5px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  opacity: 0.9;
  animation: fade-in 0.3s ease-in-out;
}

.notification.success {
  background-color: green;
}

.notification.failure {
  background-color: red;
}

.notification.warning {
  background-color: orange;
}

@keyframes fade-in {
  from {
    transform: translateY(-10px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;⚡ &lt;strong&gt;Step 4: Use It in the App Component&lt;/strong&gt;&lt;br&gt;
Now, let's wire it all together by publishing notifications when buttons are clicked.&lt;/p&gt;

&lt;p&gt;🔹 Modify App.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import eventBus from "./eventBus";
import NotificationList from "./NotificationList";

const App = () =&amp;gt; {
  const notify = (type, message) =&amp;gt; {
    eventBus.publish("notify", { type, message });
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h2&amp;gt;Notification System (Pub-Sub Pattern)&amp;lt;/h2&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; notify("success", "Success!")}&amp;gt;Success&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; notify("failure", "Failure!")}&amp;gt;Failure&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; notify("warning", "Warning!")}&amp;gt;Warning&amp;lt;/button&amp;gt;

      &amp;lt;NotificationList /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;🎯 &lt;strong&gt;How Everything Works Together&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1️⃣ Click a button → eventBus.publish("notify", { type, message })&lt;br&gt;
2️⃣ NotificationList listens for "notify" events&lt;br&gt;
3️⃣ Notification appears in the UI&lt;br&gt;
4️⃣ After 3 seconds, the notification auto-disappears&lt;/p&gt;

&lt;p&gt;📝 &lt;strong&gt;Final Thoughts: Why Use Pub-Sub?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using Pub-Sub in React is powerful because:&lt;br&gt;
✅ No Context or Redux needed → Clean &amp;amp; lightweight&lt;br&gt;
✅ Fully decoupled → Components don’t need to know about each other&lt;br&gt;
✅ Scalable → Can be extended to support WebSockets, logging, and more&lt;/p&gt;

&lt;p&gt;🔥 &lt;strong&gt;Next Steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Want to take this further? Try adding:&lt;br&gt;
✅ A close button to manually remove notifications&lt;br&gt;
✅ Animated entry/exit effects&lt;br&gt;
✅ Persistent notifications that stay until dismissed&lt;/p&gt;

&lt;p&gt;🚀 Now go and implement this in your projects! Happy coding! 🎉&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>pubsub</category>
      <category>css</category>
    </item>
    <item>
      <title>A Step-by-Step Guide to Deploying Your App on Vercel</title>
      <dc:creator>Prasanna Vijayan</dc:creator>
      <pubDate>Sat, 19 Aug 2023 03:22:35 +0000</pubDate>
      <link>https://dev.to/prasannavijayan/a-step-by-step-guide-to-deploying-your-app-on-vercel-33l8</link>
      <guid>https://dev.to/prasannavijayan/a-step-by-step-guide-to-deploying-your-app-on-vercel-33l8</guid>
      <description>&lt;p&gt;In the fast-paced world of web development, deploying your application quickly and efficiently is crucial to getting your work into the hands of users. Vercel, a popular platform for deploying web applications, streamlines the deployment process and offers a seamless experience for developers. In this blog post, we'll walk you through the steps of deploying your app on Vercel, from setup to launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Choose Vercel for Deployment?
&lt;/h2&gt;

&lt;p&gt;Vercel, formerly known as ZEIT, is a cloud platform that specializes in serverless deployment for front-end applications. It's renowned for its simplicity, speed, and scalability. Here's why you might want to consider using Vercel for deploying your app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero Configuration:&lt;/strong&gt; Vercel's default configurations work well for most projects. You can get your app online with minimal setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automatic Deployments:&lt;/strong&gt; Connect your repository to Vercel, and it will automatically build and deploy your app whenever you push changes to your codebase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Serverless Architecture:&lt;/strong&gt; Vercel uses serverless functions, which means you don't have to manage server infrastructure. This leads to cost savings and easier scalability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Global CDN:&lt;/strong&gt; Vercel's content delivery network ensures that your app is served from the location nearest to your users, improving loading times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Preview Deployments:&lt;/strong&gt; Create preview deployments for every pull request, enabling you to test changes before merging them into the main branch.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, let's dive into the steps of deploying your app on Vercel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Sign Up for a Vercel Account
&lt;/h2&gt;

&lt;p&gt;If you haven't already, visit the Vercel website and sign up for an account. You can use your GitHub, GitLab, or Bitbucket account to authenticate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Install the Vercel CLI
&lt;/h2&gt;

&lt;p&gt;The Vercel Command Line Interface (CLI) helps you manage deployments from your terminal. Install it globally using npm or yarn:&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; &lt;span class="nt"&gt;-g&lt;/span&gt; vercel
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn global add vercel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Prepare Your App
&lt;/h2&gt;

&lt;p&gt;Ensure your app's directory structure and configuration are ready for deployment. This might involve setting up build scripts, ensuring your app runs correctly, and creating a Git repository if you haven't already.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Connect Your Repository
&lt;/h2&gt;

&lt;p&gt;Navigate to the Vercel dashboard and click "New Project." Select your Git repository from the list and grant Vercel the necessary permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Configure Deployment Settings
&lt;/h2&gt;

&lt;p&gt;Vercel will ask you for deployment settings. Choose the branch you want to deploy, set up your build command (e.g., &lt;code&gt;npm run build&lt;/code&gt;), and specify the output directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Review and Deploy
&lt;/h2&gt;

&lt;p&gt;Vercel will show you a summary of your deployment settings. Review them to make sure everything is correct, and then hit the "Deploy" button.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Celebrate!
&lt;/h2&gt;

&lt;p&gt;Your app is now deployed on Vercel! The deployment process might take a few moments. Once it's done, you'll receive a URL where you can access your live app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Domains:&lt;/strong&gt; If you want to use a custom domain for your app, Vercel makes it easy to set up and manage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Environment Variables:&lt;/strong&gt; Use Vercel's environment variable management to securely store sensitive data like API keys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scaling:&lt;/strong&gt; As your app gains traction, Vercel's automatic scaling ensures your application can handle increased traffic without manual intervention.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitoring:&lt;/strong&gt; Vercel provides analytics and monitoring tools to track the performance of your deployed app.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Deploying your app on Vercel is a straightforward process that empowers you to focus on building your application rather than managing deployment infrastructure. With its automatic deployments, serverless architecture, and global CDN, Vercel offers a powerful platform for getting your web app in front of users quickly and efficiently. Whether you're a seasoned developer or just starting out, Vercel's user-friendly interface and feature set make deploying web applications a breeze. So, what are you waiting for? Get your app online with Vercel and share your creation with the world!&lt;/p&gt;

</description>
      <category>vercel</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Demystifying Ember Serialization: A Comprehensive Guide</title>
      <dc:creator>Prasanna Vijayan</dc:creator>
      <pubDate>Sat, 19 Aug 2023 03:19:47 +0000</pubDate>
      <link>https://dev.to/prasannavijayan/demystifying-ember-serialization-a-comprehensive-guide-11ko</link>
      <guid>https://dev.to/prasannavijayan/demystifying-ember-serialization-a-comprehensive-guide-11ko</guid>
      <description>&lt;p&gt;Serialization lies at the heart of data communication in web applications. It's the process of converting complex data structures, such as objects and arrays, into a format that can be easily transmitted and reconstructed on the receiving end. In the context of Ember.js, a popular JavaScript framework for building ambitious web applications, serialization plays a crucial role in managing data flow between the frontend and backend. In this blog, we'll delve into the world of Ember serialization, exploring its importance, techniques, and best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Serialization Matters in Ember
&lt;/h2&gt;

&lt;p&gt;Modern web applications often require communication with servers to exchange data, whether it's fetching information for display or updating records in a database. Serialization is the bridge that allows developers to transmit data in a standardized format, making it possible to send and receive information seamlessly. Ember, with its convention-over-configuration approach, simplifies this process by providing built-in serialization and deserialization mechanisms.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ember Serializer
&lt;/h2&gt;

&lt;p&gt;At the core of Ember's serialization process is the serializer. A serializer is responsible for converting data between the application's internal representation and the format suitable for communication, typically JSON. Ember offers a range of serializers out of the box, such as &lt;code&gt;JSONSerializer&lt;/code&gt;, &lt;code&gt;JSONAPISerializer&lt;/code&gt;, and &lt;code&gt;RESTSerializer&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;JSONSerializer:&lt;/strong&gt; This is a basic serializer that serializes records into JSON format. It's suitable for simple applications that don't require complex relationships between models.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;JSONAPISerializer:&lt;/strong&gt; If your application follows the JSON API specification, this serializer is the go-to choice. It handles complex relationships and follows the JSON API conventions for data structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;RESTSerializer:&lt;/strong&gt; This serializer is used when your API doesn't strictly adhere to the JSON API specification. It offers more customization options compared to the JSONAPISerializer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Serialization in Action
&lt;/h2&gt;

&lt;p&gt;Let's walk through a basic example of serialization using Ember's &lt;code&gt;JSONSerializer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Assume you have a &lt;code&gt;post&lt;/code&gt; model with the following attributes: &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;body&lt;/code&gt;, and &lt;code&gt;createdAt&lt;/code&gt;. To serialize a &lt;code&gt;post&lt;/code&gt; record, you would do the following:&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="nx"&gt;JSONSerializer&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;@ember-data/serializer/json&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="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostSerializer&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JSONSerializer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Customize the serialized format&lt;/span&gt;
  &lt;span class="nf"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&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;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// You can modify the serialized JSON here&lt;/span&gt;
    &lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;published&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;json&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;In this example, the &lt;code&gt;serialize&lt;/code&gt; method is overridden to modify the serialized JSON before it's sent to the server. This customization can be immensely useful when you need to add extra metadata or transform data before transmission.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choose the Right Serializer:&lt;/strong&gt; Select a serializer that matches your API's data format and requirements. If your API follows the JSON API standard, using &lt;code&gt;JSONAPISerializer&lt;/code&gt; is a wise choice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid Over-serialization:&lt;/strong&gt; Sending unnecessary data over the network can lead to performance bottlenecks. Serialize only the data needed for a particular operation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customization when Necessary:&lt;/strong&gt; If your serialization needs go beyond the basics, don't hesitate to create custom serializers. This allows you to fine-tune the serialized data to fit your application's needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Versioning and Compatibility:&lt;/strong&gt; Keep an eye on API versioning and compatibility issues. Changes in serialization format can break frontend-backend communication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testing:&lt;/strong&gt; Write tests for your serializers to ensure that they handle various scenarios correctly. Ember provides testing utilities to make this process easier.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Ember serialization is a fundamental aspect of modern web application development. It empowers developers to seamlessly communicate with servers, retrieve data, and update records. By leveraging Ember's built-in serializers and adhering to best practices, developers can ensure efficient, reliable, and secure data transmission in their applications. Understanding the nuances of serialization is key to mastering Ember and building robust, high-performance web applications.&lt;/p&gt;

</description>
      <category>ember</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How did I learn this.reduce();</title>
      <dc:creator>Prasanna Vijayan</dc:creator>
      <pubDate>Sun, 15 Sep 2019 12:38:42 +0000</pubDate>
      <link>https://dev.to/prasannavijayan/how-did-i-learn-this-reduce-1ac6</link>
      <guid>https://dev.to/prasannavijayan/how-did-i-learn-this-reduce-1ac6</guid>
      <description>&lt;p&gt;Javascript is so amazing to learn. I learn few things on the fly to fix some error or try {} catch way (basically fail and understand better). One among them is &lt;code&gt;this.reduce();&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;this.reduce()&lt;/code&gt; takes array and gives back single value. Let's take an example&lt;/p&gt;

&lt;p&gt;Before going further to understand about reduce, let's take a look at it's arguments. Reduce takes 4 arguments.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;total //!req a + b, it returns either initial value or summed value&lt;/li&gt;
&lt;li&gt;currentValue //!req value of the current element&lt;/li&gt;
&lt;li&gt;currentIndex //!opt&lt;/li&gt;
&lt;li&gt;arr //!opt array&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example with just number of arrays&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;let&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&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;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 21&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Example with objects&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;let&lt;/span&gt; &lt;span class="nx"&gt;movies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cars&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;part&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;views&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;400&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cars&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;part&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;views&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;300&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cars&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;part&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;views&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Planes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;part&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;views&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;800&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Planes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;part&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;views&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;500&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}];&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cars&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="na"&gt;planes&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;totalviewsmovies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;movies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;total&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;views&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;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;total&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { cars: 400, planes: 1300 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, there might be a question? How this is hard for you?. &lt;/p&gt;

&lt;p&gt;Answer: I didn't know this much detail of arguments and how it works until I recently got interviewed in some company.&lt;/p&gt;

&lt;p&gt;Thanks to him!&lt;/p&gt;

&lt;p&gt;Let me know what you think.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Use Promise for popup</title>
      <dc:creator>Prasanna Vijayan</dc:creator>
      <pubDate>Sun, 15 Sep 2019 07:39:27 +0000</pubDate>
      <link>https://dev.to/prasannavijayan/use-promise-for-popup-6m2</link>
      <guid>https://dev.to/prasannavijayan/use-promise-for-popup-6m2</guid>
      <description>&lt;p&gt;There are lot of things you can do with Promise. Today, I will share my experience on using promise for modal which I recently learned.&lt;/p&gt;

&lt;p&gt;If you don't know much about EmberJs or Promise. Please visit &lt;a href="http://emberjs.com" rel="noopener noreferrer"&gt;EmberJS&lt;/a&gt; and &lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" rel="noopener noreferrer"&gt;Promise&lt;/a&gt;) to get your basics up&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Promise?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261" rel="noopener noreferrer"&gt;https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ember &lt;span class="nb"&gt;install &lt;/span&gt;ember-bootstrap
ember generate ember-bootstrap &lt;span class="nt"&gt;--preprocessor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to use less instead of sass use &lt;code&gt;--preprocesor=less&lt;/code&gt;. For other config, please check &lt;a href="https://www.ember-bootstrap.com/#/getting-started/setup" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Steps
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Create your component using
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ember generate component promise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;ol&gt;
&lt;li&gt;promise.js
&lt;/li&gt;
&lt;/ol&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="nx"&gt;Component&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;@ember/component&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="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

  &lt;span class="c1"&gt;// It's important to have response undefined instead of boolean&lt;/span&gt;
  &lt;span class="na"&gt;response&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;show&lt;/span&gt;     &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;promiseClicked&lt;/span&gt;&lt;span class="p"&gt;()&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;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;respond&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;this&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;show&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;observer&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="nf"&gt;removeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nf"&gt;respond&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;proceed&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;proceed&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="nx"&gt;proceed&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;proceed&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="nf"&gt;setProperties&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;show&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;bool&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="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bool&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;Make sure variable response is set to undefined after removing observer.&lt;/p&gt;



&lt;ol&gt;
&lt;li&gt;promise.hbs
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BsButton&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;promiseClicked&lt;/span&gt;&lt;span class="dl"&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="nb"&gt;Promise&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/BsButton&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BsModal&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;open&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;show&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response&lt;/span&gt;&lt;span class="dl"&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="nd"&gt;onHidden&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h4&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;modal-title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Custom&lt;/span&gt; &lt;span class="nx"&gt;Dialog&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;badge&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h4&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/modal.header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;Promise&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
    &lt;span class="nx"&gt;Check&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt; &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;click&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cancel or Save&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/modal.body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;modal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;footer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BsButton&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Cancel&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/BsButton&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BsButton&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Save&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/BsButton&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/modal.footer&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/BsModal&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Thanks!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
