<?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: ericksong91</title>
    <description>The latest articles on DEV Community by ericksong91 (@ericksong91).</description>
    <link>https://dev.to/ericksong91</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%2F894680%2F712052a3-d1a3-40e2-9130-34e1e37fb29c.jpg</url>
      <title>DEV Community: ericksong91</title>
      <link>https://dev.to/ericksong91</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ericksong91"/>
    <language>en</language>
    <item>
      <title>Basic Auth Routing and Redirecting using React Router v6</title>
      <dc:creator>ericksong91</dc:creator>
      <pubDate>Thu, 07 Sep 2023 16:27:49 +0000</pubDate>
      <link>https://dev.to/ericksong91/basic-auth-routing-and-redirecting-using-react-router-v6-2i8l</link>
      <guid>https://dev.to/ericksong91/basic-auth-routing-and-redirecting-using-react-router-v6-2i8l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hi y'all,&lt;/p&gt;

&lt;p&gt;This is a quick tutorial on how to utilize some basic authentication routing using React Router v6. This will allow you to protect routes in your application from users who are not logged in. &lt;/p&gt;

&lt;p&gt;You can also include route protection against users who do not have certain group permissions as well (that won't be covered today but would be easy to add).&lt;/p&gt;

&lt;p&gt;I will also go over how to navigate the user back to the page that they were trying to access before logging in. &lt;/p&gt;

&lt;p&gt;Lets get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Our Project
&lt;/h2&gt;

&lt;p&gt;First start by making a new vanilla React project:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-react-app your-project-name&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Move to the directory then type:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install react-router-dom&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Components and Routing
&lt;/h2&gt;

&lt;p&gt;To continue setup, lets make our sample components. &lt;/p&gt;

&lt;p&gt;I'll be creating a &lt;code&gt;components&lt;/code&gt;, &lt;code&gt;auth&lt;/code&gt; and &lt;code&gt;context&lt;/code&gt; folder to house the page components, authentication component and the user component:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0uql6b216kqz61h9pver.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0uql6b216kqz61h9pver.png" alt="File Structure" width="200" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's go ahead and work on our context file, &lt;code&gt;user.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you're unfamiliar with context, you can read up more about context &lt;a href="https://react.dev/reference/react/createContext"&gt;here.&lt;/a&gt; Basically, context allows us to provide a &lt;code&gt;user&lt;/code&gt; token and &lt;code&gt;setUser&lt;/code&gt; function to all of the components in our application. This isn't limited only to &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;setUser&lt;/code&gt;; you can pretty much pass any prop you'd like to any component.&lt;br&gt;
&lt;/p&gt;

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

const UserContext = React.createContext();

function UserProvider({ children }) {
    const [user, setUser] = useState(false);

    return (
        &amp;lt;UserContext.Provider value={{ user, setUser }}&amp;gt;
            {children}
        &amp;lt;/UserContext.Provider&amp;gt;
    )
};

export { UserContext, UserProvider };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll be setting up the &lt;code&gt;user&lt;/code&gt; token as a simple state variable so I can turn it on (&lt;code&gt;true&lt;/code&gt;) or off (&lt;code&gt;false&lt;/code&gt;) with a button. If we had a backend, this is where we would be communicating with the server to verify the user instead.&lt;/p&gt;

&lt;p&gt;Make sure to remember to pass the &lt;code&gt;user&lt;/code&gt;  as well as &lt;code&gt;setUser&lt;/code&gt; props so the other components can access them.&lt;/p&gt;

&lt;p&gt;Next I'll open up my &lt;code&gt;index.js&lt;/code&gt; file in the root of the directory and add these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`index.js`

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter as Router } from 'react-router-dom';
import { UserProvider } from './context/user';
import './index.css';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  &amp;lt;UserProvider&amp;gt;
    &amp;lt;Router&amp;gt;
    &amp;lt;App /&amp;gt;
    &amp;lt;/Router&amp;gt;
  &amp;lt;/UserProvider&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm wrapping my &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; component in &lt;code&gt;&amp;lt;UserProvider&amp;gt;&lt;/code&gt; to give it access to the context file and also the &lt;a href="https://reactrouter.com/en/main/router-components/browser-router"&gt;&lt;code&gt;&amp;lt;BrowserRouter&amp;gt;&lt;/code&gt; component&lt;/a&gt; (renamed to &lt;code&gt;&amp;lt;Router&amp;gt;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;Admin.js&lt;/code&gt; and &lt;code&gt;Homepage.js&lt;/code&gt; let's give them both a generic template and some buttons for navigation using &lt;code&gt;&amp;lt;Link /&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`./components/Admin.js`

import React from 'react'
import { Link } from 'react-router-dom'

function Admin({ setUser }) {
    return (
      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Admin&amp;lt;/h1&amp;gt;
        &amp;lt;Link to="/" replace&amp;gt;&amp;lt;button&amp;gt;Back to Home&amp;lt;/button&amp;gt;&amp;lt;/Link&amp;gt;
      &amp;lt;/div&amp;gt;
    )
}

export default Admin

`./components/Homepage.js`

import React from 'react'
import { Link } from 'react-router-dom'

function Homepage({ setUser }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Homepage&amp;lt;/h1&amp;gt;
      &amp;lt;Link to="/admin" replace&amp;gt;&amp;lt;button&amp;gt;Admin Page&amp;lt;/button&amp;gt;&amp;lt;/Link&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

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

&lt;/div&gt;



&lt;p&gt;Now let's make a some routing in the &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; component and also import the component that we just made.&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, { useContext } from "react";
import { UserContext } from "./context/user";
import Admin from "./components/Admin";
import Homepage from "./components/Homepage";
import { Routes, Route } from "react-router-dom";

function App() {
  const { user, setUser } = useContext(UserContext);

  return (
   &amp;lt;div className="App"&amp;gt;
    &amp;lt;Routes&amp;gt;
     &amp;lt;Route path='/' element={&amp;lt;Homepage /&amp;gt;} /&amp;gt;
     &amp;lt;Route path='/admin' element={&amp;lt;Admin /&amp;gt;} /&amp;gt;
     &amp;lt;Route path="login" element={&amp;lt;Login /&amp;gt;} /&amp;gt;
    &amp;lt;/Routes&amp;gt;
   &amp;lt;/div&amp;gt;
  );
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;To test it, let's run &lt;code&gt;npm start&lt;/code&gt;.&lt;/p&gt;

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

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

&lt;p&gt;Great! Now we have some basic routing and a button that lets us navigate to &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;/admin&lt;/code&gt;! Now that we have all our pages and routes set up, we need to protect them; go into &lt;code&gt;auth.js&lt;/code&gt; and setup the authentication!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`./auth/auth.js`

import React from 'react'
import { useLocation, Outlet, Navigate } from 'react-router-dom';

function AuthLayout({ authenticated }) {
    const location = useLocation();
    return authenticated ? &amp;lt;Outlet /&amp;gt; : &amp;lt;Navigate to="/login" 
           replace state={{ from: location }} /&amp;gt;;    
};

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

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;auth.js&lt;/code&gt;, we're importing useLocation, Outlet and Navigate from react router. &lt;/p&gt;

&lt;p&gt;The return statement here is looking to check whether the prop &lt;code&gt;authenticated&lt;/code&gt; is a truthy or falsey value. &lt;code&gt;true&lt;/code&gt; is if the user is logged in, &lt;code&gt;false&lt;/code&gt; if they're not.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;Navigate /&amp;gt;&lt;/code&gt; will navigate the user to &lt;code&gt;/login&lt;/code&gt; if they're not logged in (&lt;code&gt;user&lt;/code&gt; token reads false). We're saving our user's current location to the &lt;code&gt;location&lt;/code&gt; variable then saving that state using &lt;code&gt;state={{ from: location }}&lt;/code&gt; in &lt;code&gt;&amp;lt;Navigate&amp;gt;&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;(If you &lt;code&gt;console.log(location)&lt;/code&gt;, you can see the state changing every time the url changes; check your console when switching between &lt;code&gt;/admin&lt;/code&gt; and &lt;code&gt;/&lt;/code&gt;!)&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;&amp;lt;Outlet /&amp;gt;&lt;/code&gt; will render out the child components of a parent component; in this case, &lt;code&gt;&amp;lt;AuthLayout /&amp;gt;&lt;/code&gt; will be our parent component. Every child component under &lt;code&gt;&amp;lt;AuthLayout /&amp;gt;&lt;/code&gt; will render normally when the &lt;code&gt;user&lt;/code&gt; token reads &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before we add &lt;code&gt;&amp;lt;AuthLayout /&amp;gt;&lt;/code&gt;, we need to add our &lt;code&gt;&amp;lt;Login /&amp;gt;&lt;/code&gt; component as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./components/Login.js

import React from 'react'
import { useContext } from 'react'
import { UserContext } from '../context/user'

function Login() {
    const { user, setUser } = useContext(UserContext);

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h1&amp;gt;Login&amp;lt;/h1&amp;gt;
            &amp;lt;button onClick={() =&amp;gt; setUser(true)}&amp;gt;Login&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
    )
}

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

&lt;/div&gt;



&lt;p&gt;With this component, the only prop we need is the &lt;code&gt;setUser&lt;/code&gt; function using context. With this function, we can use it to login our user every time they click on the Login button.&lt;/p&gt;

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

&lt;p&gt;Now let's go back to &lt;code&gt;App.js&lt;/code&gt; and finish the routing. This time we'll import the &lt;code&gt;&amp;lt;AuthLayout /&amp;gt;&lt;/code&gt; component and make it the parent component for &lt;code&gt;&amp;lt;Homepage /&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;Admin /&amp;gt;&lt;/code&gt;. We'll also import &lt;code&gt;&amp;lt;Login /&amp;gt;&lt;/code&gt; but keep it unprotected.&lt;br&gt;
&lt;/p&gt;

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

import React, { useContext } from "react";
import { UserContext } from "./context/user";
import Admin from "./components/Admin";
import Homepage from "./components/Homepage";
import Login from "./components/Login";
import AuthLayout from "./auth/auth";
import { Routes, Route } from "react-router-dom";

function App() {
  const { user, setUser } = useContext(UserContext);

return (
&amp;lt;div className="App"&amp;gt;
 &amp;lt;Routes&amp;gt;
  &amp;lt;Route element={&amp;lt;AuthLayout authenticated={user} /&amp;gt;}&amp;gt;
    &amp;lt;Route path='/' element={&amp;lt;Homepage /&amp;gt;} /&amp;gt;
    &amp;lt;Route path='/admin' element={&amp;lt;Admin /&amp;gt;} /&amp;gt;
  &amp;lt;/Route&amp;gt;
  &amp;lt;Route path="login" element={&amp;lt;Login /&amp;gt;} /&amp;gt;
 &amp;lt;/Routes&amp;gt;
&amp;lt;/div&amp;gt;
  );
}

export default App;

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

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;&amp;lt;Route&amp;gt;&lt;/code&gt; component, we add &lt;code&gt;&amp;lt;AuthLayout /&amp;gt;&lt;/code&gt; as the element and pass in the &lt;code&gt;user&lt;/code&gt; prop. Since right now our &lt;code&gt;user&lt;/code&gt; token reads &lt;code&gt;false&lt;/code&gt;, it should automatically redirect us to &lt;code&gt;/login&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;&amp;lt;Login /&amp;gt;&lt;/code&gt; is not a child component of &lt;code&gt;&amp;lt;AuthLayout /&amp;gt;&lt;/code&gt;, &lt;code&gt;/login&lt;/code&gt; is accessible even without a truthy &lt;code&gt;user&lt;/code&gt; token. &lt;/p&gt;

&lt;p&gt;Go ahead and spin up the instance again (or save) to refresh the changes. You should notice immediately that you have been redirected to &lt;code&gt;/login&lt;/code&gt;. Try to manually change the url to &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;/admin&lt;/code&gt; and you'll be redirected to &lt;code&gt;/login&lt;/code&gt; every time. &lt;/p&gt;

&lt;p&gt;Once you hit the Login button on &lt;code&gt;/login&lt;/code&gt;....nothing happens? It's because we haven't added a conditional yet that redirects the user once they're logged in.&lt;/p&gt;

&lt;p&gt;Let's go back to our &lt;code&gt;&amp;lt;Login /&amp;gt;&lt;/code&gt; component and add that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./components/Login.js

import React from 'react'
import { useContext } from 'react'
import { UserContext } from '../context/user'
import { useNavigate } from "react-router-dom";

function Login() {
    const { user, setUser } = useContext(UserContext);
    const navigate = useNavigate();

    if(user) {
        navigate('/')
    };

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h1&amp;gt;Login&amp;lt;/h1&amp;gt;
            &amp;lt;button onClick={() =&amp;gt; setUser(true)}&amp;gt;Login&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};

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

&lt;/div&gt;



&lt;p&gt;We'll add &lt;code&gt;useNavigate&lt;/code&gt; to redirect the user if the &lt;code&gt;user&lt;/code&gt; token is a truthy value. &lt;/p&gt;

&lt;p&gt;Save the changes and now try to login; it should be redirecting you now to &lt;code&gt;/&lt;/code&gt; after you log in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Redirecting the User After Logging In
&lt;/h2&gt;

&lt;p&gt;What if now the user wants the ability to refresh or go directly to a page, login, then keep their place? Normally it would just redirect them to &lt;code&gt;/&lt;/code&gt; because of our conditional in &lt;code&gt;&amp;lt;Login /&amp;gt;&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;We can fix that by adding a conditional that uses the &lt;code&gt;useLocation&lt;/code&gt; state that we saved in &lt;code&gt;&amp;lt;AuthLayout /&amp;gt;&lt;/code&gt;! Remember when console logging &lt;code&gt;location&lt;/code&gt; it was saving your browser history to the &lt;code&gt;location&lt;/code&gt; state.&lt;/p&gt;

&lt;p&gt;Update your &lt;code&gt;&amp;lt;Login /&amp;gt;&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./components/Login.js 

import React, { useEffect } from 'react'
import { useContext } from 'react'
import { UserContext } from '../context/user'
import { useLocation, useNavigate } from "react-router-dom";

function Login() {
    const { user, setUser } = useContext(UserContext);
    const location = useLocation();
    const navigate = useNavigate();

    if (user &amp;amp;&amp;amp; location.state?.from) {
        return navigate(location.state.from)
    };

    return (
        &amp;lt;div&amp;gt;
            &amp;lt;h1&amp;gt;Login&amp;lt;/h1&amp;gt;
            &amp;lt;button onClick={() =&amp;gt; setUser(true)}&amp;gt;Login&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
    )
}

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

&lt;/div&gt;



&lt;p&gt;We added a different conditional that checks if &lt;code&gt;user&lt;/code&gt; token is true AND &lt;code&gt;location&lt;/code&gt; has an available state that we can use to redirect with &lt;code&gt;navigate&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;To test this, let's update our &lt;code&gt;&amp;lt;Homepage /&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;Admin /&amp;gt;&lt;/code&gt; components to include logout buttons. We'll also update &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; to pass in the &lt;code&gt;setUser&lt;/code&gt; prop but you could also use context instead if you'd like.&lt;br&gt;
&lt;/p&gt;

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

import React, { useContext } from "react";
import { UserContext } from "./context/user";
import Admin from "./components/Admin";
import Homepage from "./components/Homepage";
import Login from "./components/Login";
import AuthLayout from "./auth/auth";
import { Routes, Route } from "react-router-dom";

function App() {
  const { user, setUser } = useContext(UserContext);

return (
&amp;lt;div className="App"&amp;gt;
 &amp;lt;Routes&amp;gt;
  &amp;lt;Route element={&amp;lt;AuthLayout authenticated={user} /&amp;gt;}&amp;gt;
    &amp;lt;Route path='/' element={&amp;lt;Homepage {setUser}=setUser /&amp;gt;} /&amp;gt;
    &amp;lt;Route path='/admin' element={&amp;lt;Admin {setUser}=setUser  /&amp;gt;} /&amp;gt;
  &amp;lt;/Route&amp;gt;
  &amp;lt;Route path="login" element={&amp;lt;Login /&amp;gt;} /&amp;gt;
 &amp;lt;/Routes&amp;gt;
&amp;lt;/div&amp;gt;
  );
}

export default App;

./components/Homepage.js

import React from 'react'
import { Link } from 'react-router-dom'

function Homepage({ setUser }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Homepage&amp;lt;/h1&amp;gt;
      &amp;lt;Link to="/admin" replace&amp;gt;&amp;lt;button&amp;gt;Admin Page&amp;lt;/button&amp;gt;&amp;lt;/Link&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setUser(false)}&amp;gt;Logout&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default Homepage

./components/Admin.js

import React from 'react'
import { Link } from 'react-router-dom'

function Admin({ setUser }) {
    return (
      &amp;lt;div&amp;gt;
         &amp;lt;h1&amp;gt;Admin&amp;lt;/h1&amp;gt;
         &amp;lt;Link to="/" replace&amp;gt;&amp;lt;button&amp;gt;Back to Home&amp;lt;/button&amp;gt;&amp;lt;/Link&amp;gt;
         &amp;lt;button onClick={() =&amp;gt; setUser(false)}&amp;gt;Logout&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    )
}

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

&lt;/div&gt;



&lt;p&gt;Save the changes or spin up the instance again and go ahead and login. &lt;/p&gt;

&lt;p&gt;After logging in, navigate to &lt;code&gt;/admin&lt;/code&gt; using the buttons then logout. Once you're logged out, when you log in again you should notice that you've been returned to the &lt;code&gt;/admin&lt;/code&gt; page instead of &lt;code&gt;/&lt;/code&gt;! &lt;/p&gt;

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

&lt;p&gt;React Router v6 is a very powerful tool that can be used for authentication and conditional redirects after logging in. This will make your app robust and more user friendly.&lt;/p&gt;

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

&lt;p&gt;Please let me know in the comments if I've made any errors or if you have any questions! Still new to ReactJS and React Router v6 but I hope this was useful!&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://reactrouter.com/en/main"&gt;React Router v6 Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@dennisivy/creating-protected-routes-with-react-router-v6-2c4bbaf7bc1c"&gt;Creating Protected Routes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=2lJuOh4YlGM"&gt;Redirect After Login with React Router v6 (video)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactrouter</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Using Ruby on Rails and ActiveModel::Serializer (AMS) to Control Your Data (Review)</title>
      <dc:creator>ericksong91</dc:creator>
      <pubDate>Thu, 25 May 2023 23:33:46 +0000</pubDate>
      <link>https://dev.to/ericksong91/using-ruby-on-rails-and-activemodelserializer-ams-to-control-your-data-review-3kpb</link>
      <guid>https://dev.to/ericksong91/using-ruby-on-rails-and-activemodelserializer-ams-to-control-your-data-review-3kpb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hi y'all,&lt;/p&gt;

&lt;p&gt;This is a quick review on how to utilize the Serializer gem for Ruby on Rails. &lt;code&gt;ActiveModel::Serializer&lt;/code&gt; or AMS, is a great way to control how much information an API sends as well as a way to include nested data from associations.&lt;/p&gt;

&lt;p&gt;There are many instances where your backend will store extraneous data that isn't needed for the frontend or data that should not be shown. For example, for a table of User data, you would not want to display password hashes. Or if you have a relational database about Books with many Reviews, you would not want to include all the Reviews with every Books fetch request until you explicitly needed it. &lt;/p&gt;

&lt;p&gt;This tutorial will assume you already know the basics of using Rails models and migrations along with making routes and using controllers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Our Relational Database
&lt;/h2&gt;

&lt;p&gt;Before we begin, lets come up with a simple relational table with a many-to-many relationship:&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%2Fm5eevnwrksv7qlmdjytx.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%2Fm5eevnwrksv7qlmdjytx.png" alt="Museums, Users (Artists) and Paintings"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Museums have many Users (Artists) through Paintings&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Users (Artists) have many Museums through Paintings&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The table shows a many-to-many relationship between &lt;code&gt;Museums&lt;/code&gt; and &lt;code&gt;Users&lt;/code&gt; (Artists), joined by &lt;code&gt;Paintings&lt;/code&gt;. The arrows in the table indicate the foreign keys associated with each table in &lt;code&gt;Paintings&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now lets make our models and migrations:&lt;/p&gt;

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

# models/museums.rb
class Museum &amp;lt; ApplicationRecord
    has_many :paintings
    has_many :users, -&amp;gt; { distinct }, through: :paintings
end

# models/paintings.rb
class Painting &amp;lt; ApplicationRecord
    belongs_to :user
    belongs_to :museum
end

# models/users.rb
class User &amp;lt; ApplicationRecord
    has_many :paintings, dependent: :destroy
    has_many :museums, -&amp;gt; { distinct }, through: :paintings
end


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

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;*Note: -&amp;gt; { distinct } will make sure there are no duplicate data when the &lt;code&gt;User&lt;/code&gt; or &lt;code&gt;Museum&lt;/code&gt; data is retrieved.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The schema after migration should look something like this:&lt;/p&gt;

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

# db/schema.rb
  create_table "museums", force: :cascade do |t|
    t.string "name"
    t.string "location"
    t.string "bio"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "paintings", force: :cascade do |t|
    t.string "name"
    t.string "bio"
    t.string "img_url"
    t.integer "year"
    t.integer "user_id"
    t.integer "museum_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "username"
    t.string "password_digest"
    t.string "bio"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end



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

&lt;/div&gt;

&lt;p&gt;In your &lt;code&gt;seeds.rb&lt;/code&gt; file, make some generic seed data. &lt;/p&gt;

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

# db/seeds.rb
# Example Seed Data:

user = User.create!(username: "John", password:"asdf", 
       password_confirmation: "asdf", bio: "Test")

musuem = Museum.create!(name: "Museum of Cool Things", location: 
         "Boston", bio: "Cool Test Museum")

painting = Painting.create!(name: "Mona Lisa", bio: "very famous", 
           img_url: "url of image", year: 1999,
           user_id: 1, museum_id: 1


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

&lt;/div&gt;

&lt;p&gt;Now in our Config folder, lets make a simple Index route just for &lt;code&gt;Users&lt;/code&gt; in &lt;code&gt;routes.rb&lt;/code&gt;. &lt;/p&gt;

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

# config/routes.rb
Rails.application.routes.draw do
  resources :users, only: [:index]
end


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

&lt;/div&gt;

&lt;p&gt;Then in our &lt;code&gt;users_controller.rb&lt;/code&gt;, lets make a simple function that shows all Users. &lt;/p&gt;

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

# controllers/users_controller.rb
class UsersController &amp;lt; ApplicationController
    def index
        user = User.all
        render json: users
    end
end


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

&lt;/div&gt;

&lt;p&gt;Now boot up your server and go to &lt;code&gt;/users&lt;/code&gt; to see what kind of data you're getting back: &lt;/p&gt;

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

[{
"id":1,
"username":"John",
"password_digest":"$2a$12$GXCFijd75p4VXj3OazNpFu52.nKbd0ETBbZUutVZAQqlyGCVphPGW",
"bio":"Test.",
"created_at":"2023-05-14T01:47:42.292Z",
"updated_at":"2023-05-14T01:47:42.292Z"
},


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

&lt;/div&gt;

&lt;p&gt;Yikes! You definitely don't want to have all this information, especially not the password hash. Lets get into our serializers and fix that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up and Installing AMS
&lt;/h2&gt;

&lt;p&gt;First, we want to install the gem:&lt;/p&gt;

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

gem "active_model_serializers"


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

&lt;/div&gt;

&lt;p&gt;Once the gem has been installed, you can start to generate your serializer files using &lt;code&gt;rails g serializer name_of_serializer&lt;/code&gt; in your console. &lt;/p&gt;

&lt;p&gt;Lets add one for each of our models:&lt;/p&gt;

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

rails g serializer museum
rails g serializer user
rails g serializer painting


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

&lt;/div&gt;

&lt;p&gt;This should make a Serializer folder in your project directory with the files &lt;code&gt;museum_serializer.rb&lt;/code&gt;, &lt;code&gt;user_serializer.rb&lt;/code&gt; and &lt;code&gt;painting_serializer.rb&lt;/code&gt;. Once we have these files, we can now control what kind of information we're getting. &lt;/p&gt;

&lt;p&gt;It is important to note that as long as you're following naming conventions, Rails will implicitly look for the serializer that matches the model class name.&lt;/p&gt;

&lt;p&gt;For example, for Users: &lt;/p&gt;

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

# models/user.rb
class User &amp;lt; ApplicationRecord
# code
end

# serializers/user_serializer.rb
class UserSerializer &amp;lt; ActiveModel::Serializer
end


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

&lt;/div&gt;

&lt;p&gt;Rails will look for the serializer that has the class name of &lt;code&gt;User&lt;/code&gt; then the word 'Serializer' (&lt;code&gt;UserSerializer&lt;/code&gt;). It will look for this naming convention for the default serializer.&lt;/p&gt;

&lt;p&gt;Now lets try modifying some of the information we get back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Data from Fetch Requests
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Excluding Information
&lt;/h3&gt;

&lt;p&gt;Lets reload our &lt;code&gt;/users&lt;/code&gt; &lt;code&gt;GET&lt;/code&gt; request and see what happens now. &lt;/p&gt;

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

[{}]


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

&lt;/div&gt;

&lt;p&gt;Looks like we're getting no information now but don't fear; we just need to tell the serializer what data we want. Lets start with just grabbing &lt;code&gt;:id&lt;/code&gt;, &lt;code&gt;:username&lt;/code&gt; and their &lt;code&gt;:bio&lt;/code&gt; by adding some &lt;code&gt;attributes&lt;/code&gt;.&lt;/p&gt;

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

# serializers/user_serializer.rb
class UserSerializer &amp;lt; ActiveModel::Serializer
  attributes :id, :username, :bio
end



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

&lt;/div&gt;

&lt;p&gt;Reloading our &lt;code&gt;GET&lt;/code&gt; request, we now have:&lt;/p&gt;

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

[{
"id":1,
"username":"John",
"bio":"Test"
}


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

&lt;/div&gt;

&lt;p&gt;Perfect! Now we can control what information we want to get from our &lt;code&gt;GET&lt;/code&gt; request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Nested Data
&lt;/h3&gt;

&lt;p&gt;Now lets say we want to include the paintings that belong to a user. We already have our relationships mapped out in our model files but we also need to add these macros to our serializers.&lt;/p&gt;

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

# serializers/painting_serializer.rb
class PaintingSerializer &amp;lt; ActiveModel::Serializer
    attributes :id, :name, :bio, :img_url, :user_id, :museum_id, 
    :year

    belongs_to :user
    belongs_to :museum
end

# serializers/user_serializer.rb
class UserSerializer &amp;lt; ActiveModel::Serializer
  attributes :id, :username

  has_many :paintings
end


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

&lt;/div&gt;

&lt;p&gt;Refreshing &lt;code&gt;/users&lt;/code&gt; again will display:&lt;/p&gt;

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

[{
"id":2,
"username":"John",
"bio":"Test",
"paintings":[
        {
          "id":1,
          "name":"Mona Lisa",
          "bio":"very famous",
          "img_url":"url of image",
          "user_id":1,
          "museum_id":1,
          "year":1999
}]}


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

&lt;/div&gt;

&lt;p&gt;Throwing this relationship into the &lt;code&gt;UserSerializer&lt;/code&gt; and &lt;code&gt;PaintingSerializer&lt;/code&gt; will allow you receive nested data of Paintings belonging to a User. The information nested in the User data will reflect what is in the &lt;code&gt;PaintingSerializer&lt;/code&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a Different Serializer for the Same Model
&lt;/h3&gt;

&lt;p&gt;You can also add a new serializer that includes different information from the default serializer. Lets say for a single &lt;code&gt;User&lt;/code&gt;, we want them to have a list of &lt;code&gt;Museums&lt;/code&gt; and &lt;code&gt;Paintings&lt;/code&gt; on their profile page.&lt;/p&gt;

&lt;p&gt;Make a new serializer called &lt;code&gt;user_profile_serializer.rb&lt;/code&gt;. We'll use this serializer to also include the museum data for a user.&lt;/p&gt;

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

# serializers/museum_serializer.rb
class MuseumSerializer &amp;lt; ActiveModel::Serializer
    attributes :id, :name, :bio, :location
end

# serializers/painting_serializer.rb
class PaintingSerializer &amp;lt; ActiveModel::Serializer
    attributes :id, :name, :bio, :img_url, :user_id, :museum_id, 
    :year

    belongs_to :user
    belongs_to :museum
end

# serializers/user_profile_serializer.rb
class UserProfileSerializer &amp;lt; ActiveModel::Serializer
  attributes :id, :username, :bio

  has_many :paintings
  has_many :museums, through: :paintings
end


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

&lt;/div&gt;

&lt;p&gt;Rails will not use this serializer file by default but you can call for it when rendering your JSON. In your &lt;code&gt;users_controller.rb&lt;/code&gt; file, you can change what serializer you use for a specific request. Make the appropriate changes in &lt;code&gt;routes.rb&lt;/code&gt; by including &lt;code&gt;:show&lt;/code&gt; and adding it to the controller.&lt;/p&gt;

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

# config/routes.rb
Rails.application.routes.draw do
  resources :users, only: [:index, :show]
end

# controllers/users_controller.rb
# For this example, we'll just assume we're looking for the User of ID 1

class UsersController &amp;lt; ApplicationController
    def index
        users = User.all
        render json: users
    end

    def show
        user = User.find_by(id: 1)
        render json: user, status: :created, 
                     serializer: UserProfileSerializer
    end
end


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

&lt;/div&gt;

&lt;p&gt;Loading up &lt;code&gt;/users/1&lt;/code&gt; gives us:&lt;/p&gt;

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

[{
"id":2,
"username":"John",
"bio":"Test",
"paintings":[
        {
          "id":1,
          "name":"Mona Lisa",
          "bio":"very famous",
          "img_url":"url of image",
          "user_id":1,
          "museum_id":1,
          "year":1999
}],
"museums": [
        {
          "id": 1,
          "name": "Museum of Cool Things",
          "bio": "Cool Test Museum",
          "location": "Boston",
}]}


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

&lt;/div&gt;

&lt;p&gt;We look for the specific User, and if that User is found, we render their information and include the museums nested data as well.&lt;/p&gt;

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

&lt;p&gt;Serializers are very powerful as they let you control the data your API is sending. &lt;/p&gt;

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

&lt;p&gt;Please let me know in the comments if I've made any errors or if you have any questions. Still new to Ruby on Rails and AMS but would like to know your thoughts :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra Reading, Credits and Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/rails-api/active_model_serializers/tree/v0.10.6" rel="noopener noreferrer"&gt;ActiveModel::Serializer Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@maxfpowell/a-quick-intro-to-rails-serializers-b390ced1fce7" rel="noopener noreferrer"&gt;A Quick Intro to Rails Serializers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://itnext.io/a-quickstart-guide-to-using-serializer-with-your-ruby-on-rails-api-d5052dea52c5" rel="noopener noreferrer"&gt;Quickstart Guide to Using Serializer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dbdiagram.io/home" rel="noopener noreferrer"&gt;DB Diagram&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Object Inheritance Basics Review (Ruby)</title>
      <dc:creator>ericksong91</dc:creator>
      <pubDate>Mon, 06 Feb 2023 21:11:27 +0000</pubDate>
      <link>https://dev.to/ericksong91/object-inheritance-basics-review-ruby-2n4k</link>
      <guid>https://dev.to/ericksong91/object-inheritance-basics-review-ruby-2n4k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Object inheritance means that a child (or sub) class will inherit all the methods and attributes of a parent (or super) class. This allows the user to have some reusability of code and reduces redundancy.&lt;/p&gt;

&lt;p&gt;For example, if we have a &lt;code&gt;Car&lt;/code&gt;, &lt;code&gt;Airplane&lt;/code&gt; and &lt;code&gt;Boat&lt;/code&gt; class, they would share a lot of common attributes such as &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;manufacturer&lt;/code&gt;, &lt;code&gt;fuel type&lt;/code&gt; etc. If we suddenly had to change one of these attributes, we would have to change it for all three classes!&lt;/p&gt;

&lt;p&gt;We can circumvent this problem by make a fourth class, &lt;code&gt;Vehicle&lt;/code&gt;, that could encompass a lot of the common attributes and methods for each vehicle type. This would reduce the amount of code and changes would be a lot less time consuming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding Example: &lt;code&gt;Book&lt;/code&gt; and &lt;code&gt;Textbook&lt;/code&gt; Class
&lt;/h2&gt;

&lt;p&gt;Lets say we have a &lt;code&gt;Book&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

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

 attr_accessor :title, :author, :pages

 def initialize(title, author, pages)
  @title = title
  @author = author
  @pages = pages
 end

 def flip
  "Flipping through the pages!"
 end

 def cost
   "I got this cool book for free!"
 end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets also include a &lt;code&gt;Textbook&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Textbook
 attr_accessor :title, :author, :pages

 def initialize(title, author, pages)
  @title = title
  @author = author
  @pages = pages
 end

 def subject
   "Subject: Math"
 end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can already see that &lt;code&gt;Book&lt;/code&gt; and &lt;code&gt;Textbook&lt;/code&gt; share the &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;author&lt;/code&gt; and &lt;code&gt;pages&lt;/code&gt; attribute. You also want to be able to &lt;code&gt;flip&lt;/code&gt; through both books. The only difference is that the &lt;code&gt;Textbook&lt;/code&gt; class teaches a subject, Math.&lt;/p&gt;

&lt;p&gt;If we instead change the &lt;code&gt;Textbook&lt;/code&gt; class into a subclass or child class of &lt;code&gt;Book&lt;/code&gt;, we can save ourselves some code. We use the &lt;code&gt;&amp;lt;&lt;/code&gt; symbol to inherit the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Textbook &amp;lt; Book
 def subject
   "Subject: Math"
 end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets initialize a new instance with both classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new_book = Book.new("Hello!", "John Smith", 60)
new_textbook = Textbook.new("Calculus", "Mister Math", 450)

puts new_book.title
 =&amp;gt; Hello!

puts new_book.author
 =&amp;gt; John Smith

puts new_book.pages
 =&amp;gt; 60

puts new_book.flip
 =&amp;gt; Flipping through the pages!

puts new_book.cost
 =&amp;gt; I got this cool book for free!

puts new_textbook.title
 =&amp;gt; Calculus

puts new_textbook.author
 =&amp;gt; Mister Math

puts new_textbook.pages
 =&amp;gt; 450

puts new_textbook.flip
 =&amp;gt; Flipping through the pages!

puts new_textbook.subject
 =&amp;gt; I got this cool book for free!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the issue we're running into is that textbooks usually don't cost nothing! Fortunately, we can supersede the method &lt;code&gt;cost&lt;/code&gt; from &lt;code&gt;Book&lt;/code&gt; with our own &lt;code&gt;cost&lt;/code&gt; in &lt;code&gt;Textbook&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Textbook &amp;lt; Book
 def subject
   "Subject: Math"
 end

 def cost
   "I got this used for $300!"
 end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now calling the method &lt;code&gt;cost&lt;/code&gt; on &lt;code&gt;Textbook&lt;/code&gt; will result in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;puts new_textbook.cost
 =&amp;gt; I got this used for $300!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When Ruby executes the code, it first looks at the class of the instance and looks for the method. If it cannot find the method, it will go up to the parent class and look for that method there. &lt;/p&gt;

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

&lt;p&gt;Object inheritance is a useful and key component to how classes work in Ruby. It helps improve reusability of code and allows for modular design which improves flexibility and saves time.&lt;/p&gt;

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

&lt;p&gt;Please let me know in the comments if I've made any errors. Still new to Ruby but would like to know your thoughts :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits and Additional Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.ruby-lang.org/en/documentation/faq/8/"&gt;Ruby Class&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.tutorialspoint.com/how-does-inheritance-work-in-ruby"&gt;How Does Inheritance work in Ruby? - Tutorials Point&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.geeksforgeeks.org/ruby-inheritance/"&gt;Object Inheritance - Geeks for Geeks&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using Controlled and Uncontrolled Components in React, Quick Review</title>
      <dc:creator>ericksong91</dc:creator>
      <pubDate>Mon, 21 Nov 2022 01:34:15 +0000</pubDate>
      <link>https://dev.to/ericksong91/using-controlled-and-uncontrolled-components-in-react-quick-review-1llp</link>
      <guid>https://dev.to/ericksong91/using-controlled-and-uncontrolled-components-in-react-quick-review-1llp</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Today I will be talking about uncontrolled vs controlled components in React from the perspective of a student.&lt;/p&gt;

&lt;p&gt;React is a Javascript library that allows web developers to modularize their web applications into separate and reusable components. This also comes with very convenient features that allow you to control how data is handled in forms.&lt;/p&gt;

&lt;p&gt;One of these features is Controlled Components.&lt;/p&gt;

&lt;h2&gt;
  
  
  Controlled Components
&lt;/h2&gt;

&lt;p&gt;Controlled components are forms that are handled entirely by a React component and a hook called &lt;code&gt;useState&lt;/code&gt;. &lt;code&gt;useState&lt;/code&gt; is a hook that automatically refreshes the application whenever a change is made to its state variable (prop). Form elements become controlled elements once the value is set to a prop.&lt;/p&gt;

&lt;p&gt;In the case of controlled forms, it will track every change done to the form (every input down to the letter).&lt;/p&gt;

&lt;p&gt;This is useful because the application can keep track of what the user is inputting before they hit submit. &lt;/p&gt;

&lt;p&gt;A simple way to set this up would be to have a basic form like so:&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 Form() {
    const [name, setName] = useState("");

    console.log(name);

    return (
        &amp;lt;form&amp;gt;
            &amp;lt;input type="text" value={name} onChange=
                {(e) =&amp;gt; setName(e.target.value)} /&amp;gt;
            &amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
    );
}

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

&lt;/div&gt;



&lt;p&gt;When typing into the field, you'll see that the state variable &lt;code&gt;name&lt;/code&gt; is updating in real time with its current value. The &lt;code&gt;onChange&lt;/code&gt; event uses the &lt;code&gt;setName&lt;/code&gt; function to change the value of &lt;code&gt;name&lt;/code&gt; to the current target value using &lt;code&gt;e.target.value&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is useful in cases where you need features such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Immediate feedback to input validation &lt;/li&gt;
&lt;li&gt;Disabling a submission before the field has valid input&lt;/li&gt;
&lt;li&gt;Forcing specific characters (numbers only, no special characters, etc)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Uncontrolled Components
&lt;/h2&gt;

&lt;p&gt;Uncontrolled components are more traditional forms that are controlled by the DOM instead of an individual component. Uncontrolled components use the &lt;code&gt;useRef&lt;/code&gt; attribute. You can use &lt;code&gt;useRef&lt;/code&gt; as a way to access values from the DOM.&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, { useRef } from "react";

function Form() {

    const ref = useRef();

    const handleSubmit = (e) =&amp;gt; {
        e.preventDefault();
        console.log(ref.current.value)
    };

    return (
        &amp;lt;form&amp;gt;
            &amp;lt;input type="text" ref={ref} /&amp;gt;
            &amp;lt;button type="submit" onClick= 
               {handleSubmit}&amp;gt;Submit&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
    );
}

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

&lt;/div&gt;



&lt;p&gt;We first bring in the &lt;code&gt;useRef&lt;/code&gt; hook then we use a &lt;code&gt;ref&lt;/code&gt; attribute in our JSX to give the current value to our ref variable. This gives us access to the submitted form information.&lt;/p&gt;

&lt;p&gt;Although &lt;code&gt;useRef&lt;/code&gt; is used here as a way to get information directly from the DOM, it has more uses such as holding data that will persist through application re-renders. You can check out &lt;a href="https://reactjs.org/docs/hooks-reference.html#useref"&gt;React JS useRef Hook&lt;/a&gt; to see more details about the &lt;code&gt;useRef&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;You won't use uncontrollable forms very often but here are a few examples of when you may want to use it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Media playback&lt;/li&gt;
&lt;li&gt;Maintaining focus &lt;/li&gt;
&lt;li&gt;Selecting text&lt;/li&gt;
&lt;li&gt;Integrating 3rd party DOM libraries&lt;/li&gt;
&lt;li&gt;Imperative animations&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Both types of forms have their merit but for most intents and purposes, controlled components are preferred.&lt;/p&gt;

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

&lt;p&gt;Please let me know in the comments if I've made any errors. Still new to JS and React but would like to know your thoughts :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits and Additional Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/docs/forms.html"&gt;React JS Forms&lt;/a&gt;&lt;br&gt;
&lt;a href="https://reactjs.org/docs/hooks-state.html"&gt;React JS State&lt;/a&gt;&lt;br&gt;
&lt;a href="https://reactjs.org/docs/refs-and-the-dom.html"&gt;React JS Refs and the DOM&lt;/a&gt;&lt;br&gt;
&lt;a href="https://reactjs.org/docs/hooks-reference.html#useref"&gt;React JS useRef Hook&lt;/a&gt;&lt;br&gt;
&lt;a href="https://goshacmd.com/controlled-vs-uncontrolled-inputs-react/"&gt;Controlled vs Uncontrolled Forms in React&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=ecY3QSxZZYY"&gt;Rethinking UI (video)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>beginners</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Logical Operators Review</title>
      <dc:creator>ericksong91</dc:creator>
      <pubDate>Tue, 20 Sep 2022 19:16:14 +0000</pubDate>
      <link>https://dev.to/ericksong91/logical-operators-review-2a9n</link>
      <guid>https://dev.to/ericksong91/logical-operators-review-2a9n</guid>
      <description>&lt;h1&gt;
  
  
  Logical Operators Review
&lt;/h1&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hello! Today I'd like to review some logical operators to prepare for my exams tomorrow. This post will just be class notes for me and anyone else to use as a quick review on Logical Operators.&lt;/p&gt;




&lt;h2&gt;
  
  
  Overview: NOT(!), AND(&amp;amp;&amp;amp;), OR(||)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NOT(!):

Operates on an expression, returns the opposite of its truthiness.

AND(&amp;amp;&amp;amp;):

Takes two expressions, returns the first expression that returns false.

OR(||):

Takes two expressions, returns the first expression that returns true.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Anything with a value in it is inherently true. Anything without a value is false. Quick examples below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"string"
1
3.14
-123123
"false"

Are all considered true, because they have a value.

0
""
undefined
null

Are all considered false, because they contain no values.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. The Bang Operator, NOT (!)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NOT(!):

Operates on an expression, returns the opposite of its truthiness.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As stated above, when adding the Bang operator to an expression, you will output the opposite of its current Boolean state. Truthy values become false and falsey values become true. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; There is no limit to the amount of ! you can add to an expression. It will just keep flipping between the two Boolean states with every !. &lt;/p&gt;

&lt;p&gt;Lets look at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const truthy = true
const falsey = false

!truthy
=&amp;gt; Expected output: false

!falsey
=&amp;gt; Expected output: true

!!truthy
=&amp;gt; Expected output: true

!!falsey
=&amp;gt; Expected output: false

!!!!!!!!!!!!!!truthy
=&amp;gt; Expected output: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can add as many Bang operators as you want and it will just keep switching Boolean states as there are operators. &lt;/p&gt;

&lt;p&gt;Now lets look at some additional examples where the values aren't just true or false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const truthy = "String"
const falsey = 0

Boolean(truthy)
=&amp;gt; Expected output: true

Boolean(falsey)
=&amp;gt; Expected output: false

!truthy
=&amp;gt; Expected output: false

!falsey
=&amp;gt; Expected output: true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The truthiness of a value isn't limited to just true or false. As noted earlier, expressions with a value are considered true while expressions without any value are considered false.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; You can use the built in JS object wrapper, Boolean(), to determine if a value is true or false AND to also convert the value into a boolean. You can also use the Bang operator to convert the value into a boolean as well (simply by using !!).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The AND Operator (&amp;amp;&amp;amp;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AND(&amp;amp;&amp;amp;):

Takes two expressions, returns the first expression that returns false.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets look at a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const expression1 = 'truthy'
const expression2 = 0

expression1 &amp;amp;&amp;amp; expression2
=&amp;gt; Expected output: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The returned expression is the value of expression2. Since expression 2 is the first false statement being compared, it will return that value.&lt;/p&gt;

&lt;p&gt;Lets look at another example, this time using mathematical expressions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4 * 3 &amp;amp;&amp;amp; 11 * 0
=&amp;gt; Expected output: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that it will give us the resultant value of the right hand expression since that is the expression with the false value.&lt;/p&gt;

&lt;p&gt;Now what happens when both sides are true?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4 * 3 &amp;amp;&amp;amp; 11 + 12
=&amp;gt; Expected output: 23
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returns the 2nd expression's value, despite it being true. This is because &amp;amp;&amp;amp; is required to return a value and if both sides are true, it will return the last expression it evaluated (which in this case is the right hand expression).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The OR Operator (||)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OR(||):

Takes two expressions, returns the first expression that returns true.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works much like the AND (&amp;amp;&amp;amp;) operator except it returns the first expression it finds that is true. &lt;/p&gt;

&lt;p&gt;Lets look at some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const truthy = "I am Truth"
const falsey = null

falsey || truthy
=&amp;gt; Expected output: "I am Truth"

1 * 33 || 42 * 10
=&amp;gt; Expected output: 33

42 * 10 || 1 * 33
=&amp;gt; Expected output: 420

const zero = 0 || "0"

console.log(zero)
=&amp;gt; Expected output: "0"

console.log(typeof(zero))
=&amp;gt; Expected output: String
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how in the last example, the value of a string that contains "0" is considered a value and therefore true. &lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;Hope this wasn't too confusing and gave a quick review of logical operators. &lt;/p&gt;

&lt;h3&gt;
  
  
  Credits
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.w3schools.com/js/js_booleans.asp"&gt;W3 School Boolean&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean"&gt;MDN Boolean&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Quick Review (of some) JS Iterator Methods</title>
      <dc:creator>ericksong91</dc:creator>
      <pubDate>Thu, 15 Sep 2022 19:45:18 +0000</pubDate>
      <link>https://dev.to/ericksong91/reviewing-some-js-iterator-methods-518l</link>
      <guid>https://dev.to/ericksong91/reviewing-some-js-iterator-methods-518l</guid>
      <description>&lt;h1&gt;
  
  
  Reviewing .map(), .find(), .filter(), .reduce() and .forEach()
&lt;/h1&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Today I'll be reviewing some JS iterator methods in an attempt to have a better grasp on the concepts. I'll be going over .map(), .filter(), .find(), .reduce() and forEach(). &lt;/p&gt;

&lt;p&gt;Below is a quick summary table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;array.map(callbackFunction)&lt;/td&gt;
&lt;td&gt;Creates a new array made with elements that have been mutated by a function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;array.find(callbackFunction)&lt;/td&gt;
&lt;td&gt;Returns the &lt;strong&gt;&lt;em&gt;first&lt;/em&gt;&lt;/strong&gt; element in the array that satisfies the provided test function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;array.filter(callbackFunction)&lt;/td&gt;
&lt;td&gt;Returns &lt;strong&gt;&lt;em&gt;all&lt;/em&gt;&lt;/strong&gt; of the elements in an array that satisfies the provided test function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;array.reduce(callbackFunction, initialValue)&lt;/td&gt;
&lt;td&gt;Walks through every element in an array, passing it to a function, then adds that result to the previous result. Initial value optional.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;array.forEach(callbackFunction)&lt;/td&gt;
&lt;td&gt;Changes original array made with elements that have been mutated by a function&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  .map() Method
&lt;/h2&gt;

&lt;p&gt;.map() executes a function over each element in an array, then returns us a new array.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Lets say we have an array with a set of 4 numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array1 = [1, 3, 5, 7]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a function that takes a number and multiplies it by 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function multiplier(e){
   return e * 2
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we invoke the .map() method on the array using the &lt;em&gt;multiplier&lt;/em&gt; function, then each element in the array will be passed into that function. Essentially, every element will be multiplied by 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array1 = [1, 3, 5, 7]

function multiplier(e){
   return e * 2
}

const newArray = array1.map(multiplier)

console.log(array1)
console.log(newArray)
==&amp;gt; Expected output: [1, 3, 5, 7]
==&amp;gt; Expected output: [2, 6, 10, 14]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take note that the original array was &lt;strong&gt;not&lt;/strong&gt; changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  .find() Method
&lt;/h2&gt;

&lt;p&gt;.find() returns the &lt;em&gt;first&lt;/em&gt; element in an array that satisfies the test function's conditions, read from left to right. &lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Lets say we have an array of words, with varying word lengths.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array1 = ["blast", "past", "ghast", "last", "mast", "make"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then lets have a test callback function that returns a word that is greater than 4 letters long.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function findArr(e){
  return 4 &amp;lt; e.length ;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the .find() method, we can find all words in the array that have a word length greater than 4. In this case, it should be either &lt;em&gt;blast&lt;/em&gt; or &lt;em&gt;ghast&lt;/em&gt;. However, since .find() only looks for the very first element that satisfies the condition, it should only return &lt;em&gt;blast&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array1 = ["blast", "past", "ghast", "last", "mast", "make"]

function findArr(e){
  return 4 &amp;lt; e.length ;
}

const find = array1.find(findArr)

console.log(find)
==&amp;gt; Expected output: "blast"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As expected, since only &lt;em&gt;blast&lt;/em&gt; and &lt;em&gt;ghast&lt;/em&gt; have greater than 4 letter lengths and &lt;em&gt;blast&lt;/em&gt; is the very first word in the array that satisfies this condition, it returns &lt;em&gt;blast&lt;/em&gt; only. &lt;/p&gt;

&lt;h2&gt;
  
  
  .filter() Method
&lt;/h2&gt;

&lt;p&gt;.filter() returns all the elements in an array that satisfies the test function. Unlike .find(), it finds all elements in the array that satisfy this condition and returns a new array. &lt;/p&gt;

&lt;p&gt;Lets take our last example from .find() and use .filter() instead.&lt;/p&gt;

&lt;p&gt;Using the .filter() method, we can find all words in the array that have a word length greater than 4. In this case, it should be &lt;em&gt;blast&lt;/em&gt; and &lt;em&gt;ghast&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array1 = ["blast", "past", "ghast", "last", "mast", "make"]

function filterArr(e){
  return 4 &amp;lt; e.length ;
}

const filter = array1.filter(filterArr)

console.log(filter)
==&amp;gt; Expected output: ["blast", "ghast"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since only &lt;em&gt;blast&lt;/em&gt; and &lt;em&gt;ghast&lt;/em&gt; have greater than 4 letter lengths, they were both returned in a new array with just those two words.&lt;/p&gt;

&lt;h2&gt;
  
  
  .reduce() Method
&lt;/h2&gt;

&lt;p&gt;.reduce() is a iterator method used to summarize an array into a single value. You pass a callback function into .reduce() and you have the additional option of passing in an initial value. &lt;/p&gt;

&lt;p&gt;The callback function is passed two arguments: the previous value returned from the loop and the next value in the array. If there was an initial value given, it will use that as its first "previous value" in the calculation.&lt;/p&gt;

&lt;p&gt;If there is no initial value, it takes index #0 of the array as the initial value instead. See below for clarification.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Lets take our array from our .map() example as well as an initial value of 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array1 = [1, 3, 5, 7]

const initialValue = 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now lets make our reducer function multiply the previous value, with the current element in the array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function reducer(previousValue, currentElement){
   return previousValue * currentElement
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the .reduce() method, we're going to see it calculate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Previous Value * Current Element
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Through every element in the array, starting with the initial value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array1 = [1, 3, 5, 7];

const initialValue = 2;

const finalValue = array1.reduce(reducer, initialValue);

function reducer(previousValue, currentElement){
  return previousValue * currentElement
}

console.log(finalValue)
=&amp;gt; Expected output: 210
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The calculation written out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 (initial value) * 1 (array1[0]) = 2

2 (previous value) * 3 (array1[1]) = 6

6 (previous value) * 5 (array1[2]) = 30

30 (previous value) * 7 (array1[3]) = 210
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets take the same example but forego passing in an initial value. This time it takes the value at array1's index #0 and uses that as its initial value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array1 = [1, 3, 5, 7];

const finalValue = array1.reduce(reducer);

function reducer(previousValue, currentElement){
  return previousValue * currentElement
}

console.log(finalValue)
=&amp;gt; Expected output: 105
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The calculation written out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 (array1[0]) * 3 (array1[1]) = 3

3 (previous value) * 5 (array1[2]) = 15

15 (previous value) * 7 (array1[3]) = 105
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.reduce() is a great iterator for distilling arrays down into a single value by applying a function.&lt;/p&gt;

&lt;h2&gt;
  
  
  .forEach() Method
&lt;/h2&gt;

&lt;p&gt;.forEach() works very similarly to .map() in that it takes a function then applies to to every element in the array. &lt;strong&gt;However!&lt;/strong&gt; An important distinction is that it does &lt;strong&gt;not&lt;/strong&gt; return a new array. In fact, it does not return anything.&lt;/p&gt;

&lt;p&gt;Lets take the first example and try doing .forEach() instead of .map():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array1 = [1, 3, 5, 7]

function multiplier(e){
   return e * 2
}

const newArray = array1.forEach(multiplier)

console.log(array1)
console.log(newArray)
==&amp;gt; Expected output: [1, 3, 5, 7]
==&amp;gt; Expected output: undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll notice now that the code returns undefined for &lt;em&gt;newArray&lt;/em&gt; instead of an array. That is because the .forEach() method does not return data.&lt;/p&gt;

&lt;p&gt;If you add a console.log() in the function itself, you'll notice that the individual elements in the array are still being operated 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 array1 = [1, 3, 5, 7]

function multiplier(e){
   return console.log(e * 2)
}

array1.forEach(multiplier)

console.log(array1)
==&amp;gt; Expected output: 2
==&amp;gt; Expected output: 6
==&amp;gt; Expected output: 10
==&amp;gt; Expected output: 14
==&amp;gt; Expected output: [1, 3, 5, 7]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;.forEach() is typically used in cases where you cannot use any other iterator methods for your specific purposes. It is very similar to other JS for/while loops. &lt;/p&gt;

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

&lt;p&gt;Please let me know in the comments if I've made any errors; I am still very new to coding in JS and these are notes to try to help me understand the concepts better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"&gt;MDN .map()&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find"&gt;MDN .find()&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"&gt;MDN .filter()&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce"&gt;MDN .reduce()&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach"&gt;MDN .forEach()&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Reviewing Javascript Comparisons</title>
      <dc:creator>ericksong91</dc:creator>
      <pubDate>Tue, 19 Jul 2022 19:30:56 +0000</pubDate>
      <link>https://dev.to/ericksong91/reviewing-javascript-comparisons-5ccf</link>
      <guid>https://dev.to/ericksong91/reviewing-javascript-comparisons-5ccf</guid>
      <description>&lt;p&gt;Hi y'all,&lt;/p&gt;

&lt;p&gt;This is where I'm going to be taking some notes on specific Comparison operators in Javascript. Typing this out will help me remember the specifics and may also be useful to you as a reference sheet! I will also be attempting to transliterate what the code is saying to make it easier to read.&lt;/p&gt;

&lt;h2&gt;
  
  
  Equality and Inequality Operators
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Strict Equality Operator (===)&lt;/strong&gt;&lt;br&gt;
Equal without any type conversions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;60 === 60;
// 60 (number) is strictly equal to 60 (number)
&amp;gt; true


60 === "60";
// 60 (number) is strictly equal to 60 (string)
&amp;gt; false

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Strict Inequality Operator (!==)&lt;/strong&gt;&lt;br&gt;
Unequal without any type conversions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;60 !== 60;
// 60 (number) is strictly not equal to 60 (number) 
&amp;gt; false


60 !== "60";
// 60 (number) is strictly not equal to 60 (string) 
&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Loose Equality Operator (==)&lt;/strong&gt;&lt;br&gt;
Equal with any type conversions (with extra examples)&lt;/p&gt;

&lt;p&gt;*Extra examples aren't necessarily accurate but they're true in the confines of the coding language&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;60 == "60";
// 60 (number) is loosely equal to 60 (string) 
&amp;gt; true

true == 1;
// true is loosely equal to 1 (number)
&amp;gt; true

"0" == false;
// 0 (string) is loosely equal to false
&amp;gt; true

null == undefined;
// null is loosely equal to undefined
&amp;gt; true

" " == 0;
// Empty Quotations is loosely equal to 0 (number)
&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Loose Inequality Operator (!=)&lt;/strong&gt;&lt;br&gt;
Inequal with any type conversions&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;60 != "60";
// 60 (number) is not equal to 60 (string)
&amp;gt; false

61 != 60;
// 61 (number) is not equal to 60 (number)
&amp;gt; true

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Relational Operators
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;greater than (&amp;gt;)&lt;/li&gt;
&lt;li&gt;greater than or equals (&amp;gt;=)&lt;/li&gt;
&lt;li&gt;less than (&amp;lt;)&lt;/li&gt;
&lt;li&gt;less than or equals (&amp;lt;=)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*Important to note that Javascript will attempt to convert strings into numbers here&lt;/p&gt;

&lt;p&gt;*For the last example, note that if both sides of the inequality are strings, it will only compare them lexicographically (left to right, by each character). It will NOT convert the whole string into a number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;70 &amp;gt; "60";
// 70 (number) is greater than 60 (string)
&amp;gt; true

70 &amp;gt;= 70;
// 70 (number) is greater than or equal to 70 (number)
&amp;gt; true

70 &amp;lt; "80";
// 70 (number) is less than 80 (string)
&amp;gt; true

70 &amp;lt;= "71";
// 70 (number) is less than or equal to 71 (string)
&amp;gt; true

"70" &amp;gt; "8";
// 70 (string) is greater than 8 (string)
&amp;gt; false (see note above)

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MDN:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators"&gt;Expressions and Operators&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness"&gt;Equality Comparisons and Sameness&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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