Tailored Pet Names Dev Journal Part 1: It Begins!

Tailored Pet Names Dev Journal Part 1: It Begins!

Buckle up, this is going to be a long series! I have been posting updates about building Tailored Pet Names since December 2022, but I have just decided to store them all in one (long) informal blog series.

These updates will be split into many separate blog posts so I don’t accidentally fry your browser with that much content 😉

Note: If you notice some extra spaces in the code blocks, you're not seeing things! Alas markdown applies some weird styling in code blocks that couldn't be defeated by:

  1. escaping the characters (ex: \ . is not working inside markdown code blocks to escape the periods)
  2. using their html entity codes

so the humble space reigns supreme here to defeat the weird markdown styling

image showing how text was automatically changed to very dark colors and how it was fixed by adding spaces between some elements

What is Tailored Pet Names?

Link: tailoredpetnames.com

A Next.js website which allows users to either

  1. find the purr-fect name for their pet or

  2. help adoption counselors improve pet adoption rates with unique names and/or descriptions!

Users can easily search and filter through community submitted names and descriptions. After signing up, users can save favorites, follow other users, and submit new names and descriptions. In the future, I’m considering allowing users to choose a preferred theme, so they’re not stuck with purple forever.

Technology: Next.js, React, Next-Auth, JavaScript, TailwindCSS, MongoDB, Mongoose, Cloudinary, Node /Mailer, SendGrid, SWR, resend, react-mail, CSS, HTML5

Thread for my project progress!

anakin skywalker with text this is where the fun beings

Twitter Post Link: twitter.com/Janetthedev/status/159839176768.. 11:01 AM · Dec 1, 2022


I started off with a bang 🤣 did " npm run start" and was going what the hell why won't it show my edits unless I reboot it.

I realized I needed to do npm run dev 🤦‍♀️

people starting a BMX bike race and immediately all crashing

Twitter Post Link: twitter.com/Janetthedev/status/159839239509.. Dec 1, 2022 Dec 1, 2022


Words alone cannot express my love for this next.js tutorial! Its so easy to understand so far 😍 youtube.com/watch?v=MFuwkrseXVE&ab_chan..

The projects coming along at a decent pace (for now)

capybara baby on top of parent with giddy up text

Twitter Post Link: twitter.com/Janetthedev/status/159842056960.. 12:55 PM Dec 1, 2022


I was getting a "Error: Element type is invalid: expected a string (for built-in components)" when importing a react component

I stared at my files for a second and realized I forgot to save the component's changes 🤡.

That immediate fix was instant serotonin!

Gif of man saying i laughed at my own stupidity

Twitter Post Link: twitter.com/Janetthedev/status/159844224862.. 2:21 PM Dec 1, 2022


I figured out how to change the placeholder text color using tailwindcss geeksforgeeks.org/tailwind-css-placeholder-.. the normal text color tailwindcss property wasn't working

Twitter Post Link: twitter.com/Janetthedev/status/159844653178.. 2:38 PM Dec 1, 2022


I was going to use this in the background, until I noticed one of them was "getting 💩 done " 😂

 gif of a cute litter of puppies, one is walking to the screen but one of the puppies in the background is pooping

Twitter Post Link: twitter.com/Janetthedev/status/159846389729.. 3:47 PM · Dec 1, 2022


Decent starting progress! Still more content to add and some styling to clean up, but its getting there 🔥

video showing the styled front page

Twitter Post Link: twitter.com/Janetthedev/status/159850359905.. 6:25 PM · Dec 1, 2022


I did a little bit more work on the landing page! Very rough, rough draft done.

The UI adjustments/colors ect are for future me to figure out 😂

shows the front page, describing how the page will help you find the purrfect name

showing the second page, describing how it will help you find creative descriptions for pets

showing the third page, explaining what a free profile gives you access to

Twitter Post Link: twitter.com/Janetthedev/status/159983498240.. 10:35 AM · Dec 5, 2022


I was struggling this morning to figure out why local images kept appearing broken??🥴

After watching this video I realized, I had forgotten for the public folder you don't retype out the whole address! youtube.com/watch?v=taMJct5oeoI&ab_chan.. It worked once I changed it to "profile.png" Huzzah

<img src='../public/profile.png'/>
<img src='/profile.png'/>

Twitter Post Link: twitter.com/Janetthedev/status/159983568110.. Dec 5, 2022


Although part of me wants to (FINALLY) start with the back-end, I know I'm too tired to work on it right now 😢

Time to nap 😴

kittens napping with a lab

Twitter Post Link: twitter.com/Janetthedev/status/159984262475.. 11:06 AM · Dec 5, 2022


I was trying to add links to the navbar in nextjs but I was getting this error:

Error: Multiple children were passed to <Link> with `href` of...

I found this tip about removing any space between and https://stackoverflow.com/questions/69667347/nextjs-multiple-children-were-passed-to-link-with-href-of-x-but-only-one/72754603

This fixed it! I would of NEVER of guessed 😂

Quotation from the stackOverflow Link:

"Are you sure that's how its written in your source file? This error usually happens if you have a space in between and the tags"

Twitter Post Link: twitter.com/Janetthedev/status/160017117467.. 8:51 AM · Dec 6, 2022


I used MongoDB playground to test if a basic read query to my database worked and it did! huzzah🎊

first backend step ✅

/ /  MongoDB Playground untitled-1

/ /  select the database to use.
use('main_site)

db.name_tags.findOne(
  {
     "_id":ObjectId("63423dafasf4324")
  }
)
Playground Result:
{
  "_id":{
    "$oid":"63423dafasf4324"
  },
  "tag_name":"male",
  "categories":[
    "638f31fasdflkjadsfs"
  ]
}

Twitter Post Link: twitter.com/Janetthedev/status/160019994041.. 10:46 AM · Dec 6, 2022


appsloveworld.com/mongodb/100/160/express-r..

I was trying to figure out why the test post request seemed to work, except the collection was blank!

Turns out the body was showing as "text" instead of "json!" Once I switched it to "json" in postman it worked

Twitter Post Link: twitter.com/Janetthedev/status/160055480705.. 10:16 AM · Dec 7, 2022


I've been trying to get chunks of the json data to show in a page but no luck so far🥴

I'm stopping for today before I go insane

cartoon penguin jumping on a keyboard. text says its no good. I don't know the codes

Twitter Post Link: twitter.com/Janetthedev/status/160058571282.. 12:19 PM · Dec 7, 2022


I couldn't resist trying to debug an axios error I kept getting: " OverwriteModelError: Cannot overwrite test5 model once compiled"

Adding some code to the left of my exports helped it stop yelling about using the model again "mongoose.models['test5']" 🎊🎊

code snippet:

"module.exports = mongoose.models['test5']|| mongoose.model("test5",CategoryCollectionSchema)

Twitter Post Link: twitter.com/Janetthedev/status/160059304097.. 12:48 PM · Dec 7, 2022


now I don't need to reboot my entire app every time I redo a freaking get request! huzzah 😂

the great evil axios error has been defeated!

Little girl saying the evil is defeated GIF

Twitter Post Link: twitter.com/Janetthedev/status/160059351364.. 12:50 PM · Dec 7, 2022


my brain was melting earlier clearly, that was a mongoose error not axios!

Twitter Post Link:twitter.com/Janetthedev/status/160061632924.. 2:20 PM · Dec 7, 2022


SWEET PROGRESS! The toggable accordion panels and checkboxes were made by mapping through these objects from my server!

I'm so happy🥺

showing a filter list, there are two categories holiday and gender. the holidays christmas easter and halloween can be selected with a checkbox. the gender selections also have a checkbox

   _id: ObjectId('6666666666')
   name: "holiday"
   links: Array
      0: "Christmas"
      1: "Easter"
      2: "Halloween"
    _ _v:0

    _id: ObjectId('777777')
    name: "gender"
    links: Array
       0: "Male"
       1: "Female"
       2: "Unisex"

Twitter Post Link: twitter.com/Janetthedev/status/160075767503.. 11:42 PM · Dec 7, 2022


next step i suppose will be to store whats been clicked in a react state? and then send that to the server as a second get request. Oh boy, thats gonna take a while.

(an example: store christmas + male in state, and only get back animal names with both those tags)

Twitter Post Link: twitter.com/Janetthedev/status/160075828386.. 11:44 PM · Dec 7, 2022


I made some slow but definite progress!

I can generate a list from the server and also by clicking the checkbox i can store the selected results in an array in the state. And clicking even removes it from the array (after lots of struggle haha)!

showing the checkboxes clicked, which then store up in the state in the react components section of the developer console

Twitter Post Link: twitter.com/Janetthedev/status/160113215452.. 12:30 AM · Dec 9, 2022


I'm still trying to figure out how to make it so it'll let me narrow down/filter the search... I want to start with all the names, and then have it look through the array of name objects (nameList here) and give me ones that have the given tags.

But that's for future me, Sleep time!

showing mongodb and the two categories for filters holidays and christmas, being stored in two objects. these two objects then link to an array of filters which relate to that category like christmas, easter and halloween

  let nameList= [
    {name:"santa", tags: ["Christmas","Male"]},
    {name:"beans", tags: ["food","Male"]}
  ]
<div> { nameList. map((name)=>(

   / /  if the name does not have ALL those tags stored in the state, exclude it
   / /  name: stanta, with tags christmas, male
    tags in filter: christmas, female, so it'd be excluded

   names.tags.every((element)=>
   tagFilters.includes(element))&&
   <div key={name&#46;name}>{name&#46;name} </div>>)
)}
</div>

Twitter Post Link: twitter.com/Janetthedev/status/160113431635.. 12:39 AM · Dec 9, 2022


Nothing like making a breakthrough while eating some chili! 🎊 It's a bit embarrassing to admit it took me hours, since the logic ended up being pretty simple. 😅But eh, lots of learning done and success is success ~

{ nameList. map((name)=>(

  / /  we want ONe result for each name, so map through names
     / /  names ex: beans, santa
    / /   then we want to look through EVERY tag filter ONCE
         / /  ex: filters: Male and Christmas
             / /  does the name have all these tags?
                 / /  ex: beans has male, but not christmas, so it'd return false
                 / /  while santa would return true, so it's rendered

    tagsFilters.every((tag)=>
              name.tags.includes(tag)&&
              <div key={ name .name}>{name .name}</div>
                )
))}

Twitter Post Link: twitter.com/Janetthedev/status/160134634062.. 2:41 PM · Dec 9, 2022


Though oddly it was chemistry of all things helped me! I had to think, what are the limiting factors and then write the code around the limiting factors

live pic of me fucking around and finding out with code before figuring things out. I'm a code arsonist today🔥🔥🔥

beaker being alarmed by fire in a chemistry lab

Twitter Post Link: twitter.com/Janetthedev/status/160134706743.. 2:44 PM · Dec 9, 2022


I realized I didn't show off the end result!

The names (bottom of the screen) render based on what tags are chosen

when unfiltered all names show, when filtered by male only male names like santa and beans show

only the name santa shows when filtering by male and christmas

Twitter Post Link: twitter.com/Janetthedev/status/160134811008.. 2:48 PM · Dec 9, 2022


Now to make it render prettily on the side!

Twitter Post Link: twitter.com/Janetthedev/status/160134887417.. 2:51 PM · Dec 9, 2022


Progress! The filtered results show in a table on the right

Twitter Post Link: twitter.com/Janetthedev/status/160143437108.. 8:31 PM · Dec 9, 2022


Next up I suppose will be to figure out how to add two requests to getStaticProps so I can grab the names from the server too

(right now I'm grabbing the names from a mock array in the document)

Twitter Post Link: twitter.com/Janetthedev/status/160144268270.. 9:04 PM · Dec 9, 2022


I just screwed around and what do you know, it actually works!

So the name data is being sent from the server now into the page🎉🎉🍾

Export const getStaticProps = async () => {

let response= await fetch(‘http: / /localhost: 3000/api/name-categories’);
let nameResponse = await fetch (‘http: / /localhost: 3000/api/individualNames’)

let data = await response.json()
let nameData= await nameResponse.json()

/ /   console.log(data)
/ /  getServerSideProps allows us to fetch data from an api
/ /  runs only on server side, will never run client side
/ /   can run server-side code directly in getStaticProps

  return {
      props: {
         category: data,
         nameList: nameData,
            },
        }
}

Twitter Post Link: twitter.com/Janetthedev/status/160146020755.. 10:14 PM · Dec 9, 2022


Up next will be either making profiles/adding passport ect

Or adding a form so users can submit new names

Twitter Post Link: twitter.com/Janetthedev/status/160146043087.. 10:14 PM · Dec 9, 2022


Ended up deciding to add a form to add new names 😄

I'm proud of my progress especially after working!

Users can select multiple tags (provided by a list from my server) and they can input a name. Both are saved in the state

screenshot showing that multiple tags can appear in the tag field

console.log Results:

name: l tags: Christmas, Male
name: le tags: Christmas, Male
name: leo tags: Christmas, Male
name: leon tags: Christmas, Male
import Select from 'react-select'
import React, {useState} from 'react';

export const getStaticProps = async () => {
  let tagList = await fetch('http: / /localhost:3000/api/individualTags');

  let tagData = await tagList.json()

  return {
    props:{
      tagList: tagData,
    }
  }
}
function AddNewNameWithTags({tagList}) {
  const [newName,setNewName=useState("")]
  const [tags,setTags]= useState([])

return (
  <div style={{width:"700px"}} className="mx-auto mt-4">
 {/*console.log(tagList[0].individualTag) */}
 {console.log(`name: ${newName} tags ${tags}`)}

 <form>
     {/* needs label and value for Select to work*/}
    <input type="text"
       placeholder="enter a name to add"
       onChange={(e)=> setNewName(e.target.value)}></input>

  <Select
      options={tagList. map((opt,index)=> ({label: opt. individualTag, value:opt. individualTag}))}
      isMulti
      isSearchable
      placeholder="select tags..."
      onChange={(opt)=>settings(opt. map(tag=>tag.label))}

       / /  update STATE of section of object
      />

      <button className="btn"> Add Name </button>
      {/*  submit state to server in correct format */}
      {/* if name already exists, send an error message */}
  </form>
  </div>
 );
}
export default AddNewNameWithTags;

Twitter Post Link: twitter.com/Janetthedev/status/160180381493.. 8:59 PM · Dec 10, 2022


Next step will be to have the button click = post request.

When setting up the post request I

  1. Need to give them an error message if an existing name is there
  2. have the objects from the state match the schema of the individualNames collection

Twitter Post Link: twitter.com/Janetthedev/status/160180481464.. 9:03 PM · Dec 10, 2022


Still need to work on the actual next steps, but progress for now

screenshot showing progress of name page, its possible to add a name, add tags and to search for a tag. There is also a seciton to add a tag, if the one you need is not there. Though in the future I took this out, to better secure the database

Twitter Post Link: twitter.com/Janetthedev/status/160184130367.. 11:28 PM · Dec 10, 2022


So on one hand: I'm now able to submit form data, which was stored in react state, to the server successfully 🎊HUZZAH

However! The filter system is now broken?? 🙃😂

Twitter Post Link: twitter.com/Janetthedev/status/160223302251.. 1:24 AM · Dec 12, 2022


Figured it out! It was because some of the tags were uppercase.

Filter system is unbroken again

bob the builder, can we fix it? yes we can!

Twitter Post Link: twitter.com/Janetthedev/status/160223348688.. 1:26 AM · Dec 12, 2022


next up is to make it so users can add new tags to the database.

But alas, I've got to work tomorrow so time to sleep!

cat sleeping on keyboard while random text appears on screen

Twitter Post Link: twitter.com/Janetthedev/status/160223491164.. 1:32 AM · Dec 12, 2022


Felt like I was going in circles trying to figure out why my TagList prop was working right but categoryList was undefined?! 🥴

Turns out it was the semicolons on line 10 and 11!

export const getServerSideProps = async () => {

  let tagList = await fetch('http: / /localhost:3000/api/individualTags');
  let categoryList = await fetch('http: / /localhost:3000/api/name-categories');

        let tagData = await tagList.json()
        let categoryData = await categoryList.json()

  return {
    props: {
      tagList: tagData,
      categoryList: categoryData,
    }
  }
}
function AddNewNameWithTags({tagList,categoryLIst}){

  return (
    <div style={{width:"700px"}} className="mx-auto mt-4">

        <NewNameWithTagsData tagList={tagList}/>
        <AddNewTag categoryList={categoryList}/>

    </div>
  );
}

export default AddNewNameWithTags;

Twitter Post Link: twitter.com/Janetthedev/status/160358281739.. 6:48 PM · Dec 15, 2022


realized I should change my data around a bit and change something from a post request to a put request 🤔

lets see how this goes!

Twitter Post Link: twitter.com/Janetthedev/status/160366389032.. 12:10 AM · Dec 16, 2022