<?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: loren-michael</title>
    <description>The latest articles on DEV Community by loren-michael (@lorenmichael).</description>
    <link>https://dev.to/lorenmichael</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%2F748964%2Facc5791c-a60d-47e4-b174-fc2d4e0b6d5a.jpg</url>
      <title>DEV Community: loren-michael</title>
      <link>https://dev.to/lorenmichael</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lorenmichael"/>
    <language>en</language>
    <item>
      <title>E-Commerce using Redux</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Wed, 24 May 2023 18:01:00 +0000</pubDate>
      <link>https://dev.to/lorenmichael/e-commerce-using-redux-39hm</link>
      <guid>https://dev.to/lorenmichael/e-commerce-using-redux-39hm</guid>
      <description>&lt;p&gt;The time to show off my skills is here! For my final project for Flatiron I built an application that mimics sites like Etsy, eBay and (specifically) Reverb. It is a website called "Sell It!" that allows users to sign up and list their audio gear or instruments to sell to other users. As one of our learning goals for this project, we needed to implement Redux in our application.&lt;/p&gt;

&lt;p&gt;Redux was a blast to utilize. It made state data so much easier to manage. At first the setup was a little confusing and sometimes updating data can get a little twisted, especially if you're using any nested data in your site, but it's worth figuring it out and learning a new thing that streamlines prop sharing.&lt;/p&gt;

&lt;p&gt;Redux gives the developer of an app a single, centralized place where our state data is contained. This eliminates the need for prop sharing through a tree. It also requires a specific pattern to be followed in order to update state.&lt;/p&gt;

