Phil Anderson
Phil Anderson

Reputation: 46

VueJS MEVN stack - axios put 'Error: Request failed with status code 404' although Postman 'put' works fine

I'm following a tutorial to build a full stack app using VueJS and the MEVN stack. I have

Back end routes are

const express = require('express');
const studentRoute = express.Router();

// model
let StudentModel = require('../models/Student');

studentRoute.route('/create-student').post((req, res, next) => {
  console.log('creating one student at /create-student')
  StudentModel.create(req.body, (error, data) => {
  if (error) {
    return next(error)
  } else {
    console.log(`student created ${JSON.stringify(data)}`)
    res.json(data)
  }
})
});

studentRoute.route('/').get((req, res, next) => {
  console.log('GET all students')
    StudentModel.find((error, data) => {
     if (error) {
       return next(error)
     } else {
       res.json(data)
     }
   })
 })

studentRoute.route('/edit-student/:id').get((req, res, next) => {
  console.log('get one student at /edit-student/:id')
   StudentModel.findById(req.params.id, (error, data) => {
    if (error) {
      return next(error)
    } else {
      res.json(data)
    }
  })
})

// Update
studentRoute.route('/update-student/:id').post((req, res, next) => {
  console.log(`attempting to update one student with id ${req.params.id}`)
  console.log(`request body = `)
  console.log(JSON.stringify(req.body))
  console.log(req.body)
  StudentModel.findByIdAndUpdate(req.params.id,
     { $set: req.body },
   (error, data) => {
    if (error) {
      console.log(`an error has taken place`)
      return next(error);
    } else {
      res.json(data)
      console.log('Student successfully updated!')
    }
  })
})

// Delete
studentRoute.route('/delete-student/:id').delete((req, res, next) => {
  console.log('delete one student at /delete-student/:id')
  StudentModel.findByIdAndRemove(req.params.id, (error, data) => {
    if (error) {
      return next(error);
    } else {
      res.status(200).json({
        msg: data
      })
    }
  })
})

module.exports = studentRoute;

front end update code is

<template>
    <div class="row justify-content-center">
        <div class="col-md-6">
            <h3 class="text-center">Update Student</h3>
            <form @submit.prevent="handleUpdateForm">
                <div class="form-group">
                    <label>Name</label>
                    <input type="text" class="form-control" v-model="student.name" required>
                </div>

                <div class="form-group">
                    <label>Email</label>
                    <input type="email" class="form-control" v-model="student.email" required>
                </div>

                <div class="form-group">
                    <label>Phone</label>
                    <input type="text" class="form-control" v-model="student.phone" required>
                </div>

                <div class="form-group">
                    <button class="btn btn-danger btn-block">Update</button>
                </div>
            </form>
        </div>
    </div>
</template>

<script lang="ts">
import { Vue } from 'vue-class-component';
import axios from "axios";
export default class EditComponent extends Vue {

  student!: {
    name: '',
    email: '',
    phone: ''
  }

  data() {
    return {
      student: { }
    }
  }

  created() {
    let apiURL = `http://localhost:4000/api/edit-student/${this.$route.params.id}`;
    axios.get(apiURL).then((res) => {
        this.student = res.data;
    })
  }

  handleUpdateForm() {
    let id = this.$route.params.id
    let apiURL = `http://localhost:4000/api/update-student/${this.$route.params.id}`;
    console.log(`attempt to update student at url`)
    console.log(apiURL)
    console.log(`with id`)
    console.log(id)
    console.log(`attempt to update student ${JSON.stringify(this.student)}`)
    axios.put(apiURL, this.student)
    .then(res => {
        console.log(`response is ${res}`)
        this.$router.push('/view')
    })
    .catch(error => {
        console.log('error when updating student')
        console.log(error)
    });
  }
}
</script>

when I use Postman I get this response from the api

attempting to update one student with id 6119d671cc9ce131207bd37c
request body = 
{"_id":"6119d671cc9ce131207bd37c","name":"PHIL","email":"[email protected]","phone":7888849991,"__v":0}{ _id: '6119d671cc9ce131207bd37c',
  name: 'PHIL',
  email: '[email protected]',
  phone: 7888849991,
  __v: 0 }
Student successfully updated!

when I use VueJS to update my Student I get the following error from this code

// Update
studentRoute.route('/update-student/:id').post((req, res, next) => {
  console.log(`attempting to update one student with id ${req.params.id}`)
  console.log(`request body = `)
  console.log(JSON.stringify(req.body))
  console.log(req.body)
  StudentModel.findByIdAndUpdate(req.params.id,
     { $set: req.body },
   (error, data) => {
    if (error) {
      console.log(`an error has taken place`)
      return next(error);
    } else {
      res.json(data)
      console.log('Student successfully updated!')
    }
  })
})
attempt to update student at url
EditComponent.vue?720f:29 http://localhost:4000/api/update-student/6119d671cc9ce131207bd37c
EditComponent.vue?720f:30 with id
EditComponent.vue?720f:31 6119d671cc9ce131207bd37c
EditComponent.vue?720f:32 attempt to update student {"_id":"6119d671cc9ce131207bd37c","name":"PHIL","email":"[email protected]","phone":123,"__v":0}
xhr.js?b50d:177 PUT http://localhost:4000/api/update-student/6119d671cc9ce131207bd37c 404 (Not Found)
dispatchXhrRequest @ xhr.js?b50d:177
xhrAdapter @ xhr.js?b50d:13
dispatchRequest @ dispatchRequest.js?5270:52
Promise.then (async)
request @ Axios.js?0a06:61
Axios.<computed> @ Axios.js?0a06:87
wrap @ bind.js?1d2b:9
handleUpdateForm @ EditComponent.vue?720f:33
eval @ EditComponent.vue?2308:5
eval @ runtime-dom.esm-bundler.js?830f:1400
callWithErrorHandling @ runtime-core.esm-bundler.js?5c40:6988
callWithAsyncErrorHandling @ runtime-core.esm-bundler.js?5c40:6997
invoker @ runtime-dom.esm-bundler.js?830f:347
EditComponent.vue?720f:39 error when updating student
EditComponent.vue?720f:40 Error: Request failed with status code 404
    at createError (createError.js?2d83:16)
    at settle (settle.js?467f:17)
    at XMLHttpRequest.handleLoad (xhr.js?b50d:62)

I'm aware mongo has updated their methods for handling updates and have tried the following

1)

  StudentModel.findByIdAndUpdate(req.params.id,
     { $set: req.body },
   (error, data) => {
  StudentModel.findOneAndUpdate({_id:req.params.id},
     { $set: req.body },
   (error, data) => {
  StudentModel.updateOne({_id:req.params.id},
     { $set: req.body },
   (error, data) => {

In each case I am getting the error above and in each case Postman works fine. So there's a problem with the URL being formed and I'm not sure what it is???

Your help would be appreciated!

Thank you

Philip

Also, just in case it is relevant, here is the back end app.js

let express = require('express'),
  cors = require('cors'),
  mongoose = require('mongoose'),
  database = require('./database'),
  bodyParser = require('body-parser');

// Connect mongoDB
mongoose.Promise = global.Promise;
//mongoose.set('useFindAndModify',false);
mongoose.connect(database.db, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(() => {
    console.log("Database connected")
  },
  error => {
    console.log("Database could't be connected to: " + error)
  }
)

const studentAPI = require('../api/routes/student.route')
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: false
}));
app.use(cors());

// API
app.use('/api', studentAPI)

// Create port
const port = process.env.PORT || 4000;
const server = app.listen(port, () => {
  console.log('Connected to port ' + port)
})

const logUsage = (logCode) => {
  console.log(`http serving with code ${logCode}`)
}

app.use((req, res, next) => {
  console.log(`logging data in 'next'`)
  next(logUsage(200));
});

app.use(function (err, req, res, next) {
  console.log('in app.use')
  console.error(err.message);
  if (!err.statusCode) err.statusCode = 500;
  res.status(err.statusCode).send(err.message);
});

Upvotes: 1

Views: 441

Answers (1)

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23510

You can try to replace post in update route with put

Upvotes: 1

Related Questions