react-router-dom tutorial issues
Answered
bobonlan posted this in #help-forum
bobonlanOP
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
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);
});
}
{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?bobonlanOP
yes
it's displaying the i message instead of something that matches whatever the search was
can you console.log contacts
bobonlanOP
where do i put that
have you check what thus contacts contains already ?
contacts
do a useEffect checking for contact and console.log contacts
useEffect(() => {
console.log(contacts)
}, [contacts]);
bobonlanOP
where at in which file do i need to put that
@bobonlan where at in which file do i need to put that
ohhh on the gist one
bobonlanOP
okay where at in that file
theres no export function contact
the next useEffect
bobonlanOP
i put the console log in and then tried searching name
Answer
bobonlanOP
instead of the ?
@bobonlan instead of the ?
no just add it
@bobonlan instead of the ?
nexto to contacts.length
contacts.length !== 00 ?
@bobonlan Click to see attachment
no .
contacts.length !==0 ?
did it work ?
bobonlanOP
yes
ok cool
No offense, but you should understand the code instead of just seeing and typing
bobonlanOP
agree and i do for the mostpart
Yeah, that was simple js logic
Nevermind, I have done the same multiple times
bobonlanOP
the $ threw me for a loop yesterday
Then, I think you should probably learn some basics
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
@dumbboy Then, I think you should probably learn some basics
bobonlanOP
almost everything i plan to make could be made with just html and css, react just makes it easier
bobonlanOP
whats the best source to learn that
bobonlanOP
i've been following docs to learn react and a little nextjs
bobonlanOP
i like how even in a 100 sec version you can't learn one thing without 20 other things being thrown at you
hahah
bobonlanOP
i try and learn html and when i hit a wall i get told to learn react
just google stuff .w3school is one if you want to read
bobonlanOP
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