<?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: Brennan Davis</title>
    <description>The latest articles on DEV Community by Brennan Davis (@btdavis300).</description>
    <link>https://dev.to/btdavis300</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%2F892554%2F08f9ee05-7786-411b-a3a1-dbeb9ec9c25c.jpeg</url>
      <title>DEV Community: Brennan Davis</title>
      <link>https://dev.to/btdavis300</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/btdavis300"/>
    <language>en</language>
    <item>
      <title>Tailwind, Flowbite, React, oh my.</title>
      <dc:creator>Brennan Davis</dc:creator>
      <pubDate>Thu, 06 Oct 2022 16:48:36 +0000</pubDate>
      <link>https://dev.to/btdavis300/tailwind-flowbite-react-oh-my-gf2</link>
      <guid>https://dev.to/btdavis300/tailwind-flowbite-react-oh-my-gf2</guid>
      <description>&lt;p&gt;If you are familiar with CSS, you probably have found it slightly frustrating to troubleshoot your styling. You made your styling code in your css file, you double check your names or ids, then you open your browser to see if anything has changed. It's a laborious workflow. Fortunately, their are styling frameworks to help you style your front-end with ease. Specifically, Tailwind is a styling framework that can speed your up your workflow so you can worry about more important things.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tailwindcss.com/"&gt;Tailwind&lt;/a&gt; is a framework for css that uses class names to style your projects. The documentation on their website is very clear and concise.&lt;/p&gt;

&lt;p&gt;To install Tailwind for React:&lt;/p&gt;

&lt;p&gt;Make a new project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app my-project
cd my-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;***It's important to be in your react directory when you install Tailwind.&lt;/p&gt;

&lt;p&gt;Next install Tailwind:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands will install taildwind, postcss, and autoprefixer. These allow you to use tailwind's classnames for your styling.&lt;/p&gt;

