I'm learning Node.JS and as practise I need to create to endpoints:
- GET /albums - Get a list of all albums in the dabatase
- POST /purchases - Create a purchase
My attempt is as follows:
const mongoose = require('mongoose');
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
// Imports
const Album = require("./models/album");
const Purchase = require("./models/purchase");
// TODO code the API
// Connect to DB
mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});
var conn = mongoose.connection;
conn.on('connected', function() {
console.log('database is connected successfully');
});
conn.on('disconnected',function(){
console.log('database is disconnected successfully');
})
conn.on('error', console.error.bind(console, 'connection error:'));
// Routes
app.get('/albums', function(req, res, next) {
Album.find({}, (err, albums) => {
if (!err) {
res.set({
'Content-Type': 'application/json',
'Status': 200,
})
return res.end(JSON.stringify(albums));
} else {
console.log('Failed to retrieve the Course List: ' + err);
}
});
});
// POST method route
app.post('/purchases', (req, res) => {
const purchase = new Purchase({
user: req.body.user,
album: req.body.album
})
purchase.save(function (err, post) {
if (err) { return err }
res.json(201, purchase);
})
})
module.exports = app;
Instructions for GET Request:
Since this is a JSON API, return JSON and a 200 status code, with the exception of destroy method which should return a 204 status code indicating no content.
All three Album columns title, performer and cost should be returned in a data object for the GET, POST and PUT methods. Here is an example of the format of response.body.data:
Expected Form:
response.body.data = {
_id: "the id of the album",
title: "Appetite for Destruction",
performer: "Guns N' Roses",
cost: 20
};
Instructions for POST Request:
The POST /purchases route should expect user and album properties to be set in the request body. It should then store a reference to both of these records on the newly created purchase record.
The response for POST /purchases should include the purchase record as well as the user and album relations, which should be populated with all their data fields.
Album Schema:
const albumSchema = mongoose.Schema({
performer: String,
title: String,
cost: Number
});
Purchase Schema:
const purchaseSchema = mongoose.Schema({
user: {type: mongoose.Schema.Types.ObjectId, ref: "User"},
album: {type: mongoose.Schema.Types.ObjectId, ref: "Album"}
})
The program need to pass the follwing two test cases for these endpoints:
describe("GET /albums", () => {
it("should return an array of all models", async () => {
const album = new Album(albumData).save();
const res = await chai
.request(app)
.get("/albums")
;
expect(res.status).to.equal(200);
expect(res).to.be.json;
expect(res.body.data).to.be.a("array");
expect(res.body.data.length).to.equal(1);
expect(res.body.data[0].title).to.equal(albumData.title);
expect(res.body.data[0].performer).to.equal(albumData.performer);
expect(res.body.data[0].cost).to.equal(albumData.cost);
}).timeout(2000);
});
describe("POST /purchases", () => {
it("should create a new purchase and return its relations", async () => {
const otherAlbumData = {
title: "Sample",
performer: "Unknown",
cost: 2,
};
const album = await new Album(otherAlbumData).save();
const user = await new User({name: "James"}).save();
const res = await chai
.request(app)
.post("/purchases")
.send({user, album})
;
expect(res.status).to.equal(200);
expect(res).to.be.json;
expect(res.body.data).to.haveOwnProperty("user");
expect(res.body.data.user).to.haveOwnProperty("name");
expect(res.body.data).to.haveOwnProperty("album");
expect(res.body.data.album).to.haveOwnProperty("title");
expect(res.body.data.user.name).to.equal(user.name);
expect(res.body.data.album.title).to.equal(album.title);
}).timeout(2000);
});
});
The problem is that GET /albums doesn't properly fetch the data. Error: "expected undefined to be an array" while POST /purchases throws error 500, "Cannot read property 'user' of undefined" but as per description "route should expect user and album properties to be set in the request body".
Can somebody gives me a headsup? I'm fairly new to Node.JS. Thanks.