Cannot read properties of null (reading useContext) - javascript

What I am trying to do is make it so when the submit button on my contact form is triggered and email is submitted , it redirects to another "success" page with confetti but instead I get Cannot read properties of null?
const router = useRouter();
const Contact = () => {
const form = useRef();
const sendEmail = (e) => {
e.preventDefault();
emailjs.sendForm('service', 'template', form.current, 'key')
.then((result) => {
console.log(values);
router.push({ pathname:"/success, query: values"});
}, (error) => {
console.log(error.text);
});
};

Related

Got a Uncaught (in promise) TypeError: n.indexOf is not a function while updating specific doc inside Firebase 9

I'm trying to update a specific doc inside firebase v9. It gives me this indexOf error.
Uncaught (in promise) TypeError: n.indexOf is not a function
at rt.fromString (index.esm2017.js:1032:1)
at sa (index.esm2017.js:16038:1)
at actions.js:136:1
at Object.dispatch (index.js:16:1)
at dispatch (<anonymous>:3665:80)
at editFeedback (EditFeedbackPage.js:55:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1)
I found some answers suggesting I'm referring to the non-existing doc in db.
To refer to the doc I'm using useParams() to get an id for the document.
In useEffect() I check if the id has a value and it shows that it has, but when I try to pass id into editFeedback() and use it in dispatch it appears to be undefined.
I also tried to store this id inside the state,
const [feedbackId, setFeedbackId] = useState(null)
setFeedbackId(id) // id from params
and then use it inside editFeedback(), but it still was undefined.
I guess it causes the problem and it shows me that indexOf error.
Maybe someone see where can be the issue.
EditFeedbackPage.js
const EditFeedbackPage = () => {
const initialState = {
category: "All",
comments: [],
detail: "",
id: nanoid(),
createdAt: Timestamp.now().toDate(),
status: "Suggestion",
title: "",
upVotesCount: []
}
const ref = useRef()
const [state, setState] = useState(initialState);
const { feedback } = useSelector((state) => state.data);
const { category, detail, title, status } = feedback;
console.log(feedback)
const params = useParams();
const { id } = params;
console.log("id from params => ", id)
// id from params => TexT99K7xz1Q2a4xv5PF
const dispatch = useDispatch();
const navigate = useNavigate();
const cancelAddFeedback = () => {
navigate("/")
}
useEffect(() => {
dispatch(getSingleFeedback(id));
console.log("feedbackId => ", id);
}, []);
const editFeedback = async (e, id) => {
e.preventDefault();
console.log("feedbackId => ", id);
dispatch(editFeedbackInit(id, feedback))
}
const handleInputChange = (e) => {
let { name, value } = e.target;
setState({ ...state, [name]: value })
}
const handleSubmit = (e) => {
e.preventDefault();
setState({ ...state, title: '', detail: "", category: "All" })
}
return (
<EditFeedbackContainer>
<EditFeedbackWholeContainer>
<NavbarFeedback />
<EditFeedbackInnerContainer>
<h2>Edit Feedback</h2>
<EditFeedbackFormContainer
onSubmit={handleSubmit}
>
<h4>Feedback Title</h4>
<label htmlFor="title">Add a short, descriptive headline</label>
<input
ref={ref}
type="text"
name='title'
defaultValue={title}
onChange={handleInputChange}
/>
---------------------
<EditFeedbackButtonsContainer>
<EditFeedbackButtonDelete
// onClick={deleteFeedback}
>
Delete
</EditFeedbackButtonDelete>
<EditFeedbackButtonCancel onClick={cancelAddFeedback}>Cancel</EditFeedbackButtonCancel>
<EditFeedbackButtonAdd
onClick={editFeedback}
>Edit Feedback</EditFeedbackButtonAdd>
</EditFeedbackButtonsContainer>
</EditFeedbackFormContainer>
</EditFeedbackInnerContainer>
</EditFeedbackWholeContainer>
</EditFeedbackContainer >
)
}
actions.js
// edit feedbacks actions
const editFeedbackStart = () => ({
type: types.EDIT_FEEDBACK_START,
});
const editFeedbackSussess = () => ({
type: types.EDIT_FEEDBACK_SUCCESS,
});
const editFeedbackFail = () => ({
type: types.EDIT_FEEDBACK_FAIL,
});
export const editFeedbackInit = (feedback, id, err) => {
return async function (dispatch) {
dispatch(editFeedbackStart());
console.log(id)
// await db.collection("feedbacks").doc(id).update(feedback);
// console.log(id)
// => also tried this version above
const feedDoc = doc(db, "feedbacks", id);
await updateDoc(feedDoc, feedback);
console.log(id)
dispatch(editFeedbackSussess());
if (err) {
dispatch(editFeedbackFail(err))
}
};
}
UPDATED:
Other methods such as add doc, delete doc, get doc, get all docs are working fine. There's only problem only with edit/update doc.
I was trying to ref the doc as I did when delete doc from firebase, which is working fine.
export const deleteFeedbackInit = (id, err) => {
return function (dispatch) {
dispatch(deleteFeedbackStart());
db.collection("feedbacks").doc(id).delete();
dispatch(deleteFeedbackSussess());
if (err) {
dispatch(deleteFeedbackFail(err))
}
};
}

Updating state with axios response data in reactjs

I am building a website using nextjs and axios. Users can apply to become a member and then be approved by admins. In the admin dashboard I initially load the users and the unapproved users and display them in a list.
When an admin clicks on a button the unapproved user should be approved. The functionality works. The only aspect I can't figure out is how to update the state.
Here is my code:
const AdminIndex = () => {
const [users, setUsers] = useState([])
const [unapprovedUsers, setUnapprovedUsers] = useState([])
useEffect(() => {
loadUnapprovedUsers()
loadUsers()
}, [])
const loadUnapprovedUsers = async () => {
const { data } = await axios.get('/api/admin/unapprovedUsers')
setUnapprovedUsers(data)
}
const loadUsers = async () => {
const { data } = await axios.get('/api/admin/users')
setUsers(data)
}
const approveUnapprovedUser = async (email) => {
try {
const { data } = await axios.put(
`/api/admin/approveUnapprovedUser/${email}`
)
setUnapprovedUsers([]) // only remove the approved user
setUsers(...data) // include the approved user into the array
} catch (err) {
console.log(err)
}
}
}
I am trying to remove the approved user from the unapprovedUsers array and try to add the user to the users array, hence updating the UI. The response returned by axios is an object, which doesn't make things easier.
I would be very thankful for any kind of help!
Just try to filter the unapprovedUsers with the users that don't have that email, also add the approved user to users state
const AdminIndex = () => {
const [users, setUsers] = useState([])
const [unapprovedUsers, setUnapprovedUsers] = useState([])
useEffect(() => {
loadUnapprovedUsers()
loadUsers()
}, [])
const loadUnapprovedUsers = async () => {
const { data } = await axios.get('/api/admin/unapprovedUsers')
setUnapprovedUsers(data)
}
const loadUsers = async () => {
const { data } = await axios.get('/api/admin/users')
setUsers(data)
}
const approveUnapprovedUser = async (email) => {
try {
const { data } = await axios.put(
`/api/admin/approveUnapprovedUser/${email}`
)
setUnapprovedUsers(prev => prev.filter(user => user.email !== email)) // only remove the approved user
setUsers(prev => [...prev, data]) // include the approved user into the array
} catch (err) {
console.log(err)
}
}
}

React Firebase displayName is returning null unless page is refreshed

I'm new to Firebase and using it for the first time to create a user system where you can sign up, login, and logout using Firebase authentication. There is a username state variable, and also a user state variable. Upon sign up the username is stored correctly, however the user variable is still returning null unless I refresh the page, then after the user shows correctly. Is there something that I'm missing?
const [open, setOpen] = useState(false);
const [openSignIn, setOpenSignIn] = useState(false);
const [modalStyle] = useState(getModalStyle);
const classes = useStyles();
const [username, setUsername] = useState("")
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [user, setUser] = useState(null);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser) {
// user is logged in...
console.log(authUser);
setUser(authUser.displayName);
if (authUser.displayName) {
} else {
//if user was just created
return authUser.updateProfile({
displayName: username,
});
}
} else {
setUser(null);
}
});
return () => {
unsubscribe();
};
}, [user, username]);
const signUp = (event) => {
event.preventDefault();
auth
.createUserWithEmailAndPassword(email, password)
.then((authUser) => {
authUser.user.updateProfile({
displayName: username
})
})
.catch((error) => alert(error.message));
setOpen(false)
}
const signIn = (event) => {
event.preventDefault();
auth
.signInWithEmailAndPassword(email, password)
.catch((error) => alert(error.message));
setOpenSignIn(false)
}
In recent versions of the web SDK (since v4.0.0 in May 2017), when the Auth#onAuthStateChanged() listener is fired changed to only on sign-in and sign-out but it used to be any changes to the ID token associated with the user (like updating the displayName). If you wanted to revert to the old functionality, you would instead use Auth#onIdTokenChanged().
useEffect(() => {
const unsubscribe = auth.onIdTokenChanged((authUser) => {
if (authUser) {
// user is logged in...
console.log(authUser);
setUser(authUser.displayName);
if (authUser.displayName) {
} else {
//if user was just created
return authUser.updateProfile({
displayName: username,
});
}
} else {
setUser(null);
}
});
return () => {
unsubscribe();
};
}, [user, username]);
I recommend renaming user to something else like userDisplayName as you should reserve user for use with instances of firebase.auth.User. This will prevent confusion with other code samples you stumble across.
Personally, I would recommend splitting this functionality out of the onAuthStateChanged handler like so:
// outside your component
function updateDisplayName(user, username) {
if (!user) {
return Promise.reject(new Error("You must be signed in first!"));
}
return user.updateProfile({
displayName: username
});
}
// inside your component
// user == undefined -> still verifying auth token
// user == null -> signed out
// user is a firebase.user.User -> user signed in
const [user, setUser] = useState(() => firebase.auth().currentUser || undefined);
// username == null -> signed out/still verifying user token/displayName not set
// username is a string -> user signed in & displayName set
const [username, setUsername] = useState(user ? user.displayName : null);
// userIsLoading == true -> still verifying user token, lock the form/show loading icon
// userIsLoading == false -> `user` is resolved and ready for use
const userIsLoading = user === undefined;
// a value to store the proposed new username, connect this to an input
const [newUsername, setNewUsername] = useState("");
// an error message for the input of `newUsername`
const [usernameError, setUsernameError] = useState(null);
// keep `user` & `username` (if available) up to date
useEffect(() => auth.onAuthStateChanged((user) => {
setUser(user);
setUsername(user ? user.displayName : null);
}), []);
// attach this to a button - don't connect to "onChange" of "newUsername"
// note: this returns a Promise that finishes when the username was either updated or failed to update
const onChangeUsernameSubmit = () => {
return updateDisplayName(user, newUsername)
.then(() => {
// updated successfully. update state
setUsername(newUsername);
setUsernameError(null);
})
.catch((err) => {
// failed to change username. invalid value? expired token?
setUsernameError("username not changed: " + (err.message || "something unexpected went wrong"));
});
}