&lt;p&gt;Next in your &lt;code&gt;tailwind.config.js&lt;/code&gt;, add all these paths to your tailwind template file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last step is to add these directives in your main CSS files (usually it's in './src/index.css'):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Tailwind is installed. Let's go through some examples in how to implement this styling framework...&lt;/p&gt;

</description>
    </item>
    <item>
      <title>You Shall Not Pass: The Ins and Outs of Authentication</title>
      <dc:creator>Brennan Davis</dc:creator>
      <pubDate>Sun, 18 Sep 2022 21:01:02 +0000</pubDate>
      <link>https://dev.to/btdavis300/you-shall-not-pass-the-ins-and-outs-of-authentication-5e4</link>
      <guid>https://dev.to/btdavis300/you-shall-not-pass-the-ins-and-outs-of-authentication-5e4</guid>
      <description>&lt;h2&gt;
  
  
  As I was finishing up my fourth phase at Flatiron School
&lt;/h2&gt;

&lt;p&gt;we learned about how to make a login/signup feature on web applications using an authentication process. This phase in my software development program is centered around the fullstack framework Ruby on Rails. It's quite a power language that can do both frontend and backend programming. &lt;/p&gt;

&lt;p&gt;The process to make a website secured through an login or signup authentication process can be very complicated. I definitely had some trouble getting this process down, so I decided the best way to climb this mountain was to write a blog about it to fully conquer authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y6jnqb2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjvrsio8skk0o1djooqn.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y6jnqb2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjvrsio8skk0o1djooqn.jpeg" alt="Ace Venture When Nature Calls" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are familiar with Ruby on Rails, you probably are know about Gemfiles. They are project dependencies, similar to node modules, that have pre-made code that does a lot of heavy lifting for you, so you can focus on other aspects of your project. We will be using BCrypt.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bcrypt-ruby/bcrypt-ruby"&gt;BCrypt&lt;/a&gt; is a hefty gemfile that uses hashes and salts to encrypt passwords in your database.  Hashes are a fixed-length value that will always produce the same output for the same given input. The output can be a 32-bit or 64-bit number. What BCrypt does, is add a salt to this hash, which is an additional 29-bit number that generates a new salt every time you login with your password. This method makes it incredibly difficult to hack into the database to reveal the actual password to a user.&lt;/p&gt;

&lt;p&gt;Additionally, this gem adds three methods that the user model can use to read, write, and encrypt passwords:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;password=
password_confirmation=
authenticate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  As there are many ways to authenticate,
&lt;/h2&gt;

&lt;p&gt;this is the method I have found to work (after a lot of troubleshooting). There is a lot to set up, but there is flexibility in how you implement your ruby methods and display your data in the front end. For this example, I am using Ruby v.2.7.4, Rails v.6.1.3 along with React v.17.0.2 and React Dom v.5 for my frontend framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup Work Flow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install gemfiles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are starting a new rails project, these are some important gems to include in your Gemfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem 'bcrypt', '~&amp;gt; 3.1.7'
gem 'rack-cors'
gem 'pg', '~&amp;gt; 1.1'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something of note is that I use PostgreSQL for my database, and rack-cors as middleware. Rack-cors is usually needed when you are deal with separate frontend and backend projects that work through different domains. Theoretically if you are working on a mono-template, where both ends are in the same parent directory, you won't need rack-cors. When working through this demo, if you encounter any issues related to AJAX or CORS, I would recommend installing rack-cors in your gemfile.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bundle install&lt;/code&gt; to install all of your gem files. Additionally, don't forget to &lt;code&gt;npm install&lt;/code&gt; all your node modules for your frontend (Use this command in your &lt;strong&gt;&lt;em&gt;React&lt;/em&gt;&lt;/strong&gt; folder if your local environment combines both frontend and backend in a parent directory).&lt;/p&gt;

&lt;h2&gt;
  
  
  Next,
&lt;/h2&gt;

&lt;p&gt;we will need to configure Rails to create cookies and sessions (I highly recommend learning about sessions and how Rails interacts with, more info through the &lt;a href="https://guides.rubyonrails.org/action_controller_overview.html#session"&gt;Rails Docs&lt;/a&gt;). Inside the &lt;code&gt;configure/application.rb&lt;/code&gt; file 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;module MyApp
  class Application &amp;lt; Rails::Application
    config.load_defaults 6.1
    config.api_only = true

    config.middleware.use ActionDispatch::Cookies
    config.middleware.use ActionDispatch::Session::CookieStore

    config.action_dispatch.cookies_same_site_protection = :strict
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last line that starts with &lt;code&gt;configu.action_dispatch&lt;/code&gt; is important to include so that cookies are only shared in the same domain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving on,
&lt;/h2&gt;

&lt;p&gt;we need to add a line of code to our &lt;code&gt;app/controllers/application_controller.rb&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ApplicationController &amp;lt; ActionController::API
  include ActionController::Cookies
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create
&lt;/h2&gt;

&lt;p&gt;a user model. I prefer using a resource generator to fast-track some of the coding. In your terminal in your project directory, use this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g resource User name email password_digest 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a user controller, model, serializer, and all CRUD routes in your &lt;code&gt;config/routes.rb&lt;/code&gt; file. The column in your user table can be whatever you would like, but the password_digest column is vital to interact with bcrypt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add
&lt;/h2&gt;

&lt;p&gt;this to the User Model file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;has_secure_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows up to have proper validations for the password.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Whew,&lt;/em&gt;&lt;/strong&gt; that was a lot to set up. Let's start writing some methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sign Up Work Flow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Frontend display a signup form.&lt;/li&gt;
&lt;li&gt;Client submits form, initiating a &lt;code&gt;POST&lt;/code&gt; request to a create method.&lt;/li&gt;
&lt;li&gt;The backend will make sure the data is properly validated. If it is, it will serialize a newly created object (a user row in the User table). If invalid, the server is provide error messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before we talk about the frontend, let's deal with what the server side will do.&lt;/p&gt;

&lt;p&gt;Although not necessary, it is advised to create a custom route for your &lt;code&gt;users#create&lt;/code&gt; method, 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 '/signup', to: 'users#create'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using a custom route will allow to continue to use the &lt;code&gt;create&lt;/code&gt; method for the user controller if you ever need to.&lt;/p&gt;

&lt;h2&gt;
  
  
  In your User Controller
&lt;/h2&gt;

&lt;p&gt;create your strong params, to control what the client can send to the database. In a private method, write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def user_params
      params.permit(:username, :email, :password, :password_confirmation)
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then write your create method:&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)
      if user.valid?
        session[:user_id] = user.id # this is the piece that logs a user in and keeps track of users info in subsequent requests.
        render json: user, status: :ok
      else
        render json: user.errors.full_messages, status: :unprocessable_entity
      end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's breakdown this method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We first declare a variable, that creates and saves a new User object with the &lt;em&gt;user_params&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;If&lt;/em&gt; the user takes in the valid parameters, it will create a new session, using the id of the newly create user variable. This session will allow the client to stay logged in throughout their entire experience using the web application.&lt;/li&gt;
&lt;li&gt;If the user is NOT valid, it will render a json object of error messages that can subsequently be rendered by the frontend to display.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  On the Frontend
&lt;/h2&gt;

&lt;p&gt;this is how I used my frontend to control a form, use &lt;code&gt;State&lt;/code&gt; to create a new object with the form data, and to make a fetch request on submit:&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 } from "react";

