<?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: Saheedat</title>
    <description>The latest articles on DEV Community by Saheedat (@saheedat).</description>
    <link>https://dev.to/saheedat</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%2F1494006%2Fd8808b7b-d14a-4dbf-985a-77f3402bfe96.jpg</url>
      <title>DEV Community: Saheedat</title>
      <link>https://dev.to/saheedat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saheedat"/>
    <language>en</language>
    <item>
      <title>A Beginner's Guide to Using Mirage.js in a React TypeScript Smart Home Dashboard.</title>
      <dc:creator>Saheedat</dc:creator>
      <pubDate>Wed, 30 Oct 2024 10:44:57 +0000</pubDate>
      <link>https://dev.to/saheedat/a-beginners-guide-to-using-miragejs-in-a-react-typescript-smart-home-dashboard-4odj</link>
      <guid>https://dev.to/saheedat/a-beginners-guide-to-using-miragejs-in-a-react-typescript-smart-home-dashboard-4odj</guid>
      <description>&lt;p&gt;Hi everyone! I hit a wall while I was building the &lt;a href="https://dev.to/saheedat/episode-1-introduction-1k8o"&gt;smart home dashboard&lt;/a&gt;, but I’m here now. Consistency is hard sometimes, but I guess what matters is showing up when it is needed.&lt;/p&gt;

&lt;p&gt;The smart home dashboard system is complex and involves various devices that communicate through APIs. Step 4 in my roadmap to build the dashboard involves creating mock data to create certain functionalities for the app pending the time I find an actual API to use for it. &lt;/p&gt;

&lt;p&gt;This is where Mirage.js comes in, offering a solution to mock backend services and simulate real-world data. Basically, it is helping me to build and test the frontend when the backend isn’t available. In this article, we will look at how to use Mirage.js to create a mock API for the smart home dashboard. &lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Mirage.js and Why Do We Use It?
&lt;/h2&gt;

&lt;p&gt;Mirage.js is a library that creates a mock server right in your browser. It can be thought of as a temporary stand-in for your real backend server. It's particularly useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Your backend API isn't ready yet&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want to prototype features quickly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need to test how your frontend handles different API responses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You're working offline&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my smart home dashboard, I needed to test different devices (lights, humidifiers, speakers, air conditioners etc) and how they would interact with the interface before connecting to real IoT devices' API. Here’s how I did it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Mirage.js
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;STEP 1:&lt;/strong&gt; Install Mirage.js&lt;br&gt;
First, you need to install mirage.js in your React TypeScript project.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install –save-dev miragejs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 2:&lt;/strong&gt; Create the basic server&lt;br&gt;
Create a new file, and name it &lt;code&gt;mirage.ts&lt;/code&gt; in your src directory. This is what the basic structure looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import { createServer } from "miragejs";

export function makeServer({ environment = "development" } = {}) {
  return createServer({
    environment,

    models: {
      // We'll define our data models here
    },

    seeds(server) {
      // We'll add sample data here
    },

    routes() {
      // We'll define API endpoints here
    },
  });
}

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

&lt;/div&gt;



&lt;p&gt;At this point, you need to have decided on the appliances that you want to mock and their properties such as &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;room&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;For this project, some of the appliances to be used include light, humidifier, speaker, appliances (e.g TV, AC, heater).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 3:&lt;/strong&gt; Define typescript interfaces&lt;br&gt;
Before we create our mock data, we have to define the types for our smart home devices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Light {
  id: number;
  room: string;
  status: "on" | "off";
  brightness: number;
  color: string;
  schedule: string | null;
}

interface Humidifier {
  id: number;
  room: string;
  status: "on" | "off";
  schedule: string | null;
  energyEfficiency: boolean;
}

interface Appliance {
  id: number;
  type: "TV" | "Heater" | "AC";
  room: string;
  status: "on" | "off";
}
interface Speaker = {
  id: number;
  room: string;
  status: "playing" | "off";
  volume: number;
  energy: number;
};

interface AppSchema {
  light: Light;
  humidifier: Humidifier;
  appliance: Appliance;
  Speaker: Speaker
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;STEP 4:&lt;/strong&gt; Set up models and seed data&lt;br&gt;
Here, you get to create our mock server with sample data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createServer, Model, Server } from "miragejs";
import Schema from "miragejs/orm/schema";