Unable to access route params (functional component)

I am trying to pass the username from signup1 to signup 2:
handleSignUp = () => {
console.log(this.state.username) <------------- This logs correctly
try {
this.props.navigation.navigate('Signup2', {
username: this.state.username, <------------- Passing here
});
} catch (error) {
console.log(error);
}
}
Here is the code from Signup2:
const Signup2 = (props, route, navigation) => {
const { username } = route.params; <----------- Trying to access it here
I get the following error:
undefined is not an object (evaluating 'route.params.username')
I have also tried this:
const { username } = props.route.params
And neither work.
How can I access the route params?
I believe you would need to destructure your route and navigation properties if you'd like to access them as intended.
You can go for:
const Signup2 = ({route, navigation}) => {
const { username } = route.params
}
Or maybe:
const Signup2 = (props) => {
const { username } = props.route.params
}

How to insert React Array data to Mysql with Axios & Express?

i need to insert a prescription details in mySQL database, but i struggle to inserting it with array data.
I have 2 states, 1 array state to keep the medicines i push into it then send the values to axios when done & 1 state to save the selected medicine.
My options example: using react-select
const medicine = [
{ id_obat: '123', label: 'Amoxcilin 300mg' },
{ id_obat: '321', label: 'Ibuprofen 500ml' }
];
React codes:
const [values, setValues] = useState([]);
const [meds, setMeds] = useState({
obat: {},
cara_pakai: '',
kuantitas: ''
});
const initialState = {
obat: {},
cara_pakai: '',
kuantitas: ''
};
const handleChange = obat => {
setMeds({ ...meds, ['obat']: obat });
};
const addMed = () => {
setValues([...values, meds]);
setMeds({ ...initialState });
};
const onSubmit = e => {
e.preventDefault();
addPrescript(values);
};
My axios action to send it to my API:
export const addPrescript = values => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
const form = qs.stringify(values);
try {
const res = await axios.post('/api/prescription', form, config);
dispatch({ type: ADD_PRESCRIPT, payload: res.data });
dispatch(setAlert('Submit Success', 'success', 3000));
} catch (err) {
let errors = err.response.data.errors;
if (errors) {
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
}
}
};
My prescription controller:
exports.createPrescription = async (req, res) => {
const { id_obat, cara_pakai, kuantitas, deskripsi } = req.body;
const p_value = {
deskripsi: deskripsi
};
const p_sql = 'INSERT INTO resep SET ?';
const d_sql = 'INSERT INTO detail_resep SET ?';
conn.query(p_sql, p_value, (error, p_result) => {
if (error) throw error;
let d_value = [
{
id_resep: p_result.insertId,
id_obat: id_obat,
cara_pakai: cara_pakai,
kuantitas: kuantitas
}
];
conn.query(d_sql, [d_value], (error, d_result) => {
if (error) throw error;
res.status(200).json({
values: d_result
});
});
});
};
My backend server keep sending me error [You have an error in your SQL syntax], i dont know how to solve it.
my API required req.body to submit is | id_resep | id_obat | cara_pakai | kuantitas | to be success inserted. i dont know if im wrong with the stringify. my first time work with array data :>
Any help appreciated.
look like below statement has to change
const p_sql = 'INSERT INTO resep SET ?';
const d_sql = 'INSERT INTO detail_resep SET ?';
to
const p_sql = 'INSERT INTO resep( {columnname}) values({value1,value2})';
const d_sql = 'INSERT INTO detail_resep ( {columnname}) values({value1,value2}))';
change {columnname } to your column name and corresponding values in {value}
Basically insert statement syntax is not correct here.

Categories

Resources