function Signup() {
  const [currentUser, setCurrentUser] = useState({})
  const [formData, setFormData] = useState({
    name: "",
    email: "",
    password: "",
  });

  const { name, email, password } = formData;

  function handleChange(e) {
    const { name, value } = e.target;
    setFormData({ ...formData, [name]: value });
  }

  function handleSubmit(e) {
    e.preventDefault();
    fetch(`/signup`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(formData),
    }).then((res) =&amp;gt; {
      if (res.ok) {
        res.json().then((formData) =&amp;gt; {
          setCurrentUser(formData);
        });
      } else {
        res.json().then((errors) =&amp;gt; {
          console.error(errors);
        });
      }
    });
  }

  return (
    &amp;lt;form onSubmit={handleSubmit}&amp;gt;
      &amp;lt;label htmlFor="name"&amp;gt;Username:&amp;lt;/label&amp;gt;
      &amp;lt;input
        id="username-signup-input"
        type="text"
        name="name"
        value={formData.name}
        onChange={handleChange}
      /&amp;gt;
      &amp;lt;label htmlFor="email"&amp;gt;Email:&amp;lt;/label&amp;gt;
      &amp;lt;input
        id="email-signup-input"
        type="text"
        name="email"
        value={formData.email}
        onChange={handleChange}
      /&amp;gt;
      &amp;lt;label htmlFor="password"&amp;gt;Password:&amp;lt;/label&amp;gt;
      &amp;lt;input
        id="password-signup-input"
        type="password"
        name="password"
        value={formData.password}
        onChange={handleChange}
      /&amp;gt;
      &amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  );
}

export default Signup;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;strong&gt;Important Note:&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
When I used the fetch in React, I had issues actually creating a session. What fixed this issue was using back-ticks for the URL in your fetch. I would recommend using these back-ticks as precaution.&lt;/p&gt;

&lt;p&gt;One additional note about the front end is in the onSubmit function: after the &lt;code&gt;POST&lt;/code&gt; request, this function uses a callback function called &lt;code&gt;setCurrentUser&lt;/code&gt; that will set state to the newly created user object. That way you can use a &lt;code&gt;useEffect&lt;/code&gt; hook to call this state upon initial render of the application. That way your front end will know if the current user is logged in when navigating through the webpage.&lt;/p&gt;


&lt;h2&gt;
  
  
  To Display User Information
&lt;/h2&gt;

&lt;p&gt;We need to verify that the current user id matches the session id.&lt;/p&gt;

&lt;p&gt;In your Application Controller, write a method to check if these two ids match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    def current_user
        User.find_by(id: session[:user_id])
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now let's focus back on the User. Create a new custom route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get '/me', to: "users#show"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside your User model, add the appropriate &lt;code&gt;show&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def show
  if current_user
    render json: current_user, status: :ok
  else
    render json: "No current session stored", status: :unauthorized
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the &lt;code&gt;current_user&lt;/code&gt; method in the Application Controller can be inherited in all children controllers, this method is using the current_user method to create a boolean return of either true or false. If true, then render a json object of the current_user's data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Log In/Log Out Workflow
&lt;/h2&gt;

&lt;p&gt;This is a similar workflow to the Sign Up process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write custom routes for the &lt;code&gt;create&lt;/code&gt; and &lt;code&gt;destroy&lt;/code&gt; for your Sessions Controller &lt;/li&gt;
&lt;li&gt;Write the appropriate methods in your Sessions Controller.&lt;/li&gt;
&lt;li&gt;Write the frontend code that practically mimics the Signup component. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't have sessions controller already, use this command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g controller Sessions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Logging In...
&lt;/h2&gt;

&lt;p&gt;In your config/routes.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;post "/login", to: "sessions#create"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your Sessions Controller, write a &lt;code&gt;create&lt;/code&gt; method that would create a user variable that uses &lt;code&gt;:params&lt;/code&gt; from the form in the frontend to find the appropriate user in the database. If the credentials match up, render a json object of the user variable. If they don't match up, render 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;  def create
    user = User.find_by(username: params[:username])
    if user&amp;amp;.authenticate(params[:password])
      session[:user_id] = user.id
      render json: user, status: :ok
    else
      render json: "Invalid Credentials", status: :unauthorized
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then write your front end to take in data from a controlled form and use a &lt;code&gt;POST&lt;/code&gt; request to the /login endpoint. This code should look almost identical to the signup component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logging Out...
&lt;/h2&gt;

