<?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: Miriamfark</title>
    <description>The latest articles on DEV Community by Miriamfark (@miriamfark).</description>
    <link>https://dev.to/miriamfark</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%2F782727%2F0567a530-1214-4c99-93ac-235f7705d46e.png</url>
      <title>DEV Community: Miriamfark</title>
      <link>https://dev.to/miriamfark</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/miriamfark"/>
    <language>en</language>
    <item>
      <title>Display Backend Errors to the Frontend</title>
      <dc:creator>Miriamfark</dc:creator>
      <pubDate>Fri, 17 Mar 2023 03:28:25 +0000</pubDate>
      <link>https://dev.to/miriamfark/display-backend-errors-to-the-frontend-4hoa</link>
      <guid>https://dev.to/miriamfark/display-backend-errors-to-the-frontend-4hoa</guid>
      <description>&lt;p&gt;Errors are awesome. Errors tell you that something needs to be fixed. If one would not have the error, it would be very frustrating as things would not work and we would not know why. The more specific an error is, the more helpful it is. The best errors are the ones that tell you what is wrong and what you can do to fix it.&lt;/p&gt;

&lt;p&gt;When users sign up for an account, or fill out a form on an app, there are (hopefully) validations being checked before a new instance is added to the database. If the data being submitted is not valid, the best case scenario would be for a very specific error message to show up on the screen and direct the user in what to do to submit their information correctly. In this post we will describe how to grab an error from a rails backend and conditionally display it on a react frontend.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Validations in the Model
&lt;/h2&gt;

&lt;p&gt;For each model that you create, you can specify what validations are necessary. To do this you would use &lt;a href="https://guides.rubyonrails.org/active_record_validations.html"&gt;Active Record validation methods&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In the example below, a user signs up for an account and creates a new user instance. These validations check that&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;there is a username&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the username is unique&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;there is a password&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;there is an email address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the email address fits the criteria of a valid email address&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User &amp;lt; ApplicationRecord
    validates :name, uniqueness: true
    validates :password, presence: true
    validates :email, presence: true, format: /\w+@\w+\.{1}[a-zA-Z]{2,}/
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any of these requirements are not met, the user will not be able to sign up. At the same time an error is being generated based on these validations. Now, how will the user see the error and know where they went wrong?&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Controller Error Handling
&lt;/h2&gt;