&lt;p&gt;There are a handful of new terms that you need to learn when utilizing Redux. Here's a quick rundown of the different functions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Store:&lt;/strong&gt; The &lt;em&gt;store&lt;/em&gt; is where the current Redux application state lives. When we set up our application, we create the store in our index.js file so that immediately upon loading, the user has access to current data. This is also where we can implement other Redux middleware that I will not be covering in this blog post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Action:&lt;/strong&gt; An &lt;em&gt;action&lt;/em&gt; is a JavaScript object that has a "type" field. An action is an event that describes what event is happening in the application. For example, addItem would be a good action name to describe adding an item to your store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const addItem = item =&amp;gt; {
  return (dispatch)  =&amp;gt; {
    dispatch({ type: "CREATE_ITEM", payload: item })
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dispatch:&lt;/strong&gt; The Redux store has a method called &lt;em&gt;dispatch&lt;/em&gt;. The only way to update state is to call dispatch() and pass in an action object. Here you can see a short function that is triggered by an event (pushing a delete button) that dispatches the deleteItem action with an id being passed to the action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  function handleDeleteListing (e) {
    dispatch(deleteItem(e.target.id))
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reducers:&lt;/strong&gt; A &lt;em&gt;reducer&lt;/em&gt; is a function that&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receives the current state and an action object&lt;/li&gt;
&lt;li&gt;Decides how to update state if necessary&lt;/li&gt;
&lt;li&gt;Returns the new state
A reducer functions similarly to an event listener based on the action it receives.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Above I showed the addItem action, that dispatches an object. In the object is a "type" key whole value is "CREATE_ITEM". When dispatched, the reducer looks for the matching action type and updates and returns state based on the data being sent in the payload value (in this case, the new item).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const itemsReducer = (state=initialState, action) =&amp;gt; {
  switch(action.type) {
    case "CREATE_ITEM":
      return {
        ...state,
        items: [...state.items, action.payload]
      };
    default:
      return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Selector:&lt;/strong&gt; The &lt;em&gt;selector&lt;/em&gt; function is used in any component where you need to access the store. When it's time to access the store to display the items, we define our variable and then "select" the data from the store that we want to access. Below I've shown two different ways of defining what data we want to access from which reducer (store.items or store.sessions).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const items = useSelector(store =&amp;gt; store.items)
  const { loggedIn, currentUser } = useSelector(store =&amp;gt; store.sessions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The way that data flows one way through Redux is brilliant.&lt;/p&gt;

&lt;p&gt;First, state describes the condition of the app at that point in time, and UI is rendered based on that state.&lt;/p&gt;

&lt;p&gt;Next, when an event occurs in the app, an action is dispatched.&lt;/p&gt;

&lt;p&gt;The store looks through the reducers to find the correct action type and updates state based on the action and the action's payload.&lt;/p&gt;

&lt;p&gt;Then, the store tells the UI that there has been an update to the state, triggering a re-render based on the new state.&lt;/p&gt;

&lt;p&gt;It's been a really great tool to use and I can't wait to build another app that uses Redux!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>redux</category>
      <category>react</category>
      <category>rails</category>
    </item>
    <item>
      <title>Ruby on Rails: A Simple Movie Rental Application</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Mon, 13 Feb 2023 20:12:25 +0000</pubDate>
      <link>https://dev.to/lorenmichael/ruby-on-rails-a-simple-movie-rental-application-4djo</link>
      <guid>https://dev.to/lorenmichael/ruby-on-rails-a-simple-movie-rental-application-4djo</guid>
      <description>&lt;p&gt;Over the last couple months I've been diving deeper into Rails. Learning how to connect a React frontend to a Ruby on Rails backend was honestly pretty smooth. In building out this application I discovered a couple of weak points in my learning and will be able to course correct easier in the future because of this experience.&lt;/p&gt;

&lt;p&gt;A lot of the lessons that I got out of this project revolved around establishing a good order of operations. When you're building a house, you start with foundations, then framework, then plumbing and electric, then finally walls and a roof. I think a lot of my early struggles in building my own apps has stemmed from losing sight of this particular lesson. While it can be difficult to stop and pivot to a different task, it really helps to exercise the brain while learning new things to rotate subjects in and out - set up a database model, seed it, switch to React and build it out, repeat. Going back and forth from setting up a database model to making sure that the frontend will receive the data it needs is incredibly helpful. Setting up your frontend components earlier in the process will also give you a better idea of what kind of data you will need to provide from your database. In my case, it would have helped me decide exactly what keys I would want for my movies model, rather than guessing and adding more information than I really needed.&lt;/p&gt;

&lt;p&gt;For this application, I built out a database that included Movies, Rentals, Stores and Users, with Rentals set up as a join table for the other 3 models. When a User starts a rental, the User's id, Movie id and Store id are stored together with a Rental id. When fetching rentals from the backend, we also include the associated movie for easy iteration.&lt;/p&gt;

&lt;p&gt;Near the end of my project phase, I was tasked to learn a hook, useContext. I found this hook to be incredibly useful with this application. When you implement useContext, you allow your data to move freely around your component tree, rather than having to send it through a hierarchy to reach the components that access it (often passing through components that don't). This hook potentially saves a lot of time in larger applications with many nested components.&lt;/p&gt;

&lt;p&gt;To utilize the useContext hook in this app, I followed these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a context folder within my src folders (where both components and context share the src as a parent directory). Inside that folder, I made a file for each of the models that I wanted to use with the useContext hook. In this case, I made a movies.js file and a stores.js file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once these files are set up, we add the following code to them:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

const MoviesContext = createContext(null);

const MoviesProvider = ({ children }) =&amp;gt; {
  const [movies, setMovies] = useState([])

const value = [movies, setMovies]

  return (
    &amp;lt;MoviesContext.Provider value={value}&amp;gt;
      { children }
    &amp;lt;/MoviesContext.Provider&amp;gt;)
}

export { MoviesProvider, MoviesContext }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First we import React and createContext as well as any other relevant hooks to the context we are creating. The next line just sets up MoviesContext as our newly created context. This can start either empty or with a null value.&lt;/p&gt;

&lt;p&gt;Then we need to create our Provider. The provider acts like a component, in which we can set up things like state and determine what gets returned to the Context Provider when it is called in other components. Our provider has a prop of children because we want this provider and the information it holds to be available to any of the children of its element in our index.js file. We'll get to that in a moment.&lt;/p&gt;

&lt;p&gt;Within the return block of the Provider, we need to tell the &lt;code&gt;&amp;lt;MoviesContext.Provider&amp;gt;&lt;/code&gt; element what information we want it to provide using the value tag. Here, I am setting movies and setMovies within my value tag. Within the element we include the &lt;code&gt;{ children }&lt;/code&gt; prop to specify that the value is available to all children of the element.&lt;/p&gt;

&lt;p&gt;Last, we need to export our Provider and Context.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Next the Provider needs to be added to the main index.js file. Remember, all children of this Provider will be able to access the information, so we want to nest our &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; element within the Provider. It looks like this:
&lt;/li&gt;
&lt;/ol&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/client';
import './index.css';
import App from './App';
import { MoviesProvider } from './context/movies';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;MoviesProvider&amp;gt;
      &amp;lt;App /&amp;gt;        
    &amp;lt;/MoviesProvider&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);

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

&lt;/div&gt;



&lt;p&gt;Notice that we need to import our Provider from our context folder in order to use it in our render.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Then, we move into our components to access the Context that our Provider is making available to our App. In order to access the information, we first need to import our Context...&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;import { MoviesContext } from '../context/movies'&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;...define the props that we will be using...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const [movies, setMovies] = useContext(MoviesContext);&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
...and then continue to use these variables within our components the same as if they were passed down through our component hierarchy. Here's a full example of a component that uses the movies prop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import '../styles.css';
import React, { useContext } from 'react';
import { Card } from 'semantic-ui-react';
import { MoviesContext } from '../context/movies'
import MovieCard from './MovieCard';

function MoviesContainer() {
  const [movies, setMovies] = useContext(MoviesContext);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;br&amp;gt;&amp;lt;/br&amp;gt;
      &amp;lt;Card.Group className="movie-cards"&amp;gt;
        {movies.map(movie =&amp;gt; {
          return (&amp;lt;MovieCard key={movie.id} movie={movie} /&amp;gt;)
        })}
      &amp;lt;/Card.Group&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default MoviesContainer

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

&lt;/div&gt;



&lt;p&gt;It's always a challenge to learn a new hook. Luckily useContext is one of the easier ones to implement within an existing application. Just remember to remove any other code that defines, calls or passes down the original state props and you should be good to go!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>rails</category>
      <category>ruby</category>
      <category>react</category>
    </item>
    <item>
      <title>Creating an App with React and Sinatra</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Tue, 11 Oct 2022 18:48:44 +0000</pubDate>
      <link>https://dev.to/lorenmichael/creating-an-app-with-react-and-sinatra-loa</link>
      <guid>https://dev.to/lorenmichael/creating-an-app-with-react-and-sinatra-loa</guid>
      <description>&lt;p&gt;To wrap up my current phase of learning, I've been tasked to create a React application that utilizes &lt;a href="https://sinatrarb.com/" rel="noopener noreferrer"&gt;Sinatra&lt;/a&gt;. As an avid D&amp;amp;D fan, I decided that for this project I'd create a character manager. I thought it would be a challenging way to create a backend database of users who manage their characters. I also created a &lt;a href="https://dbdiagram.io/d/634597ccf0018a1c5fdfcad2" rel="noopener noreferrer"&gt;DB Diagram&lt;/a&gt; to show my tables and relationships:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40qc2lcpcf9ylv3waicd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40qc2lcpcf9ylv3waicd.png" alt="Database Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an added challenge to myself, I wanted to learn how to utilize a simple login prompt to better organize the characters and show proper ownership over each of them. I decided not to use any kind of password or authenticator, this is simply a persistent username based login. By using the browser's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage" rel="noopener noreferrer"&gt;localStorage&lt;/a&gt;, I was able to set up a way for users to persist on different visits. When logging in, the app will look for an existing user in the database. If a user is found, a few different states get updated. A currentUser is set, isLoggedIn is set to true, we add a user id to localStorage, and then we navigate to a home page where all of that user's characters are displayed. The login code looks 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;  const login = (user) =&amp;gt; {
    setCurrentUser(user);
    setIsLoggedIn(true);
    localStorage.setItem('user_id', user.id);
    navigate(`/${user.id}/characters`)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then wrote a useEffect that would fetch the characters of a user whenever the currentUser state gets updated. When the user logs out, all of these states get reverted back to their default settings, including wiping out the state that stores the characters so that there are no data remnants from previous users. In order for this to work properly, I had to find a way to look up users in the backend when entering a username into the Login component. To do this, I wrote a fetch that would send the submitted username to the backend. The backend then searches for the username, and if it exists, sends back the user data and calls the login function shown above. If the user does not exist, it sends a message instead of user data, and the browser will alert the user that the username they are trying to log in with does not exist. (Currently I have not implemented a way to create a new user but I plan to add that in the future.)&lt;/p&gt;

&lt;p&gt;On the frontend, the fetch takes the username and POSTs it to the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const handleLogin = e =&amp;gt; {
    e.preventDefault();

    fetch('http://localhost:9292/login', {
      method: "POST",
      headers: {
        "Accept": "application/json",
        "Content-Type": "application/json"        
      },
      body: JSON.stringify({ username })
    })
      .then(resp =&amp;gt; resp.json())
      .then(data =&amp;gt; {
        if(!data.message) {
          login(data)
        } else if (data.message) {
          alert(data.message)
        }
      })
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this process I also learned that a project can have multiple Controller files to better organize your routes. When making additional Controller files, they need to be added to your config file so your application knows to access them for routes. &lt;br&gt;
When we make this fetch, we use the SessionsController file, which has a route specifically for login requests. the route looks 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;  post '/login' do
    user = User.find_by_username(params[:username])
    if user
      user.to_json
    else
      { message: "This user does not exist."}.to_json
    end
  end

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

&lt;/div&gt;



&lt;p&gt;The next step was writing a basic React frontend that would properly display all of a user's characters and allow the user to level up each of the characters (only to 20, naturally) and delete them if desired. But before being able to display data, I needed to create it! Using Active Record I created a migration for each of the tables that I wanted to utilize (Characters, Users and Games). In each of the migrations, I wrote out a create_table that included the information that I wanted to be able to store in each of the tables.&lt;/p&gt;

&lt;p&gt;Here is the character table migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CreateCharacters &amp;lt; ActiveRecord::Migration[6.1]
  def change
    create_table :characters do |t|
      t.string :name
      t.string :race
      t.integer :level
      t.belongs_to :game
      t.belongs_to :user
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But wait! I forgot some columns! As I progressed with project development I went back to write additional migrations to add columns for character_class (since class is a reserved word, the column could not simply be named "class") and an icon, which holds the string of the URL for the icon images. While going through this process I also made a seed file that would create users, games and characters to test the application's functionality. Once seeded, I was able to display a user's characters after login:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62ubttkzwrut8ho5xnfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62ubttkzwrut8ho5xnfw.png" alt="Character Manager"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, there are buttons on each character card that will allow the user to Level Up their character (to a maximum of 20 per traditional D&amp;amp;D rules) and delete them. The routes for these two tasks were fairly simple, either sending a new integer to PATCH to the character or destroying the entry.&lt;/p&gt;

&lt;p&gt;This was a challenging way to reinforce everything that I've learned about React, Active Record, Sinatra, and even some basic Javascript/CSS. I look forward to learning so much more in the coming months!&lt;/p&gt;

</description>
      <category>flatiron</category>
      <category>beginners</category>
      <category>react</category>
      <category>sinatra</category>
    </item>
    <item>
      <title>Recipe Manager 2.0: React!</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Wed, 22 Jun 2022 20:24:38 +0000</pubDate>
      <link>https://dev.to/lorenmichael/recipe-manager-20-react-52c4</link>
      <guid>https://dev.to/lorenmichael/recipe-manager-20-react-52c4</guid>
      <description>&lt;p&gt;Over the past few weeks I've been learning React, and now it's time to show what I've learned. I decided to make a recipe manager similar to the one that I previously built using vanilla JavaScript. While it was relatively easy to make this transition, I definitely encountered some hiccups that required a little more troubleshooting than I anticipated.&lt;/p&gt;

&lt;p&gt;After setting up my project and building my components, I made sure they would render by lining them up in my App and checking them in my browser. I then wrote a useEffect to fetch the recipes from my JSON database and stored that information in state so that any recipe can be rendered using a single fetch. Next, I started to distribute props and added Routes to the components. Right away I knew there was something wrong. The issue I encountered stemmed from using incompatible versions of React and React Router. Of course I figured out where the problem was &lt;em&gt;after&lt;/em&gt; I wrote all of my Routes! Because I had installed v18 of React, I had to update my React Router from v5 to v6 and update all of the syntax around my Routes. Ultimately, updating the syntax didn't take very long and in the long run the new version looks much cleaner, so I'm actually glad I ran into this issue and learned a new and updated way of Routing.&lt;/p&gt;

&lt;p&gt;From there, I was able to build out a home page using Semantic UI Cards. Each card shows a picture, the recipe title and whether or not the recipe is one of my favorites. Clicking on a recipe title will take you to the recipe's details page, where ingredients, instructions and any comments are displayed. Here is where you can add a comment or favorite/unfavorite a recipe.&lt;/p&gt;

&lt;p&gt;This is where I ran into a common issue when using state in React. When updating state within a function, I would often try to utilize the updated state before the function finished and the changes were actually applied within the component.&lt;/p&gt;

&lt;p&gt;For example, instead of changing whether or not a recipe was a favorite just by setting the "favorite" state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleFavorite() {
    const newFavorite = !favorite;
    setFavorite(newFavorite);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used a callback function within my setState hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleFavorite() {
    setFavorite(function (favorite) {
        const newFavorite = !favorite;
        return newFavorite;
    })
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then paired this function with a useEffect hook that is called whenever the "favorite" state is changed. Within the useEffect, the new "favorite" status gets PATCHed to the recipe database to make sure it is always current. At this point, the "recipes" state that is stored is no longer current, so I have the useEffect also fetch the updated database to store in the "recipes" state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
     fetch(`http://localhost:3000/recipes/${recipe.id}`, {
        method: "PATCH",
        headers: {
           "Content-Type": "application/json"
        },
        body: JSON.stringify({"favorite": favorite})
     })
     .then(fetch(`http://localhost:3000/recipes`)
        .then(r =&amp;gt; r.json())
        .then(recipes =&amp;gt; {
           setRecipes(recipes);
}))
}, [favorite])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used a similar process for the comments section, so that when a comment is submitted to the recipe, it updates the state of the "comments" array, which triggers a fetch within a useEffect that patches the new array to the database and then fetches the recipes to save into the "recipes" state to keep current with the database.&lt;/p&gt;

&lt;p&gt;To set up all of these inputs as controlled inputs, I looked at my database and created a newRecipe state that had all of the keys that I wanted to include in the form. This includes things like the name of the recipe, the author, website, a photo URL, etc... When I got to the keys whose values were arrays, I simply included an empty array or, in the case of the comments, the value was assigned as another state. Take a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [newRecipe, setNewRecipe] = useState({
    img: "",
    video: "",
    name: "",
    source: "",
    author: "",
    mealtype: "",
    preptime: "",
    cooktime: "",
    servings: "",
    ingredients: [],
    instructions: [],
    comments: commArr
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here, I made all of the single string inputs controlled by one function to update the values for those items in the newRecipe state. I had to be a little creative with the ingredients and instructions, because recipes don't have a set number of ingredients or instructions to include in a form like this. I couldn't just throw in 5 inputs for ingredients and 5 inputs for instructions. I wanted to be able to click a button and add a new input that would then be included in the new recipe's state. To do this, I wrote a function that would update a state array that simply had numbers in it that would act as my keys later on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [numIng, setNumIng] = useState([0, 1, 2, 3, 4]);

function handleAddIng() {
    const newNum = numIng.length;
    setNumIng([...numIng, newNum], () =&amp;gt; {});
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once I had that functioning properly I took that state array and mapped it to render one input for each value in the array, using the value as a key. Once the state array updates with a new number, a new input is added to the page with a proper key, className and onChange function for the input to be controlled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{numIng.map((num) =&amp;gt; {
    return (
        &amp;lt;div&amp;gt;
            &amp;lt;input type="text" key={num} className="add-ingredient" onChange={handleIngredients}&amp;gt;&amp;lt;/input&amp;gt;
        &amp;lt;/div&amp;gt;
    )
})}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, to make sure these inputs are also controlled and are being stored in the new recipe state object, I wrote a function to keep the array updated. I had to keep in mind that retrieving elements this way gives an HTML collection, and not an array that I can iterate through in the way I wanted, so I used a spread operator to convert the data from a collection to an array that I could use. I then filter out any of the inputs that don't have any text in them and store the resulting array in the new recipe state object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function handleIngredients() {
    const ingElements = document.getElementsByClassName("add-ingredient");
    const convIng = [...ingElements];
    const newIngArr = convIng.filter((ing) =&amp;gt; ing.value.length &amp;gt; 0).map((ing) =&amp;gt; ing.value)
    console.log(newIngArr);
    setNewRecipe({...newRecipe, ingredients: newIngArr});
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recipe Manager 2.0 is now functioning the way that I want it to - at least for now. In the future I plan on adding functionality that will display recipes based on an ingredient search, rather than only searching by recipe name. I would also like to filter by tags and include embedded videos from the recipe's author if one is available.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>programming</category>
    </item>
    <item>
      <title>My Recipe Manager Project</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Mon, 07 Feb 2022 17:22:42 +0000</pubDate>
      <link>https://dev.to/lorenmichael/my-recipe-manager-project-4h66</link>
      <guid>https://dev.to/lorenmichael/my-recipe-manager-project-4h66</guid>
      <description>&lt;p&gt;Today I wrapped up working on my first project. I decided to make a recipe manager that can help me with meal planning every week. The basic concept is that I can use this site to enter in recipes with forms for their ingredients, instructions, where it came from, etc... and have them all get stored in my own database to pull up later. &lt;/p&gt;

&lt;h2&gt;
  
  
  Figuring out a database
&lt;/h2&gt;

&lt;p&gt;First I had to figure out a database. I referenced some free recipe API's on the internet, but for my vision there was just too much information and it felt too bulky. Instead, I created my own json file and figured out exactly what information I wanted to be able to store. I started with basic things like the name of the recipe, the link where I found it, an image, ingredients and instructions. Knowing what information I wanted to save, I created a form on the site to allow me to input all of this information. Then I wrote a function that creates a recipe object when the form is submitted, then that recipe object gets posted to the database. Here is an example of one of the recipe objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
      "img": "https://www.rabbitandwolves.com/wp-content/uploads/2018/07/DSC_0872.jpg",
      "video": "",
      "name": "Vegan Caesar Pasta Salad",
      "source": "https://www.rabbitandwolves.com/caesar-pasta-salad-vegan/#recipe",
      "author": "Lauren Hartmann",
      "mealtype": "Side",
      "preptime": "10 mins",
      "cooktime": "30 mins",
      "servings": "6",
      "instructions": [
        "Cook your pasta according to package directions. Drain and let cool. ",
        "Make the dressing. Add all the dressing ingredients to a blender. Blend until smooth, taste and adjust seasoning. ",
        "Once the croutons are done, in a large bowl, add the chopped romaine, pasta, croutons and then pour the dressing on and toss. Serve immediately. "
      ],
      "ingredients": [
        "1/2 C. Vegan Mayo",
        "2 tsp. Dijon mustard",
        "1 Tbsp. Capers",
        "Juice of 2 Lemons, about 2 Tbsp.",
        "2 Tbsp. Nutritional yeast",
        "1 Clove Garlic",
        "1/4 tsp. Salt",
        "Pinch of black pepper",
        "1 Head Romaine, chopped",
        "16 oz. Pasta"
      ],
      "comments": [
        "Omitted the crouton portion of the recipe as we don't make them.",
        "Mini penne is perfect",
        "We don't use nutritional yeast in our dressing, and only use half a lemon."
      ],
      "id": 17
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Rendering is fun!
&lt;/h2&gt;

&lt;p&gt;In many places, I encountered the need to iterate through arrays, including the recipes themselves. As an example, I decided to use some forEach loops to render the recipe names in a list:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;function renderAllRecipes(recArr) {&lt;br&gt;
    recArr.forEach(renderOneRecipe)&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Of course, the renderOneRecipe is much more involved, but this was a powerful way to be able to iterate through each of the items in my database and simply pick out the name of the recipe to display it as an option. Now, when our page loads, we see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xHiZJKxH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9nhpnolyx0sq0v29khaq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xHiZJKxH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9nhpnolyx0sq0v29khaq.png" alt="RecipeManager1.0" width="736" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember when I mentioned that the renderOneRecipe function was a little more involved? Well, I had to make sure that I was not only displaying the name of the recipe as the inner text of my list item, I also set the id of each of them to the id number of the recipe and added an event listener so that you can click on them to load the entire recipe. I use the id number set from the original fetch to fetch the entire recipe card and display each of the relevant elements on the page in a meaningful way. I made sure that my images would be the same size, I made sure that credit was given and source links provided for each recipe that I use from somewhere else on the web, and I iterated over any arrays in my recipe object to display lists where they're needed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting around without reloading
&lt;/h2&gt;

&lt;p&gt;I also wanted to build some navigational functionality, but without having to reload the page to go between recipes and details. I was able to use two different methods to demonstrate this. For one, I use part of my function to change the display parameter of an element from inline-block to none and vice versa. These two lines of code look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;recListSec.style="display: inline-block";&lt;/code&gt;&lt;br&gt;
and&lt;br&gt;
&lt;code&gt;recListSec.style="display: none";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The other method I used to hide elements was by assigning or removing the "hide" class to things I wanted to be hidden. These lines looks like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;selectBar.classList = "hide";&lt;/code&gt;&lt;br&gt;
and&lt;br&gt;
&lt;code&gt;selectBar.classList.remove("hide")&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, when we go back and forth between the index view and a recipe details view, we don't see things that aren't relevant to the details view.&lt;/p&gt;
&lt;h2&gt;
  
  
  Form building
&lt;/h2&gt;

&lt;p&gt;Now to tackle some forms. I wanted to create a way to enter in all of the information I need for a new recipe. Things like "recipe name" and "servings" are pretty straightforward, but every recipe is different. How do I know how many ingredients are on the list? How many steps are there? Instead of filling up the page with empty boxes, I decided to make a button that would give you a new text box so you never have more than you need. (Don't worry if you hit it too many times, I have a solution for that too!) From there, I wrote a function called createNewRecObj that takes the information from the form and enters it into a new object that then gets sent to a fetch method to POST it to the database. Here is the createNewRecObj function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createNewRecObj (e) {
    e.preventDefault();

    // Ingredient array
    let ingArr = [];
    let ingColl = document.getElementsByClassName("add-ingredient");
    for (let i = 0; i &amp;lt; ingColl.length; i++) {
        if (ingColl[i].value.length &amp;gt; 0) {
            ingArr.push(ingColl[i].value)
        }
    };

    // Instruction array
    let instrArr = [];
    let instrColl = document.getElementsByClassName("add-instructions");
    for (let i = 0; i &amp;lt; instrColl.length; i++) {
        if (instrColl[i].value.length &amp;gt; 0) {
            instrArr.push(instrColl[i].value)
        }
    };

    // Comment array
    let commArr = [];
    if (document.getElementById("init-comm").value.length &amp;gt; 0) {
        commArr.push(document.getElementById("init-comm").value)
    };

    // Create the new recipe object that will get sent to the database
    let newRecObj = {
        img: document.getElementById("add-img").value,
        video: document.getElementById("add-video").value,
        name: document.getElementById("add-name").value,
        source: document.getElementById("add-source").value,
        author: document.getElementById("add-author").value,
        mealtype: document.getElementById("add-meal-selector").value,
        preptime: document.getElementById("add-preptime").value,
        cooktime: document.getElementById("add-cooktime").value,
        servings: document.getElementById("add-servings").value,
        instructions: instrArr,
        ingredients: ingArr,
        comments: commArr
    }
    postNewRecipe(newRecObj);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking into this code a little more, we can see that I'm making  three arrays. Looking at the ingredient array, we can see that I am finding each of the text boxes being used for the ingredient list, using a for...of loop to iterate through them, and also looking at the value length to make sure that I'm not adding an empty string to my array.&lt;/p&gt;

&lt;p&gt;Then, we simply take each of the form inputs and assign them to their proper key in the object, and send them off to my postNewRecipe function with the newly made recipe object as the argument.&lt;/p&gt;

&lt;p&gt;To post, we fetch our resource, tell it we're making a POST with content-type of application/json, and in the body of our POST, stringify our recipe object. This will add our new recipe to the database, and the page will revert to displaying the recipe list with our newly added recipe included.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving forward and a note on accessibility
&lt;/h2&gt;

&lt;p&gt;Obviously, there were many other features added to this project and I don't want to nitpick over each and every one of them. I plan on continuing to work on this to add more functionality in the future. If you noticed in the original recipe database item at the top, there are some other tags that aren't used quite yet, like "video embed" and "tags". I would like to find a way to use those things in future versions of this project.&lt;/p&gt;

&lt;p&gt;I also am learning the importance of making things as accessible as possible. There are parts of this project that are not as accessible as they could be, so I plan to update them as I learn more about javascript to demonstrate that I am able to consider users of all abilities who might like to use this project moving forward.&lt;/p&gt;

&lt;p&gt;Thank you for looking over my project! Make sure you check it out in the future for new versions!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>flatiron</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Rendering: Half-Full or Half-Empty?</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Thu, 06 Jan 2022 20:41:21 +0000</pubDate>
      <link>https://dev.to/lorenmichael/rendering-half-full-or-half-empty-581n</link>
      <guid>https://dev.to/lorenmichael/rendering-half-full-or-half-empty-581n</guid>
      <description>&lt;p&gt;Today I was working on a lab for my Flatiron courses and noticed a note:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Pessimistic rendering is recommended."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well what the heck does that mean? Is my program feeling low? Down? Defeated? (Sometimes I do when I hit a snag, but that's no reason for the program to feel that way...)&lt;/p&gt;

&lt;p&gt;I quickly learned that there are two different forms of rendering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pessimistic&lt;/li&gt;
&lt;li&gt;Optimistic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In today's world of instant gratification, users generally don't want to wait for anything to load. It's understandable - with fast internet and apps that are designed for delivering information fast, we've just gotten used to it. When you are coding, it's smart to keep this in mind, because often you will discover changes you can make that will update your DOM but won't necessarily require you to reload/refresh your entire page. This kind of rendering is referred to as Optimistic, because it assumes that the server will update the database with the new information and doesn't depend on having to go through another load and fetch and render to display the new information. It simply says, 'oh, I see that you like this. I trust my program will update the database for you, so I'll just mark down your like really quick so you can continue browsing."&lt;/p&gt;

&lt;p&gt;On the flip side, the pessimistic way of rendering these changes involves the rigmarole of sending a patch, reloading the page, fetching the new data, rendering everything all over again... it's not very trusting of your program and though it might not take a very long time, any time spent reloading might allow the user a moment to turn their attention elsewhere.&lt;/p&gt;

&lt;p&gt;Optimistic rendering is obviously more desirable if you're trying to keep the user's attention on your program, but there are pros and cons to each style. Optimistic approaches work best with pretty simple tasks - tasks like "liking" things. When you get into more complicated tasks, like filling out forms or making a purchase, that's when you need the functionality of pessimistic rendering. It will be more accurate and dependable than making a visual change and hoping that it saved in the back-end.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>flatiron</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>innerText vs textContent</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Wed, 08 Dec 2021 22:19:26 +0000</pubDate>
      <link>https://dev.to/lorenmichael/innertext-vs-textcontent-3c4o</link>
      <guid>https://dev.to/lorenmichael/innertext-vs-textcontent-3c4o</guid>
      <description>&lt;p&gt;As I was going through some lessons about manipulating the DOM, we were presented with two ways to change the text of a node (or, more commonly, an HTML element):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.innerText&lt;/strong&gt;&lt;br&gt;
and&lt;br&gt;
&lt;strong&gt;.textContent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While their functions appear to be similar - take the text in an node and change it to something else - they actually work pretty differently when taking a closer look.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's start with .textContent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From what I've learned so far, this method will return the text in a node while also taking spacing into consideration. It will give you all of the raw text inside the node, including some text that might be hidden from users. It also can be used on all node objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Moving on to .innerText&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you use .innerText, you will have returned to you &lt;em&gt;only&lt;/em&gt; the text inside the node returned to you without any additional spacing included. It will only give you the &lt;em&gt;visible&lt;/em&gt; text that gets shown to users. Interestingly, because of the way that .innerText takes the extra computing time to look at the layout, it can feel sluggish and is more demanding on your system. &lt;/p&gt;

&lt;p&gt;Looking at them side by side, it seems that using .textContent is generally the habit you want to create when you're changing some text in your DOM.&lt;/p&gt;

&lt;p&gt;Oh, and I haven't really learned about .innerHTML yet, but maybe when it comes up I'll revisit and compare all three together.&lt;/p&gt;

</description>
      <category>flatiron</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>node</category>
    </item>
    <item>
      <title>Knowing Where to Start</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Wed, 01 Dec 2021 18:45:51 +0000</pubDate>
      <link>https://dev.to/lorenmichael/knowing-where-to-start-ae</link>
      <guid>https://dev.to/lorenmichael/knowing-where-to-start-ae</guid>
      <description>&lt;p&gt;I've discovered as of late that &lt;strong&gt;knowing where to start is half the battle&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When I am approaching a function I need to write for a lab, I can think of the different methods I need to use to complete the assignment, but I struggle a lot with knowing where to start. I might try working backwards for a change, starting with defining what I need to see in my output and working back from there.&lt;/p&gt;

&lt;p&gt;Has anyone else faced this kind of hurdle? How did you overcome it? Practice, practice, practice?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>flatiron</category>
    </item>
    <item>
      <title>Note Catch-up</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Mon, 29 Nov 2021 16:57:40 +0000</pubDate>
      <link>https://dev.to/lorenmichael/note-catch-up-35g3</link>
      <guid>https://dev.to/lorenmichael/note-catch-up-35g3</guid>
      <description>&lt;p&gt;Over the Thanksgiving holiday I traveled and didn't have access to my desktop computer (I know, I know - who has a desktop anymore?) so I spent a little bit of time going back through some lessons and making notes using VSC. It helped my understanding tremendously to go back and type functions out myself. Running the notes is not possible, because I like to practice and see the progression of functions and sometimes that involves assigning the same variable multiple times. But these notes are not meant to be functional, they are meant to give me a well organized way to return to a concept and review it quickly.&lt;/p&gt;

&lt;p&gt;I highly recommend making files of notes as you're learning, it helps quite a bit with the more complicated concepts.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>flatiron</category>
    </item>
    <item>
      <title>Note Taking 101</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Fri, 12 Nov 2021 19:11:33 +0000</pubDate>
      <link>https://dev.to/lorenmichael/note-taking-101-5b05</link>
      <guid>https://dev.to/lorenmichael/note-taking-101-5b05</guid>
      <description>&lt;p&gt;While going through Flatiron's Pre-Work and part of Phase 1, I've been taking notes in a Moleskine. While it's my favorite way to retain information (I learn well by writing things down in my own handwriting) it definitely leaves much to be desired. Writing out JS by hand is a pain if you're trying to show yourself examples of the concept you're studying. It takes up a lot of paper very quickly with how many lines it takes up, and the hand cramps!&lt;/p&gt;

&lt;p&gt;I've started to experiment with different ways to take notes while going through class. My newest method will be to keep notes organized in .js files that give examples of how different functions work. The latest concept I've gone over are Arrow Functions, so I built a file that shows progression from a regular function to a function expression then to an arrow function. It came in handy while doing my lab work, so I will likely continue this to see if it is helpful with more complex concepts.&lt;/p&gt;

&lt;p&gt;Long term I'm hoping it will be a go-to resource of my own notes and code examples so that when I come across these concepts later on I have a file that I can go to if I'm having trouble.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>motivation</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>The journey begins...</title>
      <dc:creator>loren-michael</dc:creator>
      <pubDate>Tue, 09 Nov 2021 17:55:56 +0000</pubDate>
      <link>https://dev.to/lorenmichael/the-journey-begins-313m</link>
      <guid>https://dev.to/lorenmichael/the-journey-begins-313m</guid>
      <description>&lt;p&gt;In the last couple of days I finished up the Software Engineering course pre-work for Flatiron School. I feel like my basic knowledge of HTML, CSS, JavaScript has expanded but it also feels like I've only just scratched the surface.&lt;/p&gt;

&lt;p&gt;In the coming weeks I'll be juggling course work with the holiday season. This means converting to using my laptop to do work at my mother's house while visiting for a couple of weeks over Thanksgiving. I'm hoping that I will be able to build out my own basic website very soon, and that as I learn more I'll be able to update it with new and exciting features.&lt;/p&gt;

&lt;p&gt;I hope to make blogging a regular part of my learning process going forward, both to keep track of my own progress and show others how easy it is to pick up new skills. I'm coming to this at age 36, just left an old career because of covid-19 based anxieties (I was a production manager and live sound engineer at a venue here in Chicago) and wanting a lifestyle change.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>career</category>
      <category>todayilearned</category>
    </item>
  </channel>
</rss>