&lt;p&gt;In your config/routes.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;post "/logout", to: "sessions#destroy"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your Sessions Controller, write a &lt;code&gt;destroy&lt;/code&gt; method that will delete the current session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def destroy
    session.delete :user_id
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your front end will fetch a &lt;code&gt;DELETE&lt;/code&gt; request to the &lt;code&gt;/logout&lt;/code&gt; endpoint.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4ub3xEhX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2sxv9bvwrnhzkcuczhx9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4ub3xEhX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2sxv9bvwrnhzkcuczhx9.gif" alt="Star Trek Victory" width="366" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AND THAT'S A WRAP.&lt;/strong&gt; Take a couple deep breaths, it's as complicated as you think.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go through this process slowly. Make you sure you understand every part of the code before moving on.&lt;/li&gt;
&lt;li&gt;Think about work flow process for each feature. Go step by step, from the client side to the server side, to write your code.&lt;/li&gt;
&lt;li&gt;If you get errors, use Google. Errors are your friend, you &lt;strong&gt;&lt;em&gt;WILL&lt;/em&gt;&lt;/strong&gt; debug your way through it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hopefully this blog has provided a little bit of clarity to authenticating. Thanks for reading. 'Til next time!&lt;/p&gt;

</description>
      <category>rails</category>
      <category>programming</category>
      <category>ruby</category>
      <category>security</category>
    </item>
    <item>
      <title>Everything In Its Right Place...</title>
      <dc:creator>Brennan Davis</dc:creator>
      <pubDate>Thu, 25 Aug 2022 15:15:00 +0000</pubDate>
      <link>https://dev.to/btdavis300/everything-in-its-right-place-p4n</link>
      <guid>https://dev.to/btdavis300/everything-in-its-right-place-p4n</guid>
      <description>&lt;h2&gt;
  
  
  Hello again!
&lt;/h2&gt;

&lt;p&gt;This is a going to be quite a departure from the usual technical post that I commonly sift through online trying to find the right syntax or how to properly use a Ruby method. I'm going to more or less be talking about, well, about a little band called Radiohead. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Full Disclaimer&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;This post is a doozy, and I begrudgingly talk about myself&lt;/em&gt; &lt;strong&gt;&lt;em&gt;so strap in&lt;/em&gt;&lt;/strong&gt;...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FWHZtqpg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/si95ftvi5t6f50nwq4us.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FWHZtqpg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/si95ftvi5t6f50nwq4us.jpeg" alt="Getty Images Radiohead" width="880" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This band has gotten me through many of my formative years and my relationship with their music has only aged like a fine wine. I was immediately hooked when my best friend in high school showed me "In Rainbows" back in 2008. He put on &lt;a href="https://youtu.be/FcANFVcJeOM"&gt;Weird Fishes/Arpeggios&lt;/a&gt;, and it was like Phil Segway himself gave 4 counts to kick off my entire obsession with this band.&lt;/p&gt;

&lt;p&gt;From Thom Yorke's wispy, yet powerful soaring falsetto melodies, to Jonny Greenwood's arpeggiated strumming, Ed's backup vocals, Phil's drive on drums, or even how almost oxymoronic the spelling of the title was, I was invested.&lt;/p&gt;

&lt;p&gt;I always found inspiration from Radiohead, no matter what avenue in my life I've been lead to. Music has been such a strong part of my life, essentially as far as I can remember (strong enough to make a career out of it). I played violin in elementary school, but only realized my true passion was playing drums at the end of the 5th grade. Once I "discovered" Radiohead (perhaps about 20 years into &lt;em&gt;their&lt;/em&gt; career), they ignited an even more intense musical flame. I loved their used of rhythm, how they can use rhythm as their song structure, adding melodies that soared on top, how they used texture to drown you. They always produced music that no one else could conceive.&lt;/p&gt;

&lt;p&gt;Throughout high school and even college, I used Radiohead as motivation and inspiration to perfect my craft as a percussionist. It never left me that no matter how technical you try to be, it's the emotion in music that makes it impactful.&lt;/p&gt;

&lt;p&gt;Being a previous band director and life-long musician, I've played percussion ensemble literature inspired by Radiohead, I've play arrangements of their pieces, I even WROTE arrangements of Radiohead tunes for groups I've taught (most recently at the last concert I directed before moving to Colorado). I would watch movies that members of the band had written the scores for. Jonny Greenwood, with his immense knowledge of music theory and compositional techniques, has written soundtracks for Paul Thomas Anderson's films, must notably, There Will Be Blood and Phantom Thread. Drawing inspiration from 20th century Polish micro-tonal composer, Krzysztof Penderecki, the work that Greenwood has produced is, in my opinion, worthy of a Nobel Price.&lt;/p&gt;

