menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

JS Everywhere

A community for the JavaScript Everywhere book by Adam Scott, published by O'Reilly.

Channels
Team

Something on Edit Form Ch.16

August 3, 2020 at 7:51am

Something on Edit Form Ch.16

August 3, 2020 at 7:51am
// if the current user and the author of the note do not match if (userdata.me.id !== data.note.author.id) { return <p>You do not have access to edit this note</p>; }
Gives me problems. It is always undefined, because my api returns "me" for GET_ME. So if I change it to:
const { data: me } = useQuery(GET_ME);
It does get "me" value correctly after console logging undefined for "me" a couple times. The issue is that, by the time we check the conditional either "me.id" is undefined or "data.note.author.id" is. So there seems to be a race condition. Unless I am a victim of the Node cache, source code has the same problem (npm run dev author's final versions of React and API, I had the exact same issue). Any ideas?
Thanks.

August 7, 2020 at 8:26pm
Apologies for the slow reply - I've been on holiday
I cannot seem to reproduce this bug, both manually and with Cypress tests. Are you using the "starter repo"? If so, what version of Node are you using? Thanks! My apologies for the difficulties
No worries. Also, apologies, maybe something else going on. Even though I am running npm run dev from final folders for both, for whatever reason it was running my code. This is a strange issue, even after I --force cleared npm cache. Regardless, I was able to get "me" and "note." Still because there are two queries one of them is undefined when one is defined, and then it causes checking of a property of an undefined.
After I added this, the issue is resolved:
const EditNote = props => {
// store the id found in the url as a variable
const id = props.match.params.id;
// define our note query
const { loading, error, data: note } = useQuery(GET_NOTE, { variables: { id } });
// fetch the current user's data
const { loading: l, error: e, data: me } = useQuery(GET_ME);
// define our mutation const [editNote] = useMutation(EDIT_NOTE, { variables: { id },
onCompleted: () => {
props.history.push(`/note/${id}\`);
}
});
console.log(me);
console.log(note);
// if the data is loading, display a loading message
if (loading || l) return 'Loading...';
// if there is an error fetching the data, display an error message
if (error) return <p>Error!</p>;
// if the current user and the author of the note do not match
if (me && note && note.author && me.id !== note.author.id) {
return <p>You do not have access to edit this note</p>;
}
// pass the data and mutation to the form component
return <NoteForm content={note.content} action={editNote} />;
};
For some reason, even not having "note.author" check was causing "referencing id of an undefined property." But this works. Sorry about it, have no idea why the original was causing problems. My node version is 12.2.0. Thanks for the response.
Edited

August 10, 2020 at 1:53am
Glad to see that you got it working ! I'm not quite sure where the discrepancy is, but I'll definitely take a closer look.
For future Googlers - if you come across this with a similar issue, please let me know!
Thanks , from what I understand, React is re-rendering, and normally I guess Apollo should have loading status and thus not reach the conditional check for ids. However, at some point it does go beyond loading status, but still doesn't have either me or note.author? I am not so clear on how ApolloClient handles requests, but regardless above solution works. Just a bit busy, and wasn't sure why. Thanks for the help.

August 2, 2021 at 7:41am
my node version is v15.11.0 const { data:userdata,loading:userLoading } = useQuery(GET_ME); if (loading || userLoading) return 'Loading...'; render dom after all done