Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Mike Lundahl
Mike Lundahl
13,510 Points

update MongoDB (mongoose) using express & react

I'm having a hard time figuring out what I did wrong. I have a user profile component that I want the logged in user to able to change his/her userdata like email, name, address etc. Feels like I've tried everything but I can't seem to figure it out.

Route file:

var express = require('express');
var methodOverride = require('method-override');
var router = express.Router();
var User = require('../models/user');
var path = require('path');
var mid = require('../middleware');
var logger = require('../util/logger');
var app = express();

app.use(methodOverride('_method'));
app.use(methodOverride('X-HTTP-Method'));
app.use(methodOverride('X-HTTP-Method-Override')); 
app.use(methodOverride('X-Method-Override')); 

router.put('api/update/:id', function(req, res){
    User.findByIdAndUpdate(req.params.id,
                        {
                            email: req.body.email,
                            userName: req.body.userName,
                            firstName: req.body.firstName,
                            lastName: req.body.lastName,
                            password: req.body.password            
                        },  
                        function(err, response){
                                if (err) {
                    res.send(err);
                    } else {
                            console.log(response);
                            console.log('user updated!');
                            res.redirect('/profile');
                                            }
                        });
});

react component:

import React, {Component} from 'react';
import { BrowserRouter as Router, Route, Link  } from 'react-router-dom';


export default class UserProfile extends Component {

    constructor(props) {
        super(props);

        this.state = {
            data: { userName: 'noUser',
                    firstName: ''
                  }

            };
    }

        render() {

        return (
            <div className="normalContentWrapper">
                <div id="profile">
                    <h1>Profile</h1>
                        <div className="profile-container">
                            <h2>Welcome, {fetchUser.userName}</h2>
                            <form className="profile-form" method="POST" action="api/update/{{_id}}?_method=PUT">
                                <input type="text" placeholder={fetchUser.firstName} name="firstName" className="profile-input"/><br/>
                                <input type="text" placeholder={fetchUser.lastName} name="lastName" className="profile-input"/><br/>
                                <input type="text" placeholder={fetchUser.userName} name="userName" className="profile-input"/><br/>
                                <input type="text" placeholder={fetchUser.email} name="email" className="profile-input"/><br/>
                                <input type="text" placeholder="Change Password" name="password" className="profile-input"/><br/><br/>
                                <input type="submit" value="Save changes" className="btn"/>
                            </form>
                        </div>
                        <div className="profile-container">
                            <h2>Payment</h2>
                            <p>Edit payment methods</p>
                        </div>
                    </div>
            </div>
            );
        }
    }

I can also add to that, creating a new user, logging in & out etc works fine.

1 Answer

Kyle Johnson
Kyle Johnson
33,528 Points

Hi Mike,

Looking at the mongoose documentation for findByIdAndUpdate, I think you may not be saving the changes. I don't think the code below is saving anything.

{
     email: req.body.email,
     userName: req.body.userName,
     firstName: req.body.firstName,
     lastName: req.body.lastName,
     password: req.body.password            
}

The mongoose documentation is using $set before that block of code.

Tank.findByIdAndUpdate(id, { $set: { size: 'large' }}, { new: true }, function (err, tank) {
  if (err) return handleError(err);
  res.send(tank);
});

Also, if you do not need the document returned, you may want to use update instead.

Here is the link for mongoose documents

Lastly, this might help too: https://stackoverflow.com/questions/27108177/mongoose-findbyidandupdate-doesnt-work-with-req-body

Mike Lundahl
Mike Lundahl
13,510 Points

Thanks Kyle! I'm still getting "Cannot POST" message :(

Mike Lundahl
Mike Lundahl
13,510 Points

I got the method-override to work by moving it to the main app file. But I'm still getting "Cannot PUT /api/update/%7B%7B_id%7D%7D"

Changed the route to look like

router.put('api/update/:id', function(req, res){
    User.findByIdAndUpdate(req.params.id, {$set:req.body}, function(err, response){
                             if(err){
                                                    console.log(err);
                                }
                                res.send('Done');

                        });
});