&lt;p&gt;Thom Yorke composed the score to the 2018 remake of Suspiria, using an entire orchestra at times, without having no knowledge of how to read or write music.  All this to simply drive home the fact that I look up to Radiohead, but not only as musicians, but as creative types...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eXb3YKgS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6mp3yhis259lb8rjwer8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eXb3YKgS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6mp3yhis259lb8rjwer8.jpg" alt="Suspiria, Amazon Studios" width="880" height="1173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leaving the music education field was definitively the hardest decision of my life. As you might have gathered, music has been a part of my life for as far as I can remember. Both of my parents are musicians and this is all I've know until very recently. It took a lot for me to accept that I can still keep my identity as a musician and not make it my day job.&lt;/p&gt;




&lt;p&gt;Turn to now, I am finishing up my 3rd project at Flatiron School, studying to become a Full Stack Developer. I am LOVING all the new skills I am learning as a software developer. Not only technical, but how creative you can be with developing apps is fascinating.&lt;/p&gt;

&lt;h2&gt;
  
  
  On my drives to school
&lt;/h2&gt;

&lt;p&gt;I will often listen to podcasts to pass the time (and to keep my mind off traffic on i25). I recently started listening to a podcast called &lt;a href="https://podcasts.apple.com/us/podcast/what-is-music-a-music-podcast-about-music/id1495393991"&gt;"What is Music? A  Music Podcast about Music"&lt;/a&gt; hosted by Adam Scott Glasspool, Steve Murphy, and Lucas Way. Hm, a music podcast talking about music, sounds like something I could get behind.&lt;/p&gt;

&lt;p&gt;The latest season is discussing all things Radiohead. They go through their &lt;strong&gt;ENTIRE&lt;/strong&gt; discography, song by song, and pick it apart. I have struck the gold mine. I've skipped ahead to their breakdown of the 2000 record &lt;em&gt;Kid A&lt;/em&gt;, it's one of my favorite records of all time. This podcast is practically an academic research report, enriched with Radiohead lore and analysis.&lt;/p&gt;

&lt;p&gt;They talk about things I never even heard of before; Radiohead was Internet pioneers back at the turn of the century. They were the first to stream their music on their website. Members of the band would blog during the recording of Kid A (back in 1998?!?), they would leak songs of this new record online, before their LP release, to give fans a taste to what to expect when they toured with the new album. They concocted an "anti-marketing" strategy, not promoting their new album through interviews and photo shoots, but through digital art manipulations with the help of Stanley Donwood, distorting paints and pictures of the band. They curated their own marketing campaign, to counter the global commodification of music.&lt;/p&gt;

&lt;p&gt;They knew the Internet was going to blow up back, even as early as the 90's when they started releasing their music to the public online. I mean, they were Napster before Napter was &lt;em&gt;NAPSTER&lt;/em&gt;. This wasn't the only time they used the internet for promotion. For the release of their In Rainbows, they set up a "set you price" store on their website for the record. Fans would purchase a digital copy at whatever cost they deemed fit.&lt;/p&gt;

&lt;p&gt;Radiohead reinvented themselves through Kid A. Once known as a 90's grunge band, they all came to terms of Thom Yorke's visionary idea of relying heavily on electronics for this new record. Ed, the lead guitarist, is playing synths, Thom Yorke is using Protools to distort his voice in at least four songs, Phil is playing drum machines, Jonny using the &lt;a href="https://en.wikipedia.org/wiki/Ondes_Martenot"&gt;Ondes Martenot&lt;/a&gt; on tracks, EVEN to manipulate Thom's voice! You'd think this was a John Cage inspired avant-garde group you'd see in a basement of a pizza shop in a college town (shoutout to J&amp;amp;J's Pizza in Denton, Texas, rest in peace).&lt;/p&gt;

&lt;p&gt;Listening to this podcast, Radiohead gave me inspiration, but in a different way. Radiohead gave me the OK (Computer) to reinvent myself. It's a part of life, to change and grow and evolve. As I continue my education as a computer programmer, I'll use my background as a musician to help propel myself forward in the tech field, and to redefine who I am. Change is inevitable, and it's about what you do with that change that defines you. Everything is indeed, in its right place.&lt;/p&gt;

</description>
      <category>music</category>
      <category>radiohead</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>The KonMari method of JS: variables.</title>
      <dc:creator>Brennan Davis</dc:creator>
      <pubDate>Wed, 03 Aug 2022 17:06:00 +0000</pubDate>
      <link>https://dev.to/btdavis300/the-konmari-method-of-js-variables-3cff</link>
      <guid>https://dev.to/btdavis300/the-konmari-method-of-js-variables-3cff</guid>
      <description>&lt;h2&gt;
  
  
  Have you ever
&lt;/h2&gt;

