0% found this document useful (0 votes)
42 views19 pages

Tutorial - Getting Started With Node

This tutorial will show how to set up a basic full stack web application with Node.js, Express, Jade, and MongoDB in under an hour. It begins with installing Node.js, the Express generator, and necessary dependencies. The Express generator is used to scaffold an application, and the dependencies MongoDB and Monk are added to allow communication with the database. Finally, the dependencies are installed so the application is fully configured and ready to run.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
42 views19 pages

Tutorial - Getting Started With Node

This tutorial will show how to set up a basic full stack web application with Node.js, Express, Jade, and MongoDB in under an hour. It begins with installing Node.js, the Express generator, and necessary dependencies. The Express generator is used to scaffold an application, and the dependencies MongoDB and Monk are added to allow communication with the database. Finally, the dependencies are installed so the application is fully configured and ready to run.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

THEDEADSIMPLESTEPBYSTEPGUIDEFORFRONT

ENDDEVELOPERSTOGETTINGUPANDRUNNING
WITHNODE.JS,EXPRESS,JADE,ANDMONGODB
SETUPTHEFULLSTACKANDHAVEAWEBPAGERUNNINGIN30
MINUTES.MAKEITTALKTOYOURDBINANOTHER30.
ByChristopherBuecheler
LASTUPDATED:September2nd,2015
ThistutorialusesNode.jsv0.12andwillnotworkproperlywitholderversionsonsomesystems.

Youcanfind/forktheentiresampleprojectonGitHub
Hey!ThisandallmyothertutorialswillsoonbemovingtoanewhomeatCloseBrace,asitefor
JavaScriptdevelopers.Youshouldtotallyclickthatlinkrightnow,andsignuptobealertedwhenthe
sitegoeslive.

INTRODUCTION
Thereareapproximatelyonehundredmilliontutorialsonthewebforgettinga"Hello,World!"app
runningwithNode.js.Thisisgreat!It'sespeciallygreatifyourgoalistogreettheworldandthengive
uponyourwebcareerandgospendtherestofyourlifeas,like,ajockeyorsomething.Thatdoesn't
reallydescribemostofus,sowegolookingformoretutorials.
Inmyexperience,the"nextlevel"tutorialsoutthereseemabout30levelsfurtheralong.Wegofrom
"Hello,World!"tobuildingoutanentirebloggingsystemwithcomments.Whichisalsogreat,butalot
oftimesthosetutorialsassumethereaderhasdoneawholebunchofintermediatefiddling,andthey
oftendropabunchofbigfunctionsonyouallatonce.Itendtolearnbestbymakinglotsofsmaller,
intermediatesteps,andIdon'tthinkI'mtheonlyone.
I'mnottheonlyone,right?
Well,goodnews,everyone!I'vedonethefiddlingandreadabunchoftutorialsandshoutedatmy
commandpromptuntilthingsfinallyworked.IhaveawebprojectupandrunningwhichusesNode.JS,
theExpressframework,theJadeHTMLpreprocessor,andMongoDBfordata.Icanreadtoandwrite
fromtheDB.Fromthere,thesky'sthelimit.
Here'sthedeal:I'mgoingtoshowyouhowtogetallofthisstuffsetup.I'llbeassumingthatyou'rea
frontenddeveloperwhoknowsHTML5/CSS3/JavaScriptwellenoughthatIdon'thavetoexplainthose.
Ifthat'syou,thenthisshouldbeasolidprimer.
Yourappwilllookpretty,itwillconnecttoaDB,it'llgetsomeresults,andit'lldostuffwiththose
results.Thenforkickswe'llalsomakeitsavedatatotheDB.Throughitall,Iwillexplainwhatthecode

eveninstalled,toaDBdrivenwebappwritteninalanguageyoufullyunderstand,andthefoundation
necessarytobuildadditionalfunctionalityintoyourapp.Andwe'lldoitinabout60minutesof
installationandcodingtime.Isthatawesome?Isubmitthatitis.
Let'sgo.

PARTI15MINUTESOFINSTALLING
Ifyou'rereallystartingfromscratch,thengettingeverythingupandrunningtakesalittlebitoftime.
Noneofitisdifficult.IrunWindows8onmymainmachine,soit'llbeslightlydifferentforthoseona
MacorUbuntuorother*nixsystem,butit'sprincipallythesamethinginallcases.
STEP1INSTALLNODE.JS
Thisisreallyeasy.HittheNode.jswebsiteandclickthebiggreenInstallbutton.It'lldetectyourOSand
giveyoutheappropriateinstaller(ifforsomereasonitdoesn't,clickthedownloadsbuttonandgrabthe
oneyouneed).Runtheinstaller.That'sit,youhaveinstalledNode.jsand,equallyimportant,NPM
NodePackageManagerwhichletsyouaddallkindsofgreatstufftoNodequicklyandeasily.
Openacommandprompt
cdtothedirectoryinwhichyouwishtokeepyourtestapps
(forthepurposesofthistutorial,C:\node).
STEP2INSTALLEXPRESSGENERATOR
NowthatwehaveNoderunning,weneedtherestofthestuffwe'regoingtoactuallyusetocreatea
workingwebsite.Todothatwe'regoingtoinstallExpress,whichisaframeworkthattakesNodefroma
barebonesapplicationandturnsitintosomethingthatbehavesmorelikethewebserverswe'reallused
toworkingwith(andactuallyquiteabitmorethanthat).WeneedtostartwithExpressGenerator,
whichisactuallydifferentthanExpressitself...it'sascaffoldingappthatcreatesaskeletonforexpress
drivensites.Inyourcommandprompt,typethefollowing:
COMMANDC:\NODE>
C:\node>npminstallgexpressgenerator

Thegeneratorshouldautoinstall,andsinceit(likeallpackagesinstalledwithg)livesinyourmaster
NPMinstallationdirectory,itshouldalreadybeavailableinyoursystempath.Solet'suseourgenerator
tocreatethescaffoldingforawebsite.
STEP3CREATEANEXPRESSPROJECT
We'regoingtouseExpressandJade,butnottheStylusCSSpreprocessor(whichpeopleoftenusein
thisstack).We'rejustgoingtousestraightCSSforrightnow.WehavetouseJadeoranother
templatingenginetogainaccesstoourNode/Expressbaseddata.Jade'snothardtolearnifyou
alreadyknowHTML,justrememberthatyoureallyhavetopayattentiontoindentationorthingswillgo
badlywrong.IfyouwantatemplatingenginewithtrueHTMLsyntax,youcoulduseEJSinstead(note:
IcannotprovidesupportforthistutorialifyouchoosetouseanythingotherthanJade).
Aquicknoteonindentation:everythingisthistutorialhasbeennormalizedto4spacetabs,evencode

thatwasautogeneratedwith2spacetabs.Ifyouwanttousetwoorthreespaces,oractualtabs
(whichisusuallymypreference),that'sjustfinebyme.But,again,YOURINDENTATIONMUSTBE
CONSISTENTorJadewillthrowerrors.Notjust"alltabs"or"allspaces"butyoumustbevery,very
carefultomakesurethateverythingisindentedtheexactrightamount.Forexample,inJade,the
following:
body
h1
ul
li

...isVERYdifferentfrom:
body
h1
ul
li

(thatsecondpieceofcodewouldnesttheULinsideoftheH1...whichyouobviouslydon'twant).
Anyway,stillinc:\nodeorwhereveryou'restoringyournodeapps,typethis:
COMMANDC:\NODE\
C:\node>expressnodetest1

Hitenterandwatchitgo.You'llseesomethinglikethis:
COMMANDC:\NODE\
C:\node>expressnodetest1
create:nodetest1
create:nodetest1/package.json
create:nodetest1/app.js
create:nodetest1/public
create:nodetest1/public/javascripts
create:nodetest1/public/images
create:nodetest1/public/stylesheets
create:nodetest1/public/stylesheets/style.css
create:nodetest1/routes
create:nodetest1/routes/index.js
create:nodetest1/routes/users.js
create:nodetest1/views
create:nodetest1/views/index.jade
create:nodetest1/views/layout.jade
create:nodetest1/views/error.jade
create:nodetest1/bin
create:nodetest1/bin/www
installdependencies:
>cdnodetest1&&npminstall
runtheapp:
>SETDEBUG=nodetest1b:*&npmstart

STEP4EDITDEPENDENCIES
OK,nowwehavesomebasicstructureinthere,butwe'renotquitedone.You'llnotethattheexpress
generatorroutinecreatedafilecalledpackage.jsoninyournodetest1directory.Openthisupinatext

editorandit'lllooklikethis:
C:\NODE\NODETEST1\PACKAGE.JSON
{
"name":"nodetest1",
"version":"0.0.0",
"private":true,
"scripts":{
"start":"node./bin/www"
},
"dependencies":{
"bodyparser":"~1.12.4",
"cookieparser":"~1.3.5",
"debug":"~2.2.0",
"express":"~4.12.4",
"jade":"~1.9.2",
"morgan":"~1.5.3",
"servefavicon":"~2.2.1"
}
}

ThisisabasicJSONfiledescribingourappanditsdependencies.Weneedtoaddafewthingstoit.
Specifically,callsforMongoDBandMonk.Let'smakeourdependenciesobjectlooklikethis:
"dependencies":{
"bodyparser":"~1.12.4",
"cookieparser":"~1.3.5",
"debug":"~2.2.0",
"express":"~4.12.4",
"jade":"~1.9.2",
"morgan":"~1.5.3",
"servefavicon":"~2.2.1",
"mongodb":"^1.4.4",
"monk":"^1.0.1"
}

Notethatcommaattheendoftheservfaviconline.Omitit,andyouwon'tbeabletoinstall!

ImportantNote:thistutorialisabitoutofdateatthemoment.Itisessentialthatyouuse
thisolderversionofthemongodbmodule(1.4.4)ormonkwillnotworkandyourappwill
break.IwillbedoingafullupdateassoonasIcan,butthisshouldkeepyourunningfornow.

STEP5INSTALLDEPENDENCIES
Nowwe'vedefinedourdependenciesandwe'rereadytogo.Notethattheversionnumbersforthose
twomodulesarecurrentasofthelatestupdate,butnewversionsofNPMmodulesarefrequentlyrolled
out.Theseversionsareproventoworkwiththistutorialifyougowiththelatestversions,I'mafraid
you'reonyourown.
Returntoyourcommandprompt,cdtoyournodetest1directory,andtypethis:
COMMANDC:\NODE\NODETEST1\
C:\node\nodetest1>npminstall

It'sgoingtoprintoutatonofstuff.That'sbecauseit'sreadingtheJSONfilewejusteditedand
installingallthestufflistedinthedependenciesobject(yes,includingExpressweinstalledthe
generatorglobally,butwestillhavetoinstalltheactualmoduleinsidethisoneparticularproject).Once
NPMhasrunitscourse,youshouldhaveanode_modulesdirectorywhichcontainsallofour
dependenciesforthistutorial.
Younowhaveafullyfunctioningappreadyandwaitingtorun.Beforewedothat,though,weneedto
doonequickthingtoprepareforsettingupourdatabaselater.Stillinyournodetest1directory,type
this:
COMMANDC:\NODE\NODETEST1\
C:\node\nodetest1>mkdirdata

That'swherewe'reeventuallygoingtostoreourMongoDBdata.Ifthatdirectorydoesn'texist,the
databaseserverwillchokewhenwegotorunitlater.We'renotdoinganythingwithitrightnow,
though,solet'stestoutourwebserver!Typethefollowing:
COMMANDC:\NODE\NODTEST1\
C:\node\nodetest1>npmstart

Note:inpreviousversions,youused"nodeapp.js"thishasbeendeprecatedinfavorofaskeletal
buildsystem.Forthepurposesofthistutorial,thatdoesn'treallymatter,sincewe'renotworyingabout
building.Forourpurposes,using"npmstart"isessentiallyidenticaltopreviousversionsofthistutorial.
Anyway,typethatandhitenter.You'llgetthis:
NODECONSOLE
>applicationname@0.0.1startD:\sites\node\nodetest1
>node./bin/www

Everythingworking?Awesome!Openabrowserandheadforhttp://localhost:3000whereyouwill
seeawelcometoExpresspage.

YouarenowrunningyourownNodeJSwebserver,withtheExpressengineandJadeHTML
preprocessorinstalled.Notsotough,huh?

PART2OK,FINE,LET'SDO"HELLO,WORLD!"

FireupyourfavoritetexteditororIDE.IlikeSublimeTextalot.Pointitatyournodetest1directoryand
openapp.js.Thisiskindoftheheartofyour,well,app.Notabigsurprisethere.Here'sabreakdownof
whatyou'regoingtosee:
C:\NODE\NODETEST1\APP.JS
varexpress=require('express');
varpath=require('path');
varfavicon=require('servefavicon');
varlogger=require('morgan');
varcookieParser=require('cookieparser');
varbodyParser=require('bodyparser');
varroutes=require('./routes/index');
varusers=require('./routes/users');

ThiscreatesabunchofbasicJavaScriptvariablesandtiesthemtocertainpackages,dependencies,
nodefunctionality,androutes.Routesarekindoflikeacombinationofmodelsandcontrollersinthis
setuptheydirecttrafficandalsocontainsomeprogramminglogic(youcanestablishamoretraditional
MVCarchitecturewithExpressifyoulike.That'soutsideofthescopeofthisarticle).Backwhenweset
upthisproject,Expresscreatedallofthisstuffforus.We'regoingtototallyignoretheuserroutefor
nowandjustworkinthetoplevelroute(controlledbyc:\node\nodetest1\routes\index.js).
C:\NODE\NODETEST1\APP.JS
varapp=express();

Thisone'simportant.ItinstantiatesExpressandassignsourappvariabletoit.Thenextsectionuses
thisvariabletoconfigureabunchofExpressstuff.
C:\NODE\NODETEST1\APP.JS
//viewenginesetup
app.set('views',path.join(__dirname,'views'));
app.set('viewengine','jade');
//uncommentafterplacingyourfaviconin/public
//app.use(favicon(__dirname+'/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname,'public')));
app.use('/',routes);
app.use('/users',users);

Thistellstheappwheretofinditsviews,whatenginetousetorenderthoseviews(Jade),andcallsa
fewmethodstogetthingsupandrunning.NotealsothatthefinallineistellingExpresstoservestatic
objectsfromthe/public/dir,buttomakethemactuallyseemlikethey'recomingfromthetoplevel(it
alsodoesthiswiththeviewsdirectory).Forexample,theimagesdirectoryis
c:\node\nodetest1\public\imagesbutitisaccessedathttp://localhost:3000/images
C:\NODE\NODETEST1\APP.JS
///catch404andforwardingtoerrorhandler
app.use(function(req,res,next){

next(err);
});
///errorhandlers
//developmenterrorhandler
//willprintstacktrace
if(app.get('env')==='development'){
app.use(function(err,req,res,next){
res.status(err.status||500);
res.render('error',{
message:err.message,
error:err
});
});
}
//productionerrorhandler
//nostacktracesleakedtouser
app.use(function(err,req,res,next){
res.status(err.status||500);
res.render('error',{
message:err.message,
error:{}
});
});

Theseareerrorhandlersfordevelopmentandproduction(and404's).We'renotreallyworryingabout
thedifferentbetweenthosetworightnow,butbasicallyifyourappisindevelopmentmode,yourerrors
willgiveyoumoreinformation.Obviouslyyoudon'twanttoprintastacktraceoutonaproductionsite
thatanyoneonthewebcansee.
C:\NODE\NODETEST1\APP.JS
module.exports=app;

AcorepartofNodeisthatbasicallyallmodulesexportanobjectwhichcaneasilybecalledelsewherein
thecode.Ourmasterappexportsitsappobject.
Nowthen,let'smakestuff.We'renotgoingtojuststick"Hello,World!"onourindexpage.Instead
we'regoingtousethisasanopportunitytolearnabitmoreaboutroutesandtotakealookathow
Jadeworksforputtingpagestogether.
We'regoingtostartbyaddinganewapp.usedirectivetoapp.js.Findthesectionthatlookslikethis:
C:\NODE\NODETEST1\APP.JS
app.use('/',routes);
app.use('/users',users);

ThisdirectivesaretellingExpresswhatroutefilestouse.Now,normallyI'dadvocatesettingup
separateroutefilesfordifferentpartsofyourapp.Forexample,theusersroutefilemightcontain
routesforaddingusers,deletingthem,updatingthem,andsoforth,whileanewroutefilecalled
"locations"mighthandleadding,editing,deletinganddisplayinglocationdata(inanappforwhichthat
wasrequired).Inthiscase,tokeepthingssimple,we'regoingtodoeverythingintheindexrouter.That
meansyoucancompletelyignorethe/usersline.
RememberthattheExpressscaffoldingalreadydefinedthe"routes"variableandpointeditattheindex

thedefault.Inyourtexteditor,openupyourroutesfolder,findindex.js,andopenit.Itwilllooklike
this:
C:\NODE\NODETEST1\ROUTES\INDEX.JS
varexpress=require('express');
varrouter=express.Router();
/*GEThomepage.*/
router.get('/',function(req,res){
res.render('index',{title:'Express'});
});
module.exports=router;

Prettysparse,right?Basicallywe'rerequiringourExpressfunctionality,thenattachinga"router"
variabletoExpress'sroutermethod,thenusingthatmethodwhenanattemptismadetoHTTPgetthe
topleveldirectoryofourwebsite.Finallyweexportourrouterfunctionbacktoourapp.
Wecaneasilyclonethatgetfunctionforanotherpage,solet'sdothat.Atthebottomofthefile,
justabovethemodule.exportsline,addthiscode:
C:\NODE\NODETEST1\ROUTES\INDEX.JS
/*GETHelloWorldpage.*/
router.get('/helloworld',function(req,res){
res.render('helloworld',{title:'Hello,World!'});
});

That'sallittakestohandleroutingtheURI,butwedon'thaveanyactualpageforres.renderto
render.That'swhereJadecomesin.Openupyourviewsfolder,andthengoaheadandopen
index.jade.Beforeyoudoanythingelse,saveitashelloworld.jade.
Nowtakealookatthecode:
C:\NODE\NODETEST1\VIEWS\HELLOWORLD.JADE
extendslayout
blockcontent
h1=title
pWelcometo#{title}

Thisisprettystraightforward.Ituses("extends")thefilelayout.jadeasatemplate,andthenwithinthe
contentblockdefinedinthelayoutfile,itsticksaheaderandaparagraph.Notetheuseofthe"title"
variablewhichwesetabove,inourindex.jsroute.Thismeanswedon'tevenhavetochangethetextat
allinorderforittoshowdifferentstufffromthehomepage.Butlet'schangeitanywayto:
pHello,World!Welcometo#{title}

Savethefile,gotoyourcommandprompt,ctrlctokillyourserverifit'salreadyrunning,andthentype:
COMMANDC:\NODE\NODETEST1\

Inordertorestarttheserver.Bytheway,thisseemsagoodtimetomention:changestoJade
templatesdonotrequireaserverrestart,butbasicallywheneveryouchangeajsfile,suchasapp.jsor
theroutefiles,you'llneedtorestarttoseechanges.
SOwiththeserverrestarted,navigatetohttp://localhost:3000/helloworldandenjoythecompletely
asininetextthatgetsdisplayed:

OK!Sonowwe'vegotourrouterroutingustoourview,whichweareviewing.Let'sdosomemodeling.
I'llgiveyouamomentifyouneedtofixyourhairormakeup.

PART3CREATEOURDBANDREADSTUFFFROMIT
STEP1INSTALLMONGODB
We'releavingourtexteditorforabitandgoingbacktoourcommandprompt.Well,firstwe'regoingto
ourwebbrowser,pointingittohttp://mongodb.org/anddownloadingMongo.Clickthedownloadslink
inthemainmenuandsnagtheproductionreleasethatfitsyoursystem.ForWindows8ona64bit
processor,wewant"64bit*2008R2+".ThiswillgiveyouanMSIfilethatwillrunthroughastandard
Windowsinstall.ItwilldefaulttoinstallingintoyourProgramFilesdirectory(ina\server\3.0\subfolder),
whichisfine.Forthepurposesofthistutorial,though,I'mgoingtoinstallintoC:\Mongo.Itdoesn't
reallymatterMongoitselfisquitesmall,andwe'llbestoringourdatabaseinournodetest1directory.
Anyway,copythefilesinthebinfolderwithinyourtempdirectorytowhereveryouwantMongotolive,
andyou'redone.You'veinstalledMongo.Nowlet'smakeitdostuff.
STEP2RUNMONGODANDMONGO
Inyournodetest1directory,createasubdircalled"data".Thennavigatetothedirectoryinwhichyou
placedyourMongoDBfiles(let'ssayC:\mongofornow),andthenintothe"bin"directory.Fromthat
directory,typethefollowing:
COMMANDC:\MONGO\BIN\
mongoddbpathc:\node\nodetest1\data\

You'llseetheMongoserverstartup.Thisisgoingtotakeawhileifit'sthefirsttime,becauseithasto
dosomepreallocatingofspaceandafewotherhousekeepingtasks.Onceitsays"[initandlisten]waiting
forconnectionsonport27017",you'regood.There'snothingmoretodoheretheserverisrunning.
Nowyouneedtoopenasecondcommandprompt.NavigateagaintoyourMongoinstallation

directory,andtype:
COMMANDC:\MONGO\BIN\
mongo

You'llseesomethinglikethefollowing:
MONGOCONSOLE
c:\mongo\bin>mongo
MongoDBshellversion:2.4.5
connectingto:test

Additionally,ifyou'repayingattentiontoyourmongodinstance,you'llseeitmentionthataconnection
hasbeenestablished.Allright,you'vegotMongoDBupandrunning,andyou'veconnectedtoitwiththe
client.We'llusethisclienttomanuallyworkonourdatabase,forabit,butit'snotnecessaryforrunning
thewebsite.Onlytheserverdaemon(mongod)isneededforthat.
STEP3CREATEADATABASE
Don'tworryabout"connectingto:test"that'sjustthedefaultdatabaseMongodecidestouseifyou
don'tspecifyoneonthecommandline,whichwedidn'tbecauseit'snotimportantrightnow.Itdoesn't
actuallyevencreatethe"test"databaseunlessyouaddarecord.It'dbetotallyfinetojustworkinthat
databaseforrightnow,butlet'smakeoneofourown.InyourMongoconsole,typethefollowing:
MONGOCONSOLE
usenodetest1

Nowwe'reusingthedatabase"nodetest1."Likewith"test",nothingactuallyexistsyet.Tomakethe
databaseexist,wehavetoaddsomedata.We'regoingtostartoffbydoingthatrightinsideofthe
Mongoclient.
STEP4ADDSOMEDATA
MyfavoritethingaboutMongoDBisthatitusesJSONforitsstructure,whichmeansitwasinstantly
familiarforme.Ifyou'renotfamiliarwithJSON,you'llneedtodosomereading,asI'mafraidthat's
outsidethescopeofthistutorial.
Let'saddarecordtoourcollection.Forthepurposesofthistutorial,we'rejustgoingtohaveasimple
databaseofusernamesandemailaddresses.Ourdataformatwillthuslooklikethis:
MONGOCONSOLE
{
"_id":1234,
"username":"cwbuecheler",
"email":"cwbuecheler@nospam.com"
}

Youcancreateyourown_idassignmentifyoureallywant,butIfindit'sbesttoletMongojustdoits

howitworks.InyourMongoclient,typethis:
MONGOCONSOLE
db.usercollection.insert({"username":"testuser1","email":"testuser1@testdomain.com"})

Somethingimportanttonotehere:that"db"standsforourdatabase,whichasmentionedabovewe've
definedas"nodetest1".The"usercollection"partisourcollection.Notethattherewasn'tastepwhere
wecreatedthe"usercollection"collection.That'sbecausethefirsttimeweaddtoit,it'sgoingtobe
autocreated.Handy.OK,Hitenter.Assumingeverythingwentright,youshouldseenothing.That's
notveryexciting,sotypethis:
MONGOCONSOLE
db.usercollection.find().pretty()

Incaseyou'recurious,the.pretty()methodgivesuslinebreaks.Itwillreturn:
MONGOCONSOLE
{
"_id":ObjectId("5202b481d2184d390cbf6eca"),
"username":"testuser1",
"email":"testuser1@testdomain.com"
}

Except,ofcourse,yourObjectIDwillbedifferent,sinceasmentioned,Mongoisautomatically
generatingthose.That'sallthereistowritingtoMongoDBfromtheclientapp,andifyou'veever
workedwithJSONservicesbefore,youareprobablygoing"oh,wow,that'sgoingtobeeasyto
implementontheweb."you'reright!
AquicknoteonDBstructure:obviouslyinthelongrunyou'reunlikelytobestoringeverythingatthe
toplevel.ThereareatonofresourcesontheinternetforschemadesigninMongoDB.Googleisyour
friend!
Nowthatwe'vegotonerecord,let'saddaacouplemore.InyourMongoconsole,typethefollowing:
MONGOCONSOLE

newstuff=[{"username":"testuser2","email":"testuser2@testdomain.com"},{"username":"testuser3","em
db.usercollection.insert(newstuff);

Notethat,yes,wecanpassanarraywithmultipleobjectstoourcollection.Handy!Anotheruseof
db.usercollection.find().pretty()willshowallthreerecords:
MONGOCONSOLE
{
"_id":ObjectId("5202b481d2184d390cbf6eca"),
"username":"testuser1",
"email":"testuser1@testdomain.com"

"_id":ObjectId("5202b49ad2184d390cbf6ecb"),
"username":"testuser2",
"email":"testuser2@testdomain.com"
}
{
"_id":ObjectId("5202b49ad2184d390cbf6ecc"),
"username":"testuser3",
"email":"testuser3@testdomain.com"
}

Nowwe'regoingtostartactuallyinteractingwiththewebserverandsitethatwesetupearlier.
STEP5HOOKMONGOUPTONODE
Thisiswheretherubbermeetstheroad.Let'sstartbybuildingapagethatjustspitsoutourDBentries
inamildlyprettyform.Here'stheHTMLwe'reshootingtogenerate:
<ul>
<li><ahref="mailto:testuser1@testdomain.com">testuser1</a></li>
<li><ahref="mailto:testuser2@testdomain.com">testuser2</a></li>
<li><ahref="mailto:testuser3@testdomain.com">testuser3</a></li>
</ul>

Iknowthisisn'trocketscience,butthat'sthepoint.We'rejustdoingasimpleDBreadandwriteinthis
tutorial,nottryingtobuildawholewebsite.Firstthingsfirst,weneedtoaddafewlinestoourmain
app.jsfiletheheartandsoulofourappinordertoactuallyconnecttoourMongoDBinstance.Open
C:\node\nodetest1\app.jsandatthetopyou'llsee:
C:\NODE\NODETEST1\APP.JS
varexpress=require('express');
varpath=require('path');
varfavicon=require('servefavicon');
varlogger=require('morgan');
varcookieParser=require('cookieparser');
varbodyParser=require('bodyparser');

Nowaddthesethreelines:
C:\NODE\NODETEST1\APP.JS
varexpress=require('express');
varpath=require('path');
varfavicon=require('servefavicon');
varlogger=require('morgan');
varcookieParser=require('cookieparser');
varbodyParser=require('bodyparser');
//NewCode
varmongo=require('mongodb');
varmonk=require('monk');
vardb=monk('localhost:27017/nodetest1');

TheselinestellourappwewanttotalktoMongoDB,we'regoingtouseMonktodoit,andour
databaseislocatedatlocalhost:27017/nodetest1.Notethat27017isthedefaultportyourMongoDB
instanceshouldberunningon.Ifforsomereasonyou'vechangedit,obviouslyusethatportinstead.
Nowlookatthebottomofthefile,whereyouhavethis:

app.use('/',routes);
app.use('/users',users);

Weneedtodosomeworkhere.Thoseapp.usestatements(alongwiththeothersyou'llfindinapp.js)
areestablishingmiddlewareforExpress.Theshort,simpleexplanationis:they'reprovidingcustom
functionsthattherestofyourappcanmakeuseof.It'sprettystraightforward,butduetochainingit
needstocomebeforeourroutedefinitions,sothattheycanmakeuseofit.
Abovethetwolinesjustmentioned,addthefollowing:
C:\NODE\NODETEST1\APP.JS
//Makeourdbaccessibletoourrouter
app.use(function(req,res,next){
req.db=db;
next();
});

NOTE:Ifyoudon'tputthisabovetheroutingstuffmentionedabove(app.use('/',routes)),
yourappWILLNOTWORK.
Wealreadydefined"db"whenweaddedMongoandMonktoapp.js.It'sourMonkconnectionobject.By
addingthisfunctiontoapp.use,we'readdingthatobjecttoeveryHTTPrequest(ie:"req")ourapp
makes.Note:thisisprobablysuboptimalforperformancebut,again,we'regoingquickndirtyhere.
So,again,thatcodeneedstogoaboveourroutingcode.Yourentireapp.jsshouldlooklikethis,now:
C:\NODE\NODETEST1\APP.JS
varexpress=require('express');
varpath=require('path');
varfavicon=require('servefavicon');
varlogger=require('morgan');
varcookieParser=require('cookieparser');
varbodyParser=require('bodyparser');
//NewCode
varmongo=require('mongodb');
varmonk=require('monk');
vardb=monk('localhost:27017/nodetest1');
varroutes=require('./routes/index');
varusers=require('./routes/users');
varapp=express();
//viewenginesetup
app.set('views',path.join(__dirname,'views'));
app.set('viewengine','jade');
//uncommentafterplacingyourfaviconin/public
//app.use(favicon(__dirname+'/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname,'public')));
//Makeourdbaccessibletoourrouter
app.use(function(req,res,next){
req.db=db;
next();

app.use('/',routes);
app.use('/users',users);
///catch404andforwardingtoerrorhandler
app.use(function(req,res,next){
varerr=newError('NotFound');
err.status=404;
next(err);
});
///errorhandlers
//developmenterrorhandler
//willprintstacktrace
if(app.get('env')==='development'){
app.use(function(err,req,res,next){
res.status(err.status||500);
res.render('error',{
message:err.message,
error:err
});
});
}
//productionerrorhandler
//nostacktracesleakedtouser
app.use(function(err,req,res,next){
res.status(err.status||500);
res.render('error',{
message:err.message,
error:{}
});
});
module.exports=app;

Nextthingweneedtodoismodifyourroutesothatwecanactuallyshowdatathat'sheldinour
database,usingourdbobject.
STEP6PULLYOURDATAFROMMONGOANDDISPLAYIT
OpenupC:\node\nodetest1\routes\index.jsinyoureditor.It'sstillgottheindexroute,andthegoofy
/helloworldroute.Let'saddathird:
C:\NODE\NODETEST1\ROUTES\INDEX.JS
/*GETUserlistpage.*/
router.get('/userlist',function(req,res){
vardb=req.db;
varcollection=db.get('usercollection');
collection.find({},{},function(e,docs){
res.render('userlist',{
"userlist":docs
});
});
});

OKthat'sgettingfairlycomplicated.Allit'sreallydoing,though,isextractingthe"db"objectwe
passedtoourhttprequest,andthenusingthatdbconnectiontofillour"docs"variablewithdatabase
documents,ie:userdata.Thenwedoapagerenderjustliketheothertwo"gets"inthisroutefile.
Basically,wetellourappwhichcollectionwewanttouse('usercollection')anddoafind,thenreturnthe
resultsasthevariable"docs".Oncewehavethosedocuments,wethendoarenderofuserlist(which
willneedacorrespondingJadetemplate),givingittheuserlistvariabletoworkwith,andpassingour

Nextlet'ssetupourJadetemplate.NavigatetoC:\node\nodetest1\views\andopenindex.jade.Once
again,immediatelysaveitasuserlist.jade.ThenedittheHTMLsoitlookslikethis:
C:\NODE\NODETEST1\VIEW\USERLIST.JADE
extendslayout
blockcontent
h1.
UserList
ul
eachuser,iinuserlist
li
a(href="mailto:#{user.email}")=user.username

Thisissayingthatwe'regoingtopullinthesetofdocumentswejustcalleduserlistoverintheroute
file,andthenforeachentry(named'user'duringtheloop),gettheemailandusernamevaluesfromthe
objectandputthemintoourhtml.We'vealsogotthecountihandyincaseweneedit,thoughin
thisinstancewedon't.
We'reallset.Savethatfile,andlet'srestartournodeserver.Rememberhowtodothat?Gotoyour
commandprompt,headforC:\node\nodetest1\andctrlctokillyourserverifit'sstillrunningfromway
backbefore.Thentype:
COMMANDC:\NODE\NODETEST1\
C:\node\nodetest1>npmstart

TIP
Gettingthefollowingerror?
{[Error:Cannotfindmodule'../build/Release/bson']code:'MODULE_NOT_FOUND'}jsbson:Failedtoloadc++
bsonextension,usingpureJSversion
ClickHereforHelp

Nowopenyourbrowserandheadtohttp://localhost:3000/userlistandmarvelattheresults.

You'renowpullingdatafromtheDBandspittingitoutontoawebpage.Nice!
TIP
Gettingthefollowingerror?

ClickHereforHelp

ThereonemorethingIbadlywantedtocoverinthistutorial,butbecauseit'salreadyaboutaslongas
theBible,I'mgoingtobreezethroughithere.Youcouldveryeasilychangeyouruserlistviewfroman
ExpressdrivenwebpagecompletewithJadetemplatetoaplainoldJSONresponse.Youcouldthen
accessthiswithAJAXandmanipulateitontheclientside,withjQueryforexample,insteadofonthe
serverside.Infact,IwantedtocoverthatsobadlythatIwroteanentiresecondtutorialonit.Youcan
findthelinkattheendofthisone!
Let'sfinishthisup.

PART4THEHOLYGRAIL:WRITINGTOTHEDB
Writingtothedatabaseisnotparticularlydifficult.Essentiallyweneedtosetuparoutethattakesa
POST,ratherthanaGET.
STEP1CREATEYOURDATAINPUT
We'regoingquickanddirtyhere:twougly,unstyledtextinputsandasubmitbutton.1996style,but
beforewegettothat,we'regoingtodosomejavacripting.Let'sstartbyquicklywiringuparoutefor
ouradduserform.Open/routes/index.jsandaddthefollowingcodeabovethelastmodule.exportsline:
C:\NODE\NODETEST1\ROUTES\INDEX.JS
/*GETNewUserpage.*/
router.get('/newuser',function(req,res){
res.render('newuser',{title:'AddNewUser'});
});

Nowwejustneedatemplate.Openup/views/index.jade,saveitasnewuser.jade,andreplacethe
wholefilecontentswiththis:
C:\NODE\NODETEST1\VIEWS\NEWUSER.JADE
extendslayout
blockcontent
h1=title
form#formAddUser(name="adduser",method="post",action="/adduser")
input#inputUserName(type="text",placeholder="username",name="username")
input#inputUserEmail(type="text",placeholder="useremail",name="useremail")
button#btnSubmit(type="submit")submit

Herewe'recreatingaformwiththeID"formAddUser"(IliketoprefacemyIDswiththetypeofthing
we'reID'ing.It'sapersonalquirk).Methodispost,actionisadduser.Prettystraightforward.Underthat
we'vedefinedourtwoinputsandourbutton.
Ifyourestartyournodeserverandgotohttp://localhost:3000/newuseryou'llseeyourforminallits
glory.

Goaheadandsubmit.Enjoythe404error.We'reabouttofixthat.
STEP2CREATEYOURDBFUNCTIONS
OK,thisisprettymuchthesameprocessaswiththeuserlist.Wedon'tneedanotherapp.usestatement
sincewe'vealreadywrappedourdatabaseobjectintoeveryrequest(seeabove).Thatmeansit'llbe
accessibletoanynewrouteswewrite.ThatmeansthatallweneedtodoisaddarouteforPOSTingto
/adduser.
Gobackto/routes/index.jsandlet'screateourinsertionfunction.Onceagain,you'llwanttoput
thisabovethefinalmodule.exportsline(itdoesn'tREALLYmatter,butitmakesthingscleanertowrap
upwiththeexport).Thisisabigone,soI'vecommentedthecodeprettythoroughly.Hereitis:
C:\NODE\NODETEST1\ROUTES\INDEX.JS
/*POSTtoAddUserService*/
router.post('/adduser',function(req,res){
//SetourinternalDBvariable
vardb=req.db;
//Getourformvalues.Theserelyonthe"name"attributes
varuserName=req.body.username;
varuserEmail=req.body.useremail;
//Setourcollection
varcollection=db.get('usercollection');
//SubmittotheDB
collection.insert({
"username":userName,
"email":userEmail
},function(err,doc){
if(err){
//Ifitfailed,returnerror
res.send("Therewasaproblemaddingtheinformationtothedatabase.");
}
else{
//Andforwardtosuccesspage
res.redirect("userlist");
}
});
});

Obviouslyintherealworldyouwouldwantatonmorevalidating,errorchecking,andthelike.You'd
wanttocheckforduplicateusernamesandemails,forexample.Andtovetthattheemailaddressat
leastlookslikealegitentry.Butthis'llworkfornow.Asyoucansee,onsuccessfullyaddingtotheDB,

Aretheresmootherwaystodothis?Absolutely.We'restayingasbarebonesaspossiblehere.Now,let's
goaddsomedata!
STEP3CONNECTANDADDDATATOYOURDB
Makesuremongodisrunning!Thenheadtoyourcommandprompt,killyournodeserverifit'sstill
running,andrestartit:
COMMANDC:\NODE\NODETEST1\
C:\node\nodetest1>npmstart

Assumingyourserverisrunning,whichitshouldbe,returntoyourwebbrowserandpointit
athttp://localhost:3000/newuseragain.There'sourexcitingform,justlikebefore.Exceptnowlet'sfillin
somevaluesbeforewehitsubmit.Iwentwithusername"noderocks"andemail
"noderocks@rockingnode.com"...youcangowithwhateveryou'dlike.

Clicksubmit,andcheckitout...we'rebackat/userlistandthere'sournewentry!

WeareofficiallyreadingandwritingfromaMongoDBdatabaseusingNode.js,Express,andJade.You
arenowwhatthekidscalla"fullstack"developer(probablynotaGOODone,justyet,butIdidn't
promisethat).
Congratulations.Seriously.Ifyoufollowedthisallthewaythrough,andifyoureallypaidattentionto
whatyouweredoinganddidn'tjustpastecode,youshouldhaveareallysolidgrasponroutesand
views,readingfromtheDB,andpostingtotheDB.Thatisallyouneedtogetstarteddeveloping
whateverappyouwanttobuild.Idon'tknowaboutyou,butIthinkthat'sreallycool.

PART5NEXTSTEPS
Fromhere,there'samilliondifferentdirectionsyoucouldgo.YoucouldcheckoutMongoose,whichis
anotherMongomanipulationpackageforNode/Express(here'sagoodtutorialforbeginners).It'sbigger
thanMonk,butitalsodoesmore.YoucouldcheckoutStylus,theCSSpreprocessorthatcomeswith
Express.Youcouldgoogle"NodeExpressMongoTutorial"andseewhatcomesup.Justkeepexploring
andkeepbuilding!
Ihopethistutorial'sbeenhelpful.IwroteitbecauseIcould'veuseditwhenIgotstarted,andIcouldn't
seemtofindsomethingthatwasquiteatthislevel,orthatbrokethingsdowninsuchlong,
long,loooongdetail.Ifyoumadeitthisfar,thanksforstickingwithit!
NEW:The"sequel"tothistutorialisnowavailable!Finditat:CreatingaSimpleRESTfulWebAppwith
Node.js,Express,andMongoDB.
Resource:thefolksatUdemyhaveputupanincrediblyextensiveMEANstackintroductionthat'swell
worthcheckingout.
MERCIBEAUCOUP

You might also like