export function makeServer({ environment = "development" } = {}): Server {
  return createServer({
    environment,

models: {
 light: Model.extend&amp;lt;Partial&amp;lt;Light&amp;gt;&amp;gt;({}),
 humidifier: Model.extend&amp;lt;Partial&amp;lt;Humidifier&amp;gt;&amp;gt;({}),
 appliances: Model.extend&amp;lt;Partial&amp;lt;Appliance&amp;gt;&amp;gt;({}),
 speaker: Model.extend&amp;lt;Partial&amp;lt;Speaker&amp;gt;&amp;gt;({}),
}

seeds(server){
//we are creating sample appliances
server.create("appliance", {
        id: 1,
        type: "TV",
        room: "Living Room",
        status: "off"
      });
      server.create("appliance", {
        id: 2,
        type: "Heater",
        room: "Bathroom",
        status: "off",
      });
      server.create("appliance", {
        id: 3,
        type: "Air Conditioner",
        room: "Bedroom",
        status: "on",
      });
//creating sample light
      server.create("light", {
        id: 1,
        room: "Living Room",
        status: "off",
        brightness: 50,
        color: "white",
        schedule: null,
      });

//creating sample humidifier

      server.create("humidifier", {
        id: 1,
        room: "Bathroom",
        status: "on",
        schedule: "7:00 AM",
        energyEfficiency: true,
      });
},

routes(){
this.namespace = “api”;

//the GET endpoints
    this.get("/lights", (schema: Schema&amp;lt;AppSchema&amp;gt;) =&amp;gt; schema.all("light"));
        this.get("/humidifiers", (schema: Schema&amp;lt;AppSchema&amp;gt;) =&amp;gt; schema.all("humidifier"));

        this.get("/appliances", (schema: Schema&amp;lt;AppSchema&amp;gt;) =&amp;gt; schema.all("appliance"));
        this.get("/speakers", (schema: Schema&amp;lt;AppSchema&amp;gt;) =&amp;gt; schema.all("speaker"));

//POST endpoints for toggling devices.
//In our dashboard, users can toggle some of the devices on and off

        this.post("/lights/:id/toggle", (schema: Schema&amp;lt;AppSchema&amp;gt;, request) =&amp;gt; {
        const id = request.params.id;
        const light = schema.find("light", id);

        if (light) {
          const newStatus = light.status === "on" ? "off" : "on";
          return light.update({ status: newStatus });
        }
        return null;
      });
             },
     } );
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;STEP 5:&lt;/strong&gt; Starting the mirage server&lt;br&gt;
To ensure that the server runs when the application is launched, you need to initialize Mirage.js in the main entry file i.e App.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {makeServer} from “./components/api/Mirage”;

if(import.meta.env.MODE === “development”){
makeServer();
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;STEP 6:&lt;/strong&gt; Using the Mock API in Components&lt;br&gt;
With Mirage.js set up, we can now fetch data in the frontend just as you would with a real API.&lt;/p&gt;

&lt;p&gt;Now, you can use your mock API in one of your components like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from 'react';
import { Light} from “./components/api/Mirage”;

interface Light {
  id: number;
  room: string;
  status: "on" | "off";
  brightness: number;
  color: string;
  schedule: string | null;
}

export const LightControls = () =&amp;gt; {
  const [lights, setLights] = useState&amp;lt;Light[]&amp;gt;([]);

  useEffect(() =&amp;gt; {
    fetch('/api/lights')
      .then(res =&amp;gt; res.json())
      .then(data =&amp;gt; setLights(data.lights));
  }, []);


  const toggleLight = async (id: string) =&amp;gt; {
    const response = await fetch(`/api/lights/${id}/toggle`, {
      method: 'POST',
    });
    const updatedLight = await response.json();

    setLights(prevLights =&amp;gt; 
      prevLights.map(light =&amp;gt; 
        light.id === id ? updatedLight : light
      )
    );
  };

  return (
    &amp;lt;div className="grid gap-4 grid-cols-2 md:grid-cols-3"&amp;gt;
      {lights.map(light =&amp;gt; (
        &amp;lt;div key={light.id} className="p-4 border rounded-lg"&amp;gt;
          &amp;lt;h3&amp;gt;{light.room} Light&amp;lt;/h3&amp;gt;
          &amp;lt;p&amp;gt;Status: {light.status}&amp;lt;/p&amp;gt;
          &amp;lt;button
            onClick={() =&amp;gt; toggleLight(light.id)}
            className="mt-2 px-4 py-2 bg-blue-500 text-white rounded"
          &amp;gt;
            Switch
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      ))}
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extra Tips
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Make sure your namespace in routes matches your API calls. It took me a while to figure that our because I forgot the &lt;code&gt;/api&lt;/code&gt; prefix.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create seed data that resembles your real data as much as possible. It will make transitioning to the real API smoother.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start with the simplest functionality, then add complex ones gradually.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;&lt;strong&gt;Mirage.js&lt;/strong&gt; allowed me to build and test the frontend independently of the backend, speeding up the development process. In this smart home dashboard project, I used it to mock appliance data, allowing me to build out the device control interface without relying on a live backend API. This not only speeds up development but also ensures a smoother transition when the real API becomes available.&lt;/p&gt;

&lt;p&gt;The next step in this project is to implement user authentication in the app. &lt;/p&gt;

&lt;p&gt;See you soon!&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://miragejs.com/tutorial/intro/" rel="noopener noreferrer"&gt;Mirage.js official documentation.&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>tutorial</category>
      <category>webdev</category>
      <category>learning</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Episode 1: Introduction</title>
      <dc:creator>Saheedat</dc:creator>
      <pubDate>Wed, 09 Oct 2024 18:11:32 +0000</pubDate>
      <link>https://dev.to/saheedat/episode-1-introduction-1k8o</link>
      <guid>https://dev.to/saheedat/episode-1-introduction-1k8o</guid>
      <description>&lt;p&gt;Hi everyone! I've been stuck looking for a dramatic opening for this piece, but I never seem to come up with a good one, so here goes nothing. This is a long-overdue introduction.&lt;/p&gt;

&lt;p&gt;My name is Saheedat Afolabi. I’m a physiotherapy student and a recent graduate of AltSchool Africa’s school of engineering (Front End Engineering).&lt;/p&gt;

&lt;p&gt;I have days when things make a lot of sense to me, and I make as much progress as I want, and there are days when I just sit and stare at my screen, overwhelmed by how much doesn't make sense. No in-betweens.&lt;/p&gt;

&lt;p&gt;Last week, I received a ridiculous message at 3 a.m., and it had me reassessing where I was as a developer. I decided that the only way to get better and prove that I knew what I did and more was to work on a few solid projects. &lt;/p&gt;

&lt;p&gt;For my first choice, I chose a Smart Home Dashboard. I'm realizing now that although it looked simple at first glance, it's a pretty ambitious project. &lt;/p&gt;

&lt;p&gt;Anyways, here goes something. &lt;/p&gt;

&lt;p&gt;Imagine having all your home controls in the same place. Lights? Security? Temperature? Irrigation? All in one place. A Smart Home Dashboard controls and monitors smart devices in a home. With it, you can control almost anything in your home from your phone or other devices. &lt;/p&gt;

&lt;p&gt;It is similar to the central nervous system, in that instead of having multiple apps handling different smart appliances in a home, the Smart Home Dashboard acts as a sole controller of everything. Think simplified control and a personalized experience. &lt;/p&gt;

&lt;p&gt;The first time I spoke to a senior developer, he told me to make sure I have an app that solves a real world problem. I guess you can see why I chose this project.&lt;/p&gt;

&lt;p&gt;I set out to build this project in a way that will challenge me to solve problems by myself. It is designed to have me think of multiple ways to solve a problem, rely heavily on what I learned while in AltSchool, read as many helpful technical articles as possible, and reach out to people for help. I imagine it's going to be a fun(and mostly frustrating) ride.&lt;/p&gt;

&lt;p&gt;For this project, I’m working with React, TypeScript and Tailwind CSS. I chose React because I want to try working with React and TypeScript for the first time. Tailwind CSS was my framework of choice because I really like it, and it allows for quick development with a utility-first approach, so that’s a plus.&lt;/p&gt;

&lt;p&gt;On the backend, the dashboard integrates with IoT devices through APIs, ensuring smooth communication between the interface and the devices it controls. I plan to make use of dummy data before I integrate with IoT.&lt;/p&gt;

&lt;p&gt;Additionally, I will be using Polypane during the process of development. Polypane is a development tool that is specifically designed to help web developers test their websites across multiple devices and screen sizes.&lt;/p&gt;

&lt;p&gt;The goal of this project is to improve my problem solving skills, understand how to build scalable and responsive applications, and maybe work on connecting with more people. &lt;/p&gt;

&lt;p&gt;One of the things I keep hearing over and again is “Building in public is very important”, and now I'm going to attempt to do that by documenting my process, progress and challenges faced while building this project. I’m hoping this also helps me improve my technical writing skills. &lt;/p&gt;

&lt;p&gt;I'll appreciate helpful feedback and ideas as I work on this project. &lt;/p&gt;

&lt;p&gt;Expect an update every week! &lt;/p&gt;

</description>
      <category>typescript</category>
      <category>learning</category>
      <category>frontend</category>
      <category>react</category>
    </item>
  </channel>
</rss>