&lt;p&gt;been in a mad-frenzy of code writing and you came back to it the next day and asked, "How does any of this make sense?" Have you ever looked at your code and thought it messy and unorganized? Well, there is a solution to all of your muddied code, and it's called &lt;strong&gt;&lt;em&gt;variables&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Yes, variables are not a new concept for anyone who has even dipped their toes into computer programming, but variables are a huge helper in code consolidation. When writing out functions, think of variables as the your rooms to your home. Each room is typically dedicated to a specific purpose; the kitchen contains all your cookware, plates, silverware, while your bathroom contains all of your toiletries or self-care items. Essentially, rooms are containers for specific items with specific purposes. That's how you can start to think about using variables. If you have a function that can work on multiple features or event listeners, well then, use variables so you are not writing the same function over and over again. Let's get a closer look at this concept...&lt;/p&gt;




&lt;p&gt;Say you want to display a collection of book information on a webpage. You want the user to be able to sort the books by different categories, either by book title, author, or publisher. So your book collection is set up in an array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;books = [
    {
        title: "\"The Hunger Games\","
        author: "Suzanne Collins",
        publisher: "Scholastic"
    },
    {
        title: "\"In Cold Blood\","
        author: "Truman Capote",
        publisher: "Random House",
    },
    {
        title: "\"Invisible Monsters\","
        author: "Chuck Palahniuk",
        publisher: "WW Norton",
    },
    {
        title: "\"Fight Club\","
        author: "Chuck Palahniuk",
        publisher: "WW Norton",
    },
    {
        title: "\"The Shining\","
        author: "Stephen King",
        publisher: "Doubleday",
    }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You want users to click different buttons to sort the collection by categories. After some simply HTML and DOM manipulation, with some CSS styling to pretty it up, here is what the webpage looks like: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--55KYTkcu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z547g7hkqaovurwfjh0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--55KYTkcu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z547g7hkqaovurwfjh0l.png" alt="Webpage Display" width="880" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look at what the html code looks like for the buttons, this will determine how we write our functionality: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tOscGueK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jj8aj69snjf2i8wecfv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tOscGueK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jj8aj69snjf2i8wecfv2.png" alt="button code" width="880" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that each button tag has its own id. This how we can grab each button in our JavaScript. We also added an in-line &lt;br&gt;
&lt;code&gt;onclick&lt;/code&gt; event listener function called "categorySort" that we will flesh out in a moment.&lt;/p&gt;

&lt;p&gt;We &lt;em&gt;could&lt;/em&gt; simply write a function for &lt;strong&gt;EACH&lt;/strong&gt; button that uses the &lt;code&gt;.sort()&lt;/code&gt; array method to sort the book array. For instance, our function to sort by title could look something 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 sortedArray = books.sort(
        function (bookA, bookB) {
            return bookA.title.localeCompare(bookB.title)
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is fine and it will totally work, but this function will &lt;strong&gt;ONLY&lt;/strong&gt; work for sorting by title. We will have to write two more functions that look exactly the same in order to sort by the other categories, the only difference is our dot notation will resemble the key we want to grab (book.author and book.publisher). What if we have more categories we wanted to sort? What if each object in our array contained &lt;strong&gt;&lt;em&gt;50&lt;/em&gt;&lt;/strong&gt; keys and we wanted our webpage to be able to sort by all of these keys? Our code would start to look unnecessarily long for one simple feature. That's where our friend variable comes into play...&lt;/p&gt;




&lt;h2&gt;
  
  
  Let's turn our key into a variable
&lt;/h2&gt;

&lt;p&gt;so we only write ONE function for all three buttons. Now let's write our code for the "categorySort" function:&lt;/p&gt;

&lt;p&gt;We first want to declare variable that takes the id name of whichever button we press:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function categorySort(event) {
    const category = event.target.id
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will need to pass the event as a parameter in the function declaration so we can use it for each button. The variable &lt;code&gt;category&lt;/code&gt; returns a string which will match the proper key we are trying to sort by. We can use this variable in our sort function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sortedCategory = books.sort(
        function (bookA, bookB) {
            return bookA[category].localeCompare(bookB[category])
        }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We declared &lt;strong&gt;ANOTHER&lt;/strong&gt; that uses our previous variable to sort the books array. We will then pass &lt;code&gt;sortedCategory&lt;/code&gt; to our &lt;code&gt;bookDisplay&lt;/code&gt; function to re-render our display of books. The finished code should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2he2KNV5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8h02wc5iu3fkltzpkqby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2he2KNV5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8h02wc5iu3fkltzpkqby.png" alt="categorySort" width="880" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Viola!&lt;/em&gt;&lt;/strong&gt; We have successfully write &lt;em&gt;one&lt;/em&gt; function for each button we created. If you are interested in looking at the full code, click this &lt;a href="https://github.com/btdavis300/phase-2-blog"&gt;link&lt;/a&gt; to view my repo to this blog post.&lt;/p&gt;




&lt;p&gt;As a more complicated example, we can also use multiple variables to write one function. If you are privy to React, we can write a function that will set state to multiple states. We would like to remove one item from an array, that is passed through as a parameter, and set state. So the code can look something 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;function removeStateList(deletedItem, state, setStateFunction) {
    const updatedState = state.filter(item =&amp;gt; item.id !== deletedItem.id)
    setStateFunction(updatedState)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when we invoke the function we can pass whatever variables we want as arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    removeStateList(selectedItemOne, stateOne, setStateOne)
    removeStateList(selectedItemTwo, stateOne, setStateTwo)
//etc...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used three different parameters to write one function. It's coding &lt;strong&gt;&lt;u&gt;MAGIC!&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Takeaways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Variables can be thought of as containers that can be used as a specific feature on your webpage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can use variables that make our code dynamic and to keep it DRY. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can use multiple parameters in a function to avoid repetition.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thank you for reading my post about variables. See you next time!  &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Say hello to my little (VERY helpful) friend: console.log()</title>
      <dc:creator>Brennan Davis</dc:creator>
      <pubDate>Fri, 15 Jul 2022 19:25:08 +0000</pubDate>
      <link>https://dev.to/btdavis300/say-hello-to-my-little-very-helpful-friend-consolelog-37fi</link>
      <guid>https://dev.to/btdavis300/say-hello-to-my-little-very-helpful-friend-consolelog-37fi</guid>
      <description>&lt;h2&gt;
  
  
  If you are anything like me
&lt;/h2&gt;

&lt;p&gt;you got into the tech field from switching careers. You wanted some different. You wanted a new challenge. You wanted to work in a field that is as inclusive as it's advertised. The start of my journey into software engineering was &lt;strong&gt;very&lt;/strong&gt; exciting, but very daunting. You are welcomed with your first "Hello World!" and feel as if this new field will be streamlined, the learning will be a steady climb, and each new concept will be easier to grasp than the last.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;...That was far from the truth.&lt;/em&gt; I was bombarded with new terminology, my progress was as uneasy as a sine wave, and every time I learned a new concept I felt like I was starting from scratch. Fortunately, it &lt;strong&gt;DOES&lt;/strong&gt; get better.&lt;/p&gt;

&lt;p&gt;The colloquial antidote "Practice Makes Perfect" is by far one of the best practice methods to learn a new language or concept in software development, but sometimes you can spin your wheels trying to solve a problem. I definitely encountered this numerous of times when I first started the Software Engineering program at &lt;a href="https://flatironschool.com/"&gt;Flatiron School&lt;/a&gt; (shout to Flatiron, if anyone is interested in a proven bootcamp, I would definitely recommend checking out their programs they offer.) I would learn a new topic, try to play around with the code, and attempt one of their labs. I would routinely be "stumped" and couldn't understand why I wasn't able to get my code to work. Fortunately, there was someone, or rather, &lt;em&gt;something&lt;/em&gt; that was about to take me under its wing and show me the way of debugging. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pPDVsqRs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gu06wwe4aiwpdt7jk99m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pPDVsqRs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gu06wwe4aiwpdt7jk99m.gif" alt='"This is the way" from The Mandalorian on Disney+.' width="498" height="331"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Console.log()
&lt;/h3&gt;

&lt;p&gt;is your friend! I use console.log &lt;strong&gt;CONSTANTLY&lt;/strong&gt; when I am writing new code. It can help you uncover a wide array of errors, small and large. My golden rule when writing code is to console.log() almost every step of the process. Might be over the top, but I don't want errors to suddenly start popping up down the line when my code becomes much more complicated.  Sometimes the error would be so small, and right in front of my face, I wouldn't be able to find it. That's where console.log() can really save you a lot of time and frustration 😅. Let me show you the method to my madness...&lt;/p&gt;

&lt;p&gt;Let's say we want to use JavaScript to set up some event listeners to two buttons that when pressed, will either add or subtract a number by one in a &lt;/p&gt;
&lt;p&gt; element. If you are interested in looking at the full code for this example, click this &lt;a href="https://github.com/btdavis300/Devblog1"&gt;link&lt;/a&gt;. So here is my HTML code that I have set up for this example...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Ek8k1Es--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stwh3ib4eh54c8j0auoe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Ek8k1Es--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stwh3ib4eh54c8j0auoe.png" alt="html code" width="880" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above is my HTML that wrote in &lt;a href="https://code.visualstudio.com/"&gt;VSCode&lt;/a&gt;. The two things to pay attention to are the id names and the location of my &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;. The id names for the &lt;code&gt;p&lt;/code&gt; and two &lt;code&gt;button&lt;/code&gt; elements are important because I will reference them in my JavaScript. The &lt;code&gt;script&lt;/code&gt; tag is in my head element. If you are going to put your script in your head, it is highly recommended to use the &lt;strong&gt;defer&lt;/strong&gt; attribute, so your JavaScript loads after the HTML page has been loaded. That way, JS can see what it's going to use its functional magic on.&lt;/p&gt;

&lt;p&gt;Moving along, once we set up our HTML file, and we have our script in and ids, I was to first our FIRST console.log() to make sure everything is working. Write this line of code in your .js file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log("I am connected!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, open up your HTML file in your browser (don't forget to save your files!), open up your Dev Tools (right click &amp;gt; Inspect if you are a Mac user like myself), and see what the console has told you. Hopefully you will see this message below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p6IeHHkO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yldge7dge8ki0ohle24n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p6IeHHkO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yldge7dge8ki0ohle24n.png" alt="console.log(I am connected!)" width="880" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Congratulations!&lt;/strong&gt; You have your first successful console.log()! What this console is saying to you, is that you have successfully connecting your .js file to your .index file. Imagine writing ALL your JavaScript code and just to simply get a message that reads &lt;strong&gt;"ERR_FILE_NOT_FOUND"&lt;/strong&gt;. You would pull out all of your hair.&lt;/p&gt;




&lt;p&gt;Moving along, let's now target our ids and create variable names, using &lt;code&gt;document.querySelecter&lt;/code&gt; (&lt;code&gt;.getElementById&lt;/code&gt; will also work in this case!) After our variable declarations, you should...YOU GUESSED IT! You should console.log() to make sure you targeted the right elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let add1 = document.querySelector('#add1')
let subtract1 = document.querySelector('#subtract1')
let counter = document.querySelector('#counter')

console.log(add1)
console.log(subtract1)
console.log(counter)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your saved your change, refresh your browser, and your console should say this: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lMnvI8PR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bh3nqqn1a9mtc24corhz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lMnvI8PR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bh3nqqn1a9mtc24corhz.png" alt="console.log() targeted IDs" width="833" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your console has pinpointed your elements, you can hover over each to make sure it's the right element. I find this a necessary step, because if you misspell on of your target, or use wrong syntax, your console will tell you which line is disrupting the code.&lt;/p&gt;

&lt;p&gt;Great, we have our variables, now we need to set up some event listeners to tell JavaScript to &lt;em&gt;listen&lt;/em&gt; for a click to then invoke our functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add1.addEventListener('click', counterPlus)
subtract1.addEventListener('click', counterMinus)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try to think ahead of my steps and you'll discover....yes I'm going to console.log() to check that my event listeners work. The functions I have written above simply have console.log():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function counterPlus() {
    console.log("I was clicked!")
}

function counterMinus() {
    console.log("I was clicked!")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome! My event listeners work! Let's pick up the pace...&lt;/p&gt;




&lt;p&gt;I've set up my code for the counter functions, but I stumbled into a problem. I'm getting an error message:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RUPK_nNP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ouxj8u6iogys9yafmvw6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RUPK_nNP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ouxj8u6iogys9yafmvw6.png" alt="error message1" width="826" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What? I was confident my code works. Let's click on the index line reference on the right side of the console that reads: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;index.js.8&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8p-3Za4Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbks9frchj2bqn8e5ce9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8p-3Za4Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbks9frchj2bqn8e5ce9.png" alt="error message2" width="880" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take an extra close look at the function declaration, what do you notice?&lt;/p&gt;

&lt;p&gt;No &lt;code&gt;()&lt;/code&gt; in the declaration! How does JavaScript know it's a function without it? Thank you console.log(). After some slight edits to my functions we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function counterPlus() {
    counter.textContent = Number(counter.textContent) + 1
}

function counterMinus() {
    counter.textContent = Number(counter.textContent) - 1
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;em&gt;Voila!&lt;/em&gt;, our code works!&lt;/p&gt;




&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;While console.log() is a simple tool that helps you log your code, it can be a &lt;strong&gt;&lt;em&gt;powerful&lt;/em&gt;&lt;/strong&gt; tool that can save you a lot of time and energy wasted on a small mistake like a syntax error. This blog post was a minute example of how you can use console.log(); it can expose what's under the hood that you might not initially realize. Console.log() every step of the way!&lt;/p&gt;

&lt;p&gt;If you have made it this far, thank you for reading my 1st tech blog post.&lt;/p&gt;

&lt;p&gt;'Til next time!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