&lt;p&gt;The next step takes place in the controller. In the User Controller, there is a create method that handles adding a new user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def create
        user = User.create!(user_params)
        session[:user_id] = user.id
        render json: user, status: :created
    rescue ActiveRecord::RecordInvalid =&amp;gt; e
        render json: { errors: e.record.errors.full_messages }, status: :unprocessable_entity
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, it is necessary to use the .create! method, as the bang operator (!) will throw an error if saving fails due to the data not passing the validations. If that is the case, we will render a json object that displays an array of error messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "errors": [
        "Name has already been taken",
        "Email is invalid"
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Save the Error to React State on the Frontend
&lt;/h2&gt;

&lt;p&gt;Now is when we can finally send the error to the frontend. The best way to capture the value of the error is to save it to state. State should initially be set as false, as no errors actually exist on the page load.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const [errors, setErrors] = useState(false)&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Then comes the submit form function. Within the submit is a post request to the backend, sending the new user object to be validated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleSubmit(e) {
        e.preventDefault()
        const user = {
            name,
            password,
            passwordConfirmation,
            email
        }
        fetch('/signup', {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(user)
    })
    .then((r) =&amp;gt; {
        if(!r.ok) {
            return r.json().then((e) =&amp;gt; setErrors(Object.values(e).toString()))
        } else {
            return r.json().then((data) =&amp;gt; dispatch(signupUser(data)))
        }
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need two different ways to handle the response, based on wether or not the post request was successful. If the information was successfully saved, then the user information is sent to my redux store to be processed. If not, we need to set the errors in state to the error values of the json object. I converted the array into a string so it would not have to be mapped before displaying.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Display the Error
&lt;/h2&gt;

&lt;p&gt;Finally! The error is saved in a string format in state. Now all that is needed to display the error to the user is a simple ternary expression. If there is an error, display the error. If not, don't.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ errors ? &amp;lt;h5 class="text-danger"&amp;gt;{errors}&amp;lt;/h5&amp;gt; : null }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>rails</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using Action Mailer to Send Emails from a Rails App</title>
      <dc:creator>Miriamfark</dc:creator>
      <pubDate>Thu, 16 Mar 2023 03:31:33 +0000</pubDate>
      <link>https://dev.to/miriamfark/using-action-mailer-to-send-emails-from-a-rails-app-5f4m</link>
      <guid>https://dev.to/miriamfark/using-action-mailer-to-send-emails-from-a-rails-app-5f4m</guid>
      <description>&lt;p&gt;This post contains a beginners guide to using Action Mailer to send emails from a Rails app.&lt;/p&gt;

&lt;p&gt;My latest project for Flatiron school is &lt;a href="https://github.com/Miriamfark/Carpool-App"&gt;The Carpool App&lt;/a&gt; - one central place for parents to post and find carpools for their kids. A big part of parents arranging carpools includes parents communicating with each other, especially to request for their child to join a carpool, and then for the driver of the carpool to either accept or reject the join request. As parents are not expected to keep their eyes glued to the website to see the updates, it became necessary to have the parents updated by sending them an email. &lt;/p&gt;

&lt;p&gt;As my project is built on Rails, Action Mailer was the simplest, built in choice to use to send emails. As Action Mailer is not part of the curriculum at Flatiron, it meant that I needed to teach this bit of technology to myself. At first I was confused about how to implement Action Mailer, but once I got it figured out, and that first email came through, I recognized a familiar "railsy" approach that emphasizes naming conventions and a configuration similar to the MVC pattern (model, view, controller). &lt;/p&gt;

&lt;p&gt;Let's get started! &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a mailer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;rails g mailer MailerName&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Generating a mailer is the simplest way to get started as Rails will generate the following files: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;app/mailers/mailer_name_mailer.rb&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;app/views/mailer_name_mailer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;test files in both spec/mailers/mailer_name_spec.rb and &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;spec/mailers/previews/mailer_name_preview.rb&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Decide the default email address&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of the mailers inherit from ApplicationMailer. If all of the emails in your app will be coming from the same email address, you can set the default email in one location, in the ApplicationMailer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ApplicationMailer &amp;lt; ActionMailer::Base
  default from: 'example@gmail.com'
  layout 'mailer'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will probably want to open up a new email account with your app name in it to send out app related emails. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add an Email Action to the Mailer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The next step is actually deciding what email you would like to send. For example, if you would like to send an email welcoming a new user to the app, you can create a welcome email. This would simply be a method in you mailer, defining the name of the email, what parameters are being passed in, where the email should be sent, and the subject of the email.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def welcome_email(user)
    @user = user
    mail(to: @user.email, subject: 'Welcome to The Carpool App')
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Creating a View&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After defining the email, it is time to decide what the email should look like. What will the email say? This is determined in by creating a new file in app/views/mailer_name_mailer called &lt;code&gt;welcome_email.html.erb&lt;/code&gt;. It is important to note two things. Firstly, the name of the file must be in the folder named after your mailer. Secondly, the file must follow the naming conventions of being called the same name as your email method. This sticks to a Rails principle of convention over configuration, meaning that by following conventions there is a lot less work required to configure the different files.&lt;/p&gt;

&lt;p&gt;Note: This file is an html.erb file, which is an html file with ruby embedded within. &lt;/p&gt;

&lt;p&gt;Once you have created the file, copy and paste the following inside.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta content='text/html; charset=UTF-8' http-equiv='Content-Type' /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to The Carpool App!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Thanks for joining and have a great day!&amp;lt;/p&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can edit or add any other information inside the email. Using interpolation you could personalize the email with the user's name.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;h1&amp;gt;Welcome to The Carpool App, &amp;lt;%= @user.name %&amp;gt;!&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;... or add a link to bring the user back to your app ...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;a href="&amp;lt;%= @url %&amp;gt;" target="_blank"&amp;gt;Click Here!&amp;lt;/a&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call the Email Method in a Controller&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you have figured out exactly what the email should look like and what it should say, you need to call the email method. The best place to do this is in a controller action. As my example is an email sent when a new user signs up for an account, I will call the email method in my create action of the Users Controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UsersController &amp;lt; ApplicationController
    skip_before_action :authorize, only: [:create]

    def create
        user = User.create!(user_params)
        session[:user_id] = user.id
        if user
            MailerNameMailer.welcome_email(user).deliver_now
        end
        render json: user, status: :created
    rescue ActiveRecord::RecordInvalid =&amp;gt; e
        render json: { errors: e.record.errors.full_messages }, status: :unprocessable_entity
    end

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Config&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To ensure that everything will work correctly, copy and paste the following into your config/environments/development.rb file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.perform_deliveries = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you choose to have your emails sent from a gmail account, you will need to include the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.action_mailer.default_options = {from: 'example@gmail.com'}
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address:              'smtp.gmail.com',
port:                 587,
user_name:            'example',
password:             'password',
authentication:       'plain',
enable_starttls_auto: true  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I had some trouble with gmail allowing me to sign in from my app, and so I had to go into my new gmail account, enable &lt;a href="https://support.google.com/accounts/answer/185839"&gt;two step verfication&lt;/a&gt;, and then create an &lt;a href="https://support.google.com/mail/answer/185833?hl=en-GB"&gt;app specific password&lt;/a&gt; to include above.&lt;/p&gt;

&lt;p&gt;Another great option is to use the &lt;a href="https://rubygems.org/gems/letter_opener/versions/1.4.1"&gt;letter opener gem&lt;/a&gt;. This is a great tool to use in development, because instead of the app actually sending the email, instead it opens a new tab on your browser with the email view. This is really helpful to see what is going on with the email as it happens. If you are using the letter opener gem, you would need to install it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gem install letter_opener -v 1.4.1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and include it in your config/environments/development.rb file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;config.action_mailer.delivery_method = :letter_opener&lt;br&gt;
&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;And that is it! You are now ready to send an email from your Rails app!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>rails</category>
    </item>
    <item>
      <title>Using Redux to Make a Global State</title>
      <dc:creator>Miriamfark</dc:creator>
      <pubDate>Tue, 03 Jan 2023 17:36:49 +0000</pubDate>
      <link>https://dev.to/miriamfark/using-redux-to-make-a-global-state-38c8</link>
      <guid>https://dev.to/miriamfark/using-redux-to-make-a-global-state-38c8</guid>
      <description>&lt;p&gt;Hi!&lt;/p&gt;

&lt;p&gt;I was working on my Phase-4 project for Flatiron, and ran into a very annoying problem.&lt;/p&gt;

&lt;p&gt;The project requirements were to build a rails server with three associated models, and a react front end with full CRUD that would also update state.&lt;/p&gt;

&lt;p&gt;I only want a user to see their own data, and therefore sent all of a user's data in one large user object. This made updating state based on CRUD actions very difficult and confusing. &lt;/p&gt;

&lt;p&gt;The solution to this problem was to use a state management system: I chose to use Redux.&lt;/p&gt;

&lt;p&gt;Redux works by storing state in a separate component known as a store, and allowing all components access to the store. This changes state into a global variable. No more passing down endless props! Any component that needs access to state or updates state can access it directly from the redux store.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install React-Redux and Redux Toolkit
&lt;/h3&gt;

&lt;p&gt;I used Redux Toolkit to minimize the amount of code I needed to write. Install redux toolkit and react-redux by running&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nnpm install @reduxjs/toolkit react-redux&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Wrap App with Provider
&lt;/h3&gt;

&lt;p&gt;This is my index.js, where I am importing a Provider from react-redux and using it to wrap my entire app. I am then importing my store and passing it in as props to the Provider. This gives my entire app direct access to the state stored in the redux store.&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 ReactDOM from 'react-dom';
import { Provider } from "react-redux"; 
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './components/App';
import reportWebVitals from './reportWebVitals';
import store from "./redux/store"

ReactDOM.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;Provider store={store}&amp;gt;
      &amp;lt;BrowserRouter&amp;gt;
        &amp;lt;App /&amp;gt;
      &amp;lt;/BrowserRouter&amp;gt;
    &amp;lt;/Provider&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;,
  document.getElementById('root')
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Create a Store
&lt;/h3&gt;

&lt;p&gt;Next, create a store to hold your state. The simplest way to create a store is to use redux toolkit's configureStore(). The store contains two pieces of state, my user and a list of recipients.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { configureStore } from "@reduxjs/toolkit";
import { recipientsSlice } from "./recipientsSlice";
import { usersSlice } from "./usersSlice";

const store = configureStore({
  reducer: {
    recipients: recipientsSlice.reducer,
    users: usersSlice.reducer
  },
});

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Set Up Slices
&lt;/h3&gt;

&lt;p&gt;A slice is made up of actions and reducers. The actions are methods to change state, while the reducer applies the change to the current state.&lt;/p&gt;

&lt;p&gt;The reducers job is to combine two pieces of the app - the current state and an action. It is a method that takes in the current state and the action we want to do to update state and returns the updated state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

export const fetchRecipients = createAsyncThunk('recipients/getRecipients', async () =&amp;gt; {
    try{
        const getRecipients = await axios.get('/recipients');
        const res = await getRecipients.data;
        if (getRecipients.status === 200) {
            return res;
          } else {
            return res.error;
          }
    } catch(e) {
        return e.error;
    }
});

export const postRecipient = createAsyncThunk('recipients/postRecipient', async (recipient) =&amp;gt; {
    const newRecipient = await axios.post('/recipients', recipient);
    const res = await newRecipient.data;
    return res;
});

export const recipientsSlice = createSlice({
        name: "recipients",
        initialState: {
          recipients: [],
          isFetching: false,
          isSuccess: false,
          isError: false,
          errorMessage: "",
        },
        extraReducers: {
          [postRecipient.fulfilled]: (state, { payload }) =&amp;gt; {
              state.isFetching = false;
              state.isSuccess = true;
              state.recipient = [...state.recipient, payload]
          },
          [postRecipient.pending]: (state) =&amp;gt; {
              state.isFetching = true;
          },
          [postRecipient.rejected]: (state, { payload }) =&amp;gt; {
              state.isFetching = false;
              state.isError = true;
              state.errorMessage = payload.error;
          },
          [fetchRecipients.fulfilled]: (state, { payload }) =&amp;gt; {
              state.recipient = payload;
              state.isFetching = false;
              state.isSuccess = true;
              return state;
          },
          [fetchRecipients.rejected]: (state, { payload }) =&amp;gt; {
              state.isFetching = false;
              state.isError = true;
              state.errorMessage = payload.error;
          },
          [fetchRecipients.pending]: (state) =&amp;gt; {
              state.isFetching = true;
          },
        },
})


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

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Access State in React Components
&lt;/h3&gt;

&lt;p&gt;Finally, we need to access state in a react component, as well as tell state when to update from the component. To do this there are two tools to use: useSelector and useDispatch. Both are imported into a component from "react-redux", and can be called in any component.&lt;/p&gt;

&lt;p&gt;UseSelector is used to specify which values from state should be displayed.&lt;/p&gt;

&lt;p&gt;useDispatch is used to send an action to the reducer.&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 { useSelector, useDispatch } from "react-redux";
import { userSelector, clearState, loginUser } from '../redux/usersSlice';

const LoginForm = () =&amp;gt; {

    const { isError, errorMessage } = useSelector(userSelector)

    const [username, setUsername] = useState("")
    const [password, setPassword] = useState("")
    const [errors, setErrors] = useState(false)

    const dispatch = useDispatch()

    useEffect(() =&amp;gt; {
        if (isError) {
            setErrors(errorMessage)
            dispatch(clearState())
        }
    }, [isError, dispatch, errorMessage])

    function handleSubmit(e) {
        e.preventDefault()
        const user = {
            username,
            password
        }
        dispatch(loginUser(user))
    }

  return (
    &amp;lt;div className="row container valign-wrapper"&amp;gt;
        &amp;lt;form onSubmit={handleSubmit} className="col s8"&amp;gt;
            &amp;lt;div className="row"&amp;gt;
                &amp;lt;div className="input-field col s8"&amp;gt;
                    &amp;lt;label&amp;gt;Username &amp;lt;/label&amp;gt;
                    &amp;lt;input 
                        type="text"
                        value={username}
                        onChange={(e) =&amp;gt; setUsername(e.target.value)}
                    &amp;gt;&amp;lt;/input&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div className="input-field col s8"&amp;gt;
                    &amp;lt;label&amp;gt;Password&amp;lt;/label&amp;gt;
                    &amp;lt;input 
                        type="password"
                        value={password}
                        onChange={(e) =&amp;gt; setPassword(e.target.value)}
                    &amp;gt;&amp;lt;/input&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div className="input-field col s8"&amp;gt;
                    &amp;lt;input className="btn" type="submit" value="Log In" /&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/form&amp;gt;
        { errors ? &amp;lt;h5&amp;gt;{errors}&amp;lt;/h5&amp;gt; : null }
    &amp;lt;/div&amp;gt;
  )
}

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

&lt;/div&gt;



&lt;p&gt;And there it is! State is now stored in a redux store, making it a global variable. No more passing down confusing props in order to update state in so many places.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>ORM Explained</title>
      <dc:creator>Miriamfark</dc:creator>
      <pubDate>Tue, 04 Oct 2022 02:08:45 +0000</pubDate>
      <link>https://dev.to/miriamfark/orm-explained-40fj</link>
      <guid>https://dev.to/miriamfark/orm-explained-40fj</guid>
      <description>&lt;p&gt;Hi All!&lt;/p&gt;

&lt;p&gt;I am back with another blog post, this time to tell you all about ORM's - Object-Relational Mapping.&lt;/p&gt;

&lt;p&gt;Object - Relational Mappers are a developers dream. Every app will need a database to persist information and allow full, dynamic CRUD abilities. Speaking to a database involves learning a database language, usually SQL. This is what a SQL request looks like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$SELECT * FROM table_name;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A more complicated SQL request including a condition may look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$SELECT * FROM table_name WHERE id = 1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;However, ORMs change that by being the intermediate layer, the go between, for the database and your preferred programming language.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Do ORMs Work?
&lt;/h2&gt;

&lt;p&gt;Object-Relational Mappers work by establishing a link between object-oriented programming classes and database tables. Each row in a table is represented by an instance of the linked class. &lt;/p&gt;

&lt;p&gt;What an ORM is really doing is "wrapping" the SQL statements that will talk to the database in code, to automate the SQL requests, and avoid repetition. This makes sense according to programmers #1 rule: Keep it DRY! (Don't repeat yourself!) it is similar to creating a method that performs a task and calling that method multiple times. It cuts down on annoying, repetitive code, and you can use a language that is more familiar.&lt;/p&gt;

&lt;p&gt;For example, if you are building a to-do app (&lt;a href="https://github.com/Miriamfark/Phase-3-Project-Frontend/blob/main/README.md"&gt;check out mine!&lt;/a&gt;) you will need a table of tasks. Every time you want to add a new task to the table, you will have to write a SQL statement such as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ INSERT INTO tasks (name, category, minutes) VALUES ('Sweeping', 'Housework', 20)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Instead, an ORM will abstract away that logic and you can more easily say:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ Task.create(name:'Sweeping, category:'Housework', minutes:20)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is much more familiar, much cleaner, and much quicker!&lt;/p&gt;

&lt;h2&gt;
  
  
  ORM Conventions
&lt;/h2&gt;

&lt;p&gt;Following ORM conventions is very important, as many of the functions depend on the conventions being followed. If you don't follow the conventions, your ORM will not work!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tables are lower case and plural. Example: tasks, days, categories&lt;/li&gt;
&lt;li&gt;Classes are upper case and singular. Example: Task, Day, Category&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is important to remember that every table is linked to a class and every instance is linked with a row in a table. However, the row is not the object and the object is not the row. The object is merely a representation of what actually exists within the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common ORM Capabilities
&lt;/h2&gt;

&lt;p&gt;Most ORMs, such as Active Record, have amazing capabilities. With very little code you can get access to very useful methods. Here are methods for Create, Read, Update and Delete.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;$ Day.create(name: 'Sunday')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or you can instantiate a new day without saving, or save it in a separate command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sunday = Day.new
sunday.name = 'Sunday'
sunday.save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Read
&lt;/h4&gt;

&lt;p&gt;There are several ways of reading data, depending on information you require. If you would like all the rows of a specific table you would say:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ Day.all&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;for just the first day in a collection you can say&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ Day.first&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;you can search by name, id, or other attribute&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ Day.find_by(name: 'Sunday)&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Update
&lt;/h4&gt;

&lt;p&gt;To update an attribute, you will usually have to first find the attribute by searching for and then updating.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;monday = Day.find_by(name: 'Monday')
monday.update(name: 'Meatless Monday')
```

`

####4. Delete
Likewise, for delete you will first have to find the object and then delete it.

`

```
monday = Day.find_by(name: 'Monday')
monday.destroy
```

`

## For More Information
https://guides.rubyonrails.org/active_record_basics.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>database</category>
    </item>
    <item>
      <title>Nested Dynamic Routes with React Router</title>
      <dc:creator>Miriamfark</dc:creator>
      <pubDate>Mon, 25 Jul 2022 20:27:00 +0000</pubDate>
      <link>https://dev.to/miriamfark/nested-dynamic-with-react-router-33ab</link>
      <guid>https://dev.to/miriamfark/nested-dynamic-with-react-router-33ab</guid>
      <description>&lt;p&gt;One of the futures I really enjoyed using in React Router was the nested routes hook  and useParams.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://reactrouter.com/docs/en/v6/getting-started/concepts"&gt;React Router documentation&lt;/a&gt; defines a dynamic segment as :&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Dynamic Segment - A segment of a path pattern that is dynamic, meaning it can match any values in the segment. For example the pattern /users/:userId will match URLs like /users/123&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In order to use this cool future, we need useParams() which is defined as: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;URL Params - The parsed values from the URL that matched a dynamic segment.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is very helpful for when you have multiple nested routes, such as in an ecommerce store or blog. A parent component shows a list of objects that are links to more information about each product. Without dynamic routing, one would have to manually create a card and route for each product, which is incredibly inefficient especially for stores with many products. This is also a bad idea because as products are added or changed, it requires that the code be updated. Thank goodness for dynamic routing! Keep reading to see how it's done!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
In App.js I used react-router-dom   and  to render my route to ComponentDetail.js.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;Route path="locations-detail/:id" element={&amp;lt;ComponentDetail&lt;br&gt;
               locations={locations}&lt;br&gt;
               passport={passport}&lt;br&gt;
               setPassport={setPassport}&lt;br&gt;
               bucketList={bucketList}&lt;br&gt;
               setBucketList={setBucketList}&lt;br&gt;
               /&amp;gt;} /&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the path=”location-detail/:id”, with id being a dynamic variable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Moving on, with ComponentDetail.js, I imported useParams from react-router-dom and then destructured the useParams object with id as my url variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;let { id } = useParams();&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
I then used some conditional rendering to render my LocationCard.js, to display the correct location.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;if (location.id == id) {&lt;br&gt;
           return( &amp;lt;LocationCard &lt;br&gt;
                   passport={passport}&lt;br&gt;
                   key={location.id}&lt;br&gt;
                   id={location.id}&lt;br&gt;
                   city={location.city}&lt;br&gt;
                   country={location.country}&lt;br&gt;
                   location={location}&lt;br&gt;
                   setPassport={setPassport}&lt;br&gt;
                   food={location.food}&lt;br&gt;
                   landmark={location.landmark}&lt;br&gt;
                   bucketList={bucketList}&lt;br&gt;
                   setBucketList={setBucketList}&lt;br&gt;
                   reviews={location.comments}&lt;br&gt;
                /&amp;gt;&lt;/code&gt;&lt;br&gt;
           )&lt;/p&gt;

&lt;p&gt;Now, when a user click on location link, the url displays the correct location id and the correct information is displayed on the screen. How cool is that?&lt;/p&gt;

</description>
      <category>react</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using Data Attributes For A Dynamically Added Five-Star Rating System</title>
      <dc:creator>Miriamfark</dc:creator>
      <pubDate>Sat, 19 Mar 2022 21:51:37 +0000</pubDate>
      <link>https://dev.to/miriamfark/using-data-attributes-for-a-dynamically-added-five-star-rating-system-18lg</link>
      <guid>https://dev.to/miriamfark/using-data-attributes-for-a-dynamically-added-five-star-rating-system-18lg</guid>
      <description>&lt;p&gt;I learned something new! &lt;/p&gt;

&lt;p&gt;This blog post describes a new-to-me HTML attribute data, and how I used it to solve my five-star rating woes. &lt;/p&gt;

&lt;p&gt;I encountered some trouble while working on a JavaScript project. I was trying to build out a five-star rating system for data fetched from JSON server. &lt;/p&gt;

&lt;p&gt;A card was dynamically created for each object from the JSON server and appended to the page to display the JSON data.&lt;br&gt;
Part of the card is a div containing five a tags with a rating star. I added an event listener to each star to listen for a click, and with JavaScript, I added a class name of ‘active’ to the clicked star and all the stars to its left.  Using CSS, anything with a class of ‘active’ was at full opacity.&lt;/p&gt;

&lt;p&gt;The issue that I was having, was that I had gathered all my stars into an array and added the click event to all the stars. Unfortunately, when I clicked on a star, it did not differentiate between the stars on its parent card and the stars on previous cards, as all the stars were part of the same array. When I did a for loop counting the stars indices and console logging the index of a clicked star, it did not stop at five the way I had intended, but continued looping through all six cards, coming to a total of thirty!&lt;/p&gt;

&lt;p&gt;I reached out to my awesome instructor Enoch, and he gave me the idea to use Data-* attribute. Datasets are an HTML attribute that can be used to store extra information on standard HTML elements which does not need to be seen or read. This makes it easy to differentiate between similar HTML elements that need to have the same class, but would be too annoying to make each its own id. What I did was add a data attribute called rating to each star as it is created, and assigned each star a number from 1-5. Now each card it its own parent node containing five unique stars, and the click event when rating is contained within its parent card.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;star1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="nx"&gt;star2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
      &lt;span class="nx"&gt;star3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
      &lt;span class="nx"&gt;star4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
      &lt;span class="nx"&gt;star5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;A data attribute is easy to add dynamically in JavaScript, but it must be noted that a data attribute is a string and must be parsed into an integer if you are storing numbers.&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;addRating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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;starDiv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rating&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aStars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;starDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;for&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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aStars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&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;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&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;Here is my function called by my event listener. When a star is clicked, it calls addRating, which loops through the stars and adds a class ‘active’ to the clicked star and all the stars with a rating number lower than the clicked star within its parent node!&lt;/p&gt;

&lt;p&gt;Learning about using the data attribute is really exciting because there are so many ways to use this attribute. It is useful for any situation in which you would like to include extra data on an HTML element that does not need to be seen on the page. The only downside of using datasets is that it is currently unsupported on Internet Explorer.&lt;/p&gt;

&lt;p&gt;Please let me know your feedback, I would love to hear what you think!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>json</category>
    </item>
    <item>
      <title>Coding: First Impressions</title>
      <dc:creator>Miriamfark</dc:creator>
      <pubDate>Tue, 08 Mar 2022 20:33:04 +0000</pubDate>
      <link>https://dev.to/miriamfark/coding-first-impressions-30jn</link>
      <guid>https://dev.to/miriamfark/coding-first-impressions-30jn</guid>
      <description>&lt;p&gt;Hi! I’m Miriam!&lt;/p&gt;

&lt;p&gt;I am currently enrolled in a coding boot camp, work part time as an office manager in an educational institution, and am a mom of two kids (a three year old girl and a one year old boy – they are adorable!) As I work in the morning while my kids are in preschool and day care, coding only happens at night, after the kids are sleeping. Once the kids drift off into slumber, I shift gears from Mommy to ….Coder! &lt;/p&gt;

&lt;p&gt;Coding kind of feels like my superpower. It is challenging, stimulating, at times it can be maddening, and when it finally clicks, it is very satisfying. I alternate between being intimidated of, and enjoying, the mental challenge. &lt;/p&gt;

&lt;p&gt;The time that I spend learning and practicing code is me-time. After a busy day of feeding, dressing, diapering, working in the office, some more cooking, feeding, and playing (which I love doing 😊) I crave the silence and peacefulness of sitting in front of my computer and getting lost in a new Javascript skill. &lt;/p&gt;

&lt;p&gt;Before I started boot camp, I didn’t even know what a computer programmer did. I kind of imagined a coder as a stereotypical nerd typing in a magical series of zeros and ones. I certainly never considered myself doing that! However, after doing a career consultation, I found that the logical problem solving of programming was a great match for my abilities. I was also encouraged by a friend who had done a software engineering bootcamp, had gotten a great job as a frontend developer, and was loving it!&lt;/p&gt;

&lt;p&gt;I remember one of the first skills I learned was to write a HTML tag. Seeing the words that I had typed “Hello, World!” appear on the screen felt tremendous. It may not have been the first steps on the moon, but it sure was exciting! For a few days after, every website I encountered I felt a kinship to. After all, someone else had also written an HTML tag for that website!&lt;/p&gt;

&lt;p&gt;I am currently in Phase 1 of my program, which focuses on HTML, CSS, and Javascript. I learned about DOM manipulation, event listeners, and fetch requests which I am putting altogether now in my Phase-1 project. &lt;/p&gt;

&lt;p&gt;I will be back soon with another post detailing my challenges in putting together a five star rating system for my project.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

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