Open mwhite192 opened 1 year ago
@mwhite192 looking at this real quickly it looks like you're defining the formData right away with (potentially) empty strings as values. I would suggest moving that process into the handleSubmit function you've set up, right before you use fetch(), i'm not sure if that's the only thing going on but is definitely my first guess :)
Oh an don't forget to uncomment out your route! (it might be locally but just in case!) https://github.com/mwhite192/groupomania/blob/master/backend/routes/profile.js#LL14C68-L14C68
Same with the controller :)
@mwhite192 When updating the profile, I don't think you need to instantiate a new Profile instance, couldn't you essentially spread the req.body? You may want to include the userId property in the form data you're sending too, so it's available in the controller. Maybe something like:
const updatedProfile = { ...req.body };
if (req.file) {
updatedProfile.imageUrl = url + '/images/' + req.file.filename;
}
Profile.updateOne({ userId: req.body.userId }, updatedProfile).then(...).catch(...)
@AccessiT3ch - Hey Conor! So I made the changes and got 404 NOT FOUND response!!!!! That's better than a 500 error. Now my question is do I have to pass in the actual userId in the fetch or do I just make sure the endpoint matches the endpoint in the fetch.
So I made the changes and got 404 NOT FOUND response!!!!!
Sweet! Yup that's better than a 500, lol, now the question is where is the 404 coming from? Is it from the catch after updateOne? If you console.log the req.body.userId, what does it give you? If it's an empty string, then it would make sense that it's giving a 404 because there are no profiles with userIds that are an empty string. If it's undefined, I would expect a 400 response, if not a 500 :)
do I have to pass in the actual userId in the fetch
Yup! In your component that is making the fetch request, you should have the userId at the time of fetch, so you can simply append it to the formData with the rest of the properties so it's available in the backend
do I just make sure the endpoint matches the endpoint in the fetch.
Well, we always need to make sure our fetch urls match up to the routes defined in the backend, if you don't want to append the userId you could always structure the route to accept a route parameter for the user id, something like:
// backend route
app.put('/api/profile/:userId', auth, multer, updateProfileController);
// frontend fetch
fetch('//localhost:3000/pi/profile/' + userId, {
method: 'PUT',
body: formData,
}).then(...).catch(...);
@AccessiT3ch - I got it work and was able to udpate the profile. I verified that in MongDB; however, it didn't update my user state in the store for me to access that info. So I might add a slice to get the updated profile or should I just change around the user slice?
@mwhite192 Sweet! Often times the server will send the asset that was updated back to in the response (res.status(204).json(profile)
) so it can be used in the fetch.then() to dispatch an action adding or updating the profile in the store. If you want to keep the profile data in your profileSlice under user
, then all you need to do is add an action (and corresponding reducer function) to the slice.
If you wanted to decouple the session information and the profile information (so you can save multiple profiles to state), it might make sense to move the session action/reducer into it's own sessionSlice.
@AccessiT3ch - So just to make sure I understand what your saying, it might be best to have just a userSlice and profileSlice so I can store multiple users and profiles in the store correct?
Yeah i think it would make sense since they're pretty different in terms of what the data is being used for. Whereas the session data is used for controlling certain functionalities, the profile data is purely for rendering purposes.
Honestly, i would probably make a copy of the profileSlice and call it the sessionSlice. Then you can refactor your profileSlice to save profiles by userId, that way when you render a post, you have all the profile info for the author of the post already. By saving other profile objects in the store you'll avoid re-fetching profile data again and again.
Does that make sense?
@AccessiT3ch - That does make sense! I am already working on the profileSlice (aka type copying so I can really hammer redux in my brain) now, so I will refactore to have the OG profileSlice a session slice. Now to make sure I understand that way I know how to code this.......when the user edits their profile, they can change their email and password. I was thinking that I could create an update user function that updates the users credentials and call that function in the backend somewhere. Would that be the way to handle that?
Sweet, and you could definitely make a backend function to handle updating the user credentials! The action resetting credentials would probably require a dedicated "/auth/.." route and controller in the backend. I would say any common code you need between the registerUser and updatePassword controllers would make for a lovely updateUser function to avoid duplicate code!
@AccessiT3ch - I have auth middleware......does that count?
@mwhite192 the auth middleware will be included in your route setup, b/c we need to know the user is authenticated (with the token).
What I meant was that I think if you were to write a new controller for resetting the password, you would notice a lot of overlap with the sign-up controller. If you could extract that functionality (of finding a user, comparing the current passwords, updating the user in the db, etc) you would have some nice utility functions that you can reuse throughout the backend. That's definitely not required at this point, but if it's convenient (so as to not repeat code) then go for it!
@AccessiT3ch - I get what you're saying. I will work on that tomorrow/today along with the post and comments. I do have a question for you. I am working on the delete functionality and I keep getting unauthorized. I created a new instance of the form data in my handleDelete function, I appended just the userId to the request body, but when I submit to delete, I keep getting either unauthorized or not found responses. I made sure my endpoints were the same and I made sure to complete the Profile.userId to the req.body.userId. I know there is an extra step in there somewhere lol. What could I be doing wrong?
@mwhite192 i can look at this more in the morning, but it does look like DELETE method http requests cant have a body on the request. So instead of using form data and appending it, you might try using a url param to define the userId for this route.
@AccessiT3ch - Hey Conor!
I'm in need of another pair of eyes. I am trying to update the user's profile. I implemented the same method as with the register page. I created a new instance of formData and sent that to the backend in the request body. I included the profile ID to help identify the profile. I specified this in the route, but not matter what happens I either get a 500 internal server error or a 404 not found error. I think it has something to do with the routes, my fetch, my form or all three. Would you be so kind as to take a look and see where I messed up please and thank you?