Next.js Discord

Discord Forum

react-router-dom tutorial issues

Answered
bobonlan posted this in #help-forum
Open in Discord
Avatar
following along with the tutorial and getting an issue where the search bar function only returns "No contacts" instead of anything that matches the search. No errors are popping up. code bits will be commented
Answered by Ejayz || PiggyDev
can you add in there !==0
Image
View full answer

60 Replies

import { Form, useLoaderData } from "react-router-dom";
import { getContact } from "../contacts";

export async function loader({ params }) {
  const contact = await getContact(params.contactId);
  return { contact };
}

export default function Contact() {
  const { contact } = useLoaderData();

  return (
    <div id="contact">
      <div>
        <img key={contact.avatar} src={contact.avatar || null} />
      </div>

      <div>
        <h1>
          {contact.first && contact.last ? (
            <>
              {contact.first} {contact.last}
            </>
          ) : (
            <i>No Name</i>
          )}{" "}
          <Favorite contact={contact} />
        </h1>

        {contact.twitter && (
          <p>
            <a target="_blank" href={`https://twitter.com/${contact.twitter}`}>
              {contact.twitter}
            </a>
          </p>
        )}

        {contact.notes && <p>{contact.notes}</p>}

        <div>
          <Form action="edit">
            <button type="submit">Edit</button>
          </Form>
          <Form
            method="post"
            action="destroy"
            onSubmit={(event) => {
              if (!confirm("Please confirm you want to delete this record.")) {
                event.preventDefault();
              }
            }}
          >
            <button type="submit">Delete</button>
          </Form>
        </div>
      </div>
    </div>
  );
}

function Favorite({ contact }) {
  let favorite = contact.favorite;
  return (
    <Form method="post">
      <button
        name="favorite"
        value={favorite ? "false" : "true"}
        aria-label={favorite ? "Remove from favorites" : "Add to favorites"}
      >
        {favorite ? "★" : "☆"}
      </button>
    </Form>
  );
}
import localforage from "localforage";
import { matchSorter } from "match-sorter";
import sortBy from "sort-by";

export async function getContacts(query) {
  await fakeNetwork(`getContacts:${query}`);
  let contacts = await localforage.getItem("contacts");
  if (!contacts) contacts = [];
  if (query) {
    contacts = matchSorter(contacts, query, { keys: ["first", "last"] });
  }
  return contacts.sort(sortBy("last", "createdAt"));
}

export async function createContact() {
  await fakeNetwork();
  let id = Math.random().toString(36).substring(2, 9);
  let contact = { id, createdAt: Date.now() };
  let contacts = await getContacts();
  contacts.unshift(contact);
  await set(contacts);
  return contact;
}

export async function getContact(id) {
  await fakeNetwork(`contact:${id}`);
  let contacts = await localforage.getItem("contacts");
  let contact = contacts.find((contact) => contact.id === id);
  return contact ?? null;
}

export async function updateContact(id, updates) {
  await fakeNetwork();
  let contacts = await localforage.getItem("contacts");
  let contact = contacts.find((contact) => contact.id === id);
  if (!contact) throw new Error("No contact found for", id);
  Object.assign(contact, updates);
  await set(contacts);
  return contact;
}

export async function deleteContact(id) {
  let contacts = await localforage.getItem("contacts");
  let index = contacts.findIndex((contact) => contact.id === id);
  if (index > -1) {
    contacts.splice(index, 1);
    await set(contacts);
    return true;
  }
  return false;
}

function set(contacts) {
  return localforage.setItem("contacts", contacts);
}

// fake a cache so we don't slow down stuff we've already seen
let fakeCache = {};

async function fakeNetwork(key) {
  if (!key) {
    fakeCache = {};
  }

  if (fakeCache[key]) {
    return;
  }

  fakeCache[key] = true;
  return new Promise((res) => {
    setTimeout(res, Math.random() * 800);
  });
}
Avatar
 {contacts.length ? (
            <ul>
              {contacts.map((contact) => (
                <li key={contact.id}>
                  <NavLink
                    to={`contacts/${contact.id}`}
                    className={({ isActive, isPending }) =>
                      isActive ? "active" : isPending ? "pending" : ""
                    }
                  >
                    {contact.first || contact.last ? (
                      <>
                        {contact.first} {contact.last}
                      </>
                    ) : (
                      <i>No Name</i>
                    )}{" "}
                    {contact.favorite && <span>★</span>}
                  </NavLink>
                </li>
              ))}
            </ul>
          ) : (
            <p>
              <i>No contacts</i>
            </p>
          )}
this is the part where it display contact right?
Avatar
yes
it's displaying the i message instead of something that matches whatever the search was
Avatar
can you console.log contacts
Avatar
where do i put that
Avatar
have you check what thus contacts contains already ?
contacts
do a useEffect checking for contact and console.log contacts
useEffect(() => {
 console.log(contacts)
  }, [contacts]);
Avatar
where at in which file do i need to put that
Avatar
ohhh on the gist one
Avatar
okay where at in that file
theres no export function contact
Avatar
the next useEffect
Image
Avatar
Image
i put the console log in and then tried searching name
Avatar
can you add in there !==0
Image
Answer
Avatar
instead of the ?
Avatar
no just add it
Avatar
nexto to contacts.length
Avatar
Image
Image
which one
both error
Avatar
contacts.length !== 00 ?
Avatar
no .
contacts.length !==0 ?
did it work ?
Avatar
yes
Avatar
ok cool
Avatar
No offense, but you should understand the code instead of just seeing and typing
Avatar
agree and i do for the mostpart
Avatar
Yeah, that was simple js logic
Nevermind, I have done the same multiple times
Avatar
no you're right
i can't tell ya what && means
or =>
or ||
Avatar
lmao
Avatar
the $ threw me for a loop yesterday
Avatar
Then, I think you should probably learn some basics
Avatar
no what he meant is that any length should be compared to a number and not boolean
when you leave it with that it would be considered a boolean which is false which lead to the condition to fall in no contacts
Avatar
almost everything i plan to make could be made with just html and css, react just makes it easier
Avatar
But js basics are important
Avatar
whats the best source to learn that
Avatar
youtube
Avatar
i've been following docs to learn react and a little nextjs
Avatar
i like how even in a 100 sec version you can't learn one thing without 20 other things being thrown at you
Avatar
hahah
Avatar
i try and learn html and when i hit a wall i get told to learn react
Avatar
just google stuff .w3school is one if you want to read
Avatar
then when i learn react im told i dont know enough of the basics
i jsut wish there was a linear path
like the most advanced thing my project will have is a forum, and that's not even guaranteed
anywho, the problem was solved. thank ya and goodnight