I'm converting an old LAMP stack project to use Node/Express/MongoDB instead of PHP/Laravel/MySQL. I built out my routes the same way I did in Laravel and have tested the routes I've built using Postman. Every route works as it should through testing in Postman.
However, when I try to use these routes in the display.js file that I wrote, the only route that works is GET /players. I am looking for some insight on these routes and the display file I'm using.
When I click the edit button, my GET /player/:id route grabs the correct information (status code 200 and preview shows JSON object) but will not populate the fields in my form.
When I click the delete button, I get a 404 status code with a response of "Cannot GET /players/123/delete". How do I adjust my display code to use DELETE instead of GET? (I believe I can refactor my all of my routes to just /players/:id using the correct http request method if I can figure out how to pass the request method in the display.js code).
When I try to submit a new record, I get a 400 status code with validation error saying Path age
is required. It's actually the same error for each field name, so I assume that I'm not passing the values from the field into the JSON object correctly.
I haven't been able to test patch, but believe it should be remedied through fixing DELETE /players/:id and GET /players/:id.
Any help is appreciated. Code is below for display and server js files.
display.js
// this is the base url to which all your requests will be made
var baseURL = window.location.origin;
$(document).ready(function(){
// $.ajaxSetup({
// headers: {
// 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
// }
// });
$('#table').click(function(event) { // generates the table
// change the url parameters based on your API here
// Using an JQuery AJAX GET request to get data form the server
$.getJSON(baseURL+'/players', function(data) {
generateTable(data, $('#container'));
});
});
$('#form').click(function(event) {
// creating an empty form
generateForm(null, $('#container'));
});
// Handle table click event for delete
$('#container').on('click', '.delete', function(event) {
var id = $(this).val();
// change the url parameters based on your API here
// remember to create delete functionality on the server side (Model and Controller)
// Using an JQuery AJAX GET request to get data form the server
$.getJSON(baseURL+"/players/"+id+"/delete", function(data) {
//Generate table again after delete
//change the url based on your API parameters here
// Using an JQuery AJAX GET request to get data from the server
$.getJSON(baseURL+'/players', function(data) {
generateTable(data, $('#container'));
});
});
});
// Handle form submit event for both update & create
// if the ID_FIELD is present the server would update the database otherwise the server would create a record in the database
$('#container').on('submit', '#my-form', function(event) {
var id = $('#id').val();
console.log(id);
if (id != "") {
event.preventDefault();
submitForm(baseURL+"/players/"+id+"/edit", $(this));
} else {
event.preventDefault();
submitForm(baseURL+"/player", $(this));
}
});
// Handle table click event for edit
// generates form with prefilled values
$('#container').on('click', '.edit', function(event) {
// getting id to make the AJAX request
var id = $(this).val();
// change the url parameters based on your API here
// Using an JQuery AJAX GET request to get data form the server
$.getJSON(baseURL+'/players/'+id, function(data) {
generateForm(data, $('#container'));
});
});
// function to generate table
function generateTable(data, target) {
clearContainer(target);
//Change the table according to your data
var tableHtml = '<table><thead><tr><th>Name</th><th>Age</th><th>Position</th><th>Team</th><th>Delete</th><th>Edit</th></tr></thead>';
$.each(data, function(index, val) {
tableHtml += '<tr><td>'+val.playername+'</td><td>'+val.age+'</td><td>'+val.position+'</td><td>'+val.team+'</td><td><button class="delete" value="'+val._id+'">Delete</button></td><td><button class="edit" value="'+val._id+'">Edit</button></td></tr>';
});
tableHtml += '</table>';
$(target).append(tableHtml);
}
// function to generate form
function generateForm(data, target){
clearContainer(target);
//Change form according to your fields
$(target).append('<form id="my-form"></form>');
var innerForm = '<fieldset><legend>Player Form</legend><p><label>Player Name: </label>'+'<input type="hidden" name="id" id="id"/>'+'<input type="text" name="playername" id="playername" /></p>' + '<p><label>Age: </label><input type="text" name="age" id="age" /></p>'+ '<p><label>Hometown: </label><input type="text" name="city" id="city" />'+ ' ' + '<input type="text" name="country" id="country" /></p>' + '<p><label>Gender: </label><input type="text" name="gender" id="gender" /></p>'+ '<p><label>Handedness: </label><input type="text" name="handedness" id="handedness" /></p>'+ '<p><label>Broom: </label><input type="text" name="broom" id="broom" /></p>'+ '<p><label>Position: </label><input type="text" name="position" id="position" /></p>'+ '<p><label>Team: </label><input type="text" name="team" id="team" /></p>'+ '<p><label>Favorite Color: </label><input type="text" name="favoritecolor" id="favoritecolor" /></p>'+ '<p><label>Headshot: </label><input type="text" name="headshot" id="Headshot" /></p>'+ '<input type="submit"/>';
$('#my-form').append(innerForm);
//Change values according to your data
if(data != null){
$.each(data, function(index, val) {
$('#id').val(val._id);
$('#playername').val(val.playername);
$('#age').val(val.age);
$('#city').val(val.city);
$('#country').val(val.country);
$('#gender').val(val.gender);
$('#handedness').val(val.handedness);
$('#broom').val(val.broom);
$('#position').val(val.position);
$('#team').val(val.team);
$('#favoritecolor').val(val.favoritecolor);
$('#Headshot').val(val.headshot);
});
}
}
function submitForm(url, form){
$.post(url, form.serialize(), function(data) {
showNotification(data, $('#notification'));
});
}
function showNotification(data, target){
clearContainer(target);
target.append('<p>'+data+'</p>');
}
function clearContainer(container){
container.html('');
}
});
server.js
const _ = require('lodash');
const {ObjectID} = require('mongodb');
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
var {mongoose} = require('./db/mongoose');
var {Player} = require('./models/player');
var app = express();
const port = process.env.PORT || 3000;
app.use(express.static(__dirname+'./../public'));
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.sendFile('index.html');
});
app.post('/player', (req, res) => {
var player = new Player({
playername: req.body.playername,
age: req.body.age,
city: req.body.city,
country: req.body.country,
gender: req.body.gender,
handedness: req.body.handedness,
broom: req.body.broom,
position: req.body.position,
team: req.body.team,
favoritecolor: req.body.favoritecolor,
headshot: req.body.headshot
});
player.save().then((doc) => {
res.send(doc);
}, (e) => {
res.status(400).send(e);
});
});
app.get('/players', (req, res) => {
Player.find().then((players) => {
res.send(players);
}, (e) => {
res.status(400).send(e);
});
});
app.get('/players/:id', (req, res) => {
var id = req.params.id;
if (!ObjectID.isValid(id)) {
return res.status(404).send();
}
Player.findById(id).then((player) => {
if (player) {
res.send(player);
} else {
return res.status(404).send();
}
}).catch((e) => {
res.status(400).send();
});
});
app.delete('/players/:id/delete', (req, res) => {
var id = req.params.id;
if (!ObjectID.isValid(id)) {
return res.status(404).send();
}
Player.findByIdAndRemove(id).then((player) => {
if (player) {
res.send(player);
} else {
return res.status(404).send();
}
}).catch((e) => {
res.status(400).send();
});
});
app.patch('/players/:id/edit', (req, res) => {
var id = req.params.id;
var body = _.pick(req.body, ['playername', 'age', 'city', 'country', 'gender', 'handedness', 'broom', 'position', 'team', 'favoritecolor', 'headshot']);
if (!ObjectID.isValid(id)) {
return res.status(404).send();
}
Player.findByIdAndUpdate(id, {$set: body}, {new: true}).then((player) => {
if (!player) {
return res.status(404).send();
} else {
res.send(player);
}
}).catch((e) => {
res.status(400).send();
})
});
app.listen(port, () => {
console.log(`Started on port ${port}`);
});
module.exports = {app};