Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start #42

Open
wants to merge 18 commits into
base: start
Choose a base branch
from
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"jest.jestCommandLine": "npx jest"
}
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
> Scott Moss & Frontend Masters
- [Resources](#resources)
- [Course](#course)
- [Excercises](#excercises)
- [Exercises](#exercises)
- [Installing Node](#installing-node)
- [Modules (node vs browser)](#modules-node-vs-browser)
- [CLI (npm)](#cli-npm)
Expand All @@ -18,8 +18,10 @@
* [NPM](https://www.npmjs.com/)

## Course
This course has two parts, slides and exercises. The slides describe the exercises in detail. Each exercise has a folder
Thanks for taking the [Introduction to Node.js course](https://frontendmasters.com/courses/node-js/) -- the course has two parts: slides and exercises. The slides describe the exercises in detail. Each exercise have a folder.

## Exercises

### Installing Node
Install node with [node version manager (NVM)](https://github.com/creationix/nvm#installation). NVM was created by the community and not the Nodejs foundation. However, it is the recommended approach. After installing nvm, use nvm to install the lates version of Nodejs, which at this time is `10` and set it to the default version
```bash
Expand All @@ -35,7 +37,7 @@ Important: After installing node, please run `npm install i` or `npm install` to
* test - `npx jest`

This exercise will have you convert some JavaScript written for the browser, so that it works with node.
- [ ] check out to start branch
- [ ] checkout to start branch
- [ ] check the README on how to run test (will talk later about that command)
- [ ] fix and convert the 3 js files in the exercises/modules/browser to Nodejs JavaScript and place them in exercises/modules/node
- [ ] ensure all tests pass by running test command again
Expand Down
51 changes: 35 additions & 16 deletions exercises/api/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,56 @@ const http = require('http')
const url = require('url')
const fs = require('fs')
const path = require('path')
const mime = require('mime');

/**
* this function is blocking, fix that
* @param {String} name full file name of asset in asset folder
*/
const findAsset = (name) => {
const assetPath = path.join(__dirname, 'assets', name)
return fs.readFileSync(assetPath, {encoding: 'utf-8'}).toString()
return new Promise((resolve, reject)=>{
fs.readFile(assetPath, {encoding: 'utf-8'},(error, result) => {
if(error){
reject(error)
} else{
resolve(result)
}
})
})
}

const hostname = '127.0.0.1'
const port = 3000

const router = {
'/ GET':{
asset: 'index.html',
mime: mime.getType('html')
},
'/style.css GET':{
asset: 'style.css',
mime: mime.getType('css')
}
}

// log incoming request coming into the server. Helpful for debugging and tracking
const logRequest = (method, route, status) => console.log(method, route, status)

const server = http.createServer((req, res) => {
const server = http.createServer(async (req, res) => {
const method = req.method
const route = url.parse(req.url).pathname
// this is sloppy, especially with more assets, create a "router"
if (route === '/') {
res.writeHead(200, {'Content-Type': 'text/html'})
res.write(findAsset('index.html'))
logRequest(method, route, 200)
res.end()
} else {
// missing asset should not cause server crash
throw new Error('route not found')
// check the router for the incomming route + method pair
const routeMatch = router[`${route} ${method}`]
// return not found if the router does not have a match
if (!routeMatch) {
res.writeHead(404)
logRequest(method, route, 404)
res.end()
return
}
// most important part, send down the asset

res.writeHead(200, {'Content-Type': match.mime})
res.write(await findAsset(match.asset))
logRequest(method, route, 200)
res.end()

})

server.listen(port, hostname, () => {
Expand Down
8 changes: 1 addition & 7 deletions exercises/cli/contacts.json
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
{
"adfsadf asfdasdf": {
"firstName": "adfsadf",
"lastName": "asfdasdf",
"phoneNumber": "asfdsf"
}
}
{"adfsadf asfdasdf":{"firstName":"adfsadf","lastName":"asfdasdf","phoneNumber":"asfdsf"},"dd gg":{"firstName":"dd","lastName":"gg","phoneNumber":"33"}}
13 changes: 10 additions & 3 deletions exercises/cli/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@ const fs = require('fs')
const path = require('path')

// this path needs to be relative to work with fs
const contactsLocation = 'contacts.json'

//onst contactsLocation = 'contacts.json'

const contactsLocation = path.join(__dirname, 'contacts.json')


/**
* should read the contacts at the
* @contactsLocation path and convert
* it to a js object
*/
const getContacts = () => {

const contacts = fs.readFileSync(contactsLocation).toString()

return JSON.parse(contacts)
}

/**
Expand All @@ -19,7 +25,8 @@ const getContacts = () => {
* @param {Object} contacts contacts object
*/
const saveContacts = (contacts) => {

const stringContacts = JSON.stringify(contacts)
return fs.writeFileSync(contactsLocation, stringContacts)
}

module.exports = {
Expand Down
19 changes: 19 additions & 0 deletions exercises/modules/node/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const {users, posts} = require('./data')

const getUserById = (id, cb) => {
// simulate API call
setTimeout(() => {
const user = users.find(user => user.id === id)
cb(user)
}, 150)
}

const getPostsForUser = (userId, cb) => {
// simulate API call
setTimeout(() => {
const post = posts.filter(post => post.createdBy === userId)
cb(post)
}, 150)
}

module.exports = {getPostsForUser, getUserById}
32 changes: 32 additions & 0 deletions exercises/modules/node/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const {getPostsForUser, getUserById} = require('./api')

const app = {
showPostsForCurrentUser : (userId, cb) => {
getPostsForUser(userId, posts => {
const postTemplates = posts.map(post => {
return `
<div class="post">
${post.title}
${post.body}
${post.createdBy}
</div>`
})
cb(postTemplates)
})
},
showUserProfile : (userId, cb) => {
getUserById(userId, user => {
const profile = `
<div>
${user.name}
</div>
`
cb(user)
})
}

}

module.exports = app


18 changes: 8 additions & 10 deletions exercises/modules/node/data.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
window.App = {
users: [
{id: 1, name: 'Weezy'}
],
posts: [
{title: 'yo', body: 'I ate today', createdBy: 1},
{title: 'Me', body: 'Look at my selfie', createdBy: 1},
{title: 'My doggy', body: 'my dog is better than yours', createdBy: 1}
]
}
const users = [{ id: 1, name: 'Weezy' }]

const posts = [
{ title: 'yo', body: 'I ate today', createdBy: 1 },
{ title: 'Me', body: 'Look at my selfie', createdBy: 1 },
{ title: 'My doggy', body: 'my dog is better than yours', createdBy: 1 }
]
module.exports = {users, posts}
6 changes: 3 additions & 3 deletions exercises/testing/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ app.use(urlencoded({extended: true}))
app.use(json())

app.get('/user/:id', async (req, res) => {
const id = req.id
const id = req.params.id
// should ge user by given id in route param
const user = await users.findUser(user => user.id === id)
const user = await users.findUser(id)
res.status(200).send(user)
})

app.delete('/user/:id', async (req, res) => {
const id = req.id
const id = req.params.id
await users.deleteUser(id)
res.status(201).send({id})
})
Expand Down
5 changes: 4 additions & 1 deletion exercises/testing/test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// write some tests
const {fixId} = require('./users')
describe('users', () => {

test('fixId', () => {
expect(fixId('200')).toBe(200)
})
})
20 changes: 13 additions & 7 deletions exercises/testing/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,35 @@ const users = new Array(20).fill(0)
}
})

const fixId = id => parseInt(id)

// simulate async db call with promise
const findUser = (id) => new Promise((resolve, reject) => {
const user = users.find(user => user.id === id)
const _id = fixId(id)
const user = users.find(user => user.id === _id)

console.log(user);
if (user) {
return resolve(user)
}
reject(new Error(`No user with id "${id}"`))
reject(new Error(`No user with id "${_id}"`))
})

// simulate async db call with promise
const deleteUser = (id) => new Promise((resolve, reject) => {
const id = fixId(id)
const i = users.findIndex(user => user.id === id)
const _id = fixId(id)
const i = users.findIndex(user => user.id === _id)

if (i < 0) {
return reject(new Error(`No user with id "${id}"`))
return reject(new Error(`No user with id "${_id}"`))
}

users.slice(i, 1)
resolve({id})
resolve({_id})
})

module.exports = {
findUser,
deleteUser
deleteUser,
fixId
}
Loading