Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions database/DashboardSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const schemas = require('mongoose')
const WidgetSchema = require('./WidgetSchema')

const DashboardSchema = schemas.Schema ({
_user: {type: Number, ref: 'User'},
widgets: [{type:schemas.Schema.Types.ObjectId, ref:'Widget'}]
})

const Dashboard = schemas.model('Dashboard', DashboardSchema)

module.exports = { DashboardSchema }
15 changes: 15 additions & 0 deletions database/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const schemas = require('mongoose')
schemas.connect('mongodb://localhost/lizardboard')
const db= schemas.connection
const UserSchema = require('./UserSchema')
db.on('error', console.error.bind(console,'connection error:'))
db.once('open', function() {
console.log('connected')
})

const User = schemas.model('User', UserSchema)

module.exports = {
db,
User
}
9 changes: 9 additions & 0 deletions database/UserSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const schemas = require('mongoose')
const DashboardSchema = require('./DashboardSchema')

const UserSchema = schemas.Schema ({
username: String,
dashboards: [{type: schemas.Schema.Types.ObjectId, ref:'Dashboard'}]
})

module.exports = { UserSchema }
13 changes: 13 additions & 0 deletions database/WidgetSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const schemas = require('mongoose')

const WidgetSchema = schemas.Schema ({
_dashboard:{ type:Number, ref:'Dashboard' },
type: String,
title: String,
size: String,
contents: String
})

const Widget = schemas.model( 'Widget', WidgetSchema )

module.exports = { WidgetSchema }
104 changes: 102 additions & 2 deletions routes/users.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,109 @@
const express = require('express');
const { User, db } = require('../database/User.js')
const router = express.Router();
const mongoose = require('mongoose')


/* GET users listing. */
router.get('/', (request, response, next) => {
response.send('respond with a resource');
router.get('/', ( request, response, next ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of this route?

response.send( 'respond with a resource' );
});

router.post('/', ( request, response, next ) => {
const { username } = request.body
const newUser = new User({
username: username,
dashboards: {
widgets: {}
}
})

newUser.save( (error) => {
if(error) return handleError(err)
})

})

/* GET widget */
router.get('/widgets/:widgetId', ( request, response, next ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would name this parameter :id - the URL makes it explicit that this is a widget's id.

const { widgetId } = request.params

User.find( {'widgets._id': widgetId},function(error, widgets){
return widgets
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use two spaces for indentation.

})
.then( data => console.log('finished') )
});

/* CREATE widgets */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment

router.post('/:userId/widgets/create', (request, response, next ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will follow a RESTful approach to API endpoints:

GET /resourceNamePlural - get all entries
POST /resourceNamePlural { data } - create a new entry
GET /resourceNamePlural/:id - get single entry
PUT /resourceNamePlural/:id { data } - update entry (technically, replace, but update is fine)
DELETE /resourceNamePlural/:id - delete entry

Please update endpoints to reflect this approach

const { userId } = request.params
const { type, title, size, contents } = request.body

const newWidget = {
type: type,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use implicit object creation:

const widget = { type, title, size, contents }

I also prefer a name like widget over newWidget - the newness should be apparent from the context in which this is executing. Having said that, I think a better name might be something like widgetAttributes or just attributes.

title: title,
size: size,
contents: contents
}

User.findOneAndUpdate(
{ _id: userId },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the userId the information used to uniquely identify a widget? The relationship is a little more complicated, as Users may have one or many Dashboards, which will have none to many Widgets.

{
$push: {
widgets: newWidget
}
},
{ upsert: true },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not use upsert - it results in the possibility of confusing bugs, and mixes behaviors - we should either knowingly create something, or knowingly update something, never update or create if it didn't exists.

function( error ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ES6 functions, please.

if( error ) console.log( error )
}
)
})

/* UPDATE widgets */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment

router.post('/:userId/widgets/:widgetId/update', ( request, response, next ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See note above about RESTful endpoints, removing upsert, etc.

const { userId, widgetId } = request.params
const { type, title, size, contents } = request.body

const updatedWidget = {
_id: widgetId,
type: type,
title: title,
size: size,
contents: contents
}

User.findOneAndUpdate(
{ _id: userId, widgets: { $elemMatch:{ _id: widgetId }}},
{
$set: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't mongoose provide a much better API for updating than $set? If not, we're going to throw it out...

'widgets.$': updatedWidget
}
},
{ upsert: true },
function( error ) {
if( error ) console.log( error )
}
)
})


/* DELETE widgets */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment and extraneous whitespace.

router.post( '/:userId/widgets/:widgetId/delete', ( request, response, next ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See notes above re: REST, mongoose API, ES6.

const { userId, widgetId } = request.params

User.findOneAndUpdate(
{ _id: userId },
{
$pull: {
widgets: { _id: widgetId }
}
},
{'new': true},
function( error, data ){
if( error ) console.log( error )
}
)
})

module.exports = router;