THEDEADSIMPLESTEPBYSTEPGUIDEFORFRONT
ENDDEVELOPERSTOGETTINGUPANDRUNNING
[Link],EXPRESS,JADE,ANDMONGODB
SETUPTHEFULLSTACKANDHAVEAWEBPAGERUNNINGIN30
MINUTES.MAKEITTALKTOYOURDBINANOTHER30.
ByChristopherBuecheler
LASTUPDATED:September2nd,2015
ThistutorialusesNode.jsv0.12andwillnotworkproperlywitholderversionsonsomesystems.
Youcanfind/forktheentiresampleprojectonGitHub
Hey!ThisandallmyothertutorialswillsoonbemovingtoanewhomeatCloseBrace,asitefor
[Link],andsignuptobealertedwhenthe
sitegoeslive.
INTRODUCTION
Thereareapproximatelyonehundredmilliontutorialsonthewebforgettinga"Hello,World!"app
[Link]!It'sespeciallygreatifyourgoalistogreettheworldandthengive
uponyourwebcareerandgospendtherestofyourlifeas,like,[Link]'t
reallydescribemostofus,sowegolookingformoretutorials.
Inmyexperience,the"nextlevel"[Link]
"Hello,World!"[Link],butalot
oftimesthosetutorialsassumethereaderhasdoneawholebunchofintermediatefiddling,andthey
[Link],
intermediatesteps,andIdon'tthinkI'mtheonlyone.
I'mnottheonlyone,right?
Well,goodnews,everyone!I'vedonethefiddlingandreadabunchoftutorialsandshoutedatmy
[Link],
theExpressframework,theJadeHTMLpreprocessor,[Link]
[Link],thesky'sthelimit.
Here'sthedeal:I'mgoingtoshowyouhowtogetallofthisstuffsetup.I'llbeassumingthatyou'rea
frontenddeveloperwhoknowsHTML5/CSS3/JavaScriptwellenoughthatIdon'thavetoexplainthose.
Ifthat'syou,thenthisshouldbeasolidprimer.
Yourappwilllookpretty,itwillconnecttoaDB,it'llgetsomeresults,andit'lldostuffwiththose
[Link]'[Link],Iwillexplainwhatthecode
eveninstalled,toaDBdrivenwebappwritteninalanguageyoufullyunderstand,andthefoundation
[Link]'lldoitinabout60minutesof
[Link]?Isubmitthatitis.
Let'sgo.
PARTI15MINUTESOFINSTALLING
Ifyou'rereallystartingfromscratch,thengettingeverythingupandrunningtakesalittlebitoftime.
Noneofitisdifficult.IrunWindows8onmymainmachine,soit'llbeslightlydifferentforthoseona
MacorUbuntuorother*nixsystem,butit'sprincipallythesamethinginallcases.
[Link]
[Link]'lldetectyourOSand
giveyoutheappropriateinstaller(ifforsomereasonitdoesn't,clickthedownloadsbuttonandgrabthe
oneyouneed).[Link]'sit,[Link],equallyimportant,NPM
NodePackageManagerwhichletsyouaddallkindsofgreatstufftoNodequicklyandeasily.
Openacommandprompt
cdtothedirectoryinwhichyouwishtokeepyourtestapps
(forthepurposesofthistutorial,C:\node).
STEP2INSTALLEXPRESSGENERATOR
NowthatwehaveNoderunning,weneedtherestofthestuffwe'regoingtoactuallyusetocreatea
[Link]'regoingtoinstallExpress,whichisaframeworkthattakesNodefroma
barebonesapplicationandturnsitintosomethingthatbehavesmorelikethewebserverswe'reallused
toworkingwith(andactuallyquiteabitmorethanthat).WeneedtostartwithExpressGenerator,
whichisactuallydifferentthanExpressitself...it'sascaffoldingappthatcreatesaskeletonforexpress
[Link],typethefollowing:
COMMANDC:\NODE>
C:\node>npminstallgexpressgenerator
Thegeneratorshouldautoinstall,andsinceit(likeallpackagesinstalledwithg)livesinyourmaster
NPMinstallationdirectory,[Link]'suseourgenerator
tocreatethescaffoldingforawebsite.
STEP3CREATEANEXPRESSPROJECT
We'regoingtouseExpressandJade,butnottheStylusCSSpreprocessor(whichpeopleoftenusein
thisstack).We'[Link]
templatingenginetogainaccesstoourNode/[Link]'snothardtolearnifyou
alreadyknowHTML,justrememberthatyoureallyhavetopayattentiontoindentationorthingswillgo
[Link],youcoulduseEJSinstead(note:
IcannotprovidesupportforthistutorialifyouchoosetouseanythingotherthanJade).
Aquicknoteonindentation:everythingisthistutorialhasbeennormalizedto4spacetabs,evencode
[Link],oractualtabs
(whichisusuallymypreference),that'[Link],again,YOURINDENTATIONMUSTBE
[Link]"alltabs"or"allspaces"butyoumustbevery,very
[Link],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
[Link]'llseesomethinglikethis:
COMMANDC:\NODE\
C:\node>expressnodetest1
create:nodetest1
create:nodetest1/[Link]
create:nodetest1/[Link]
create:nodetest1/public
create:nodetest1/public/javascripts
create:nodetest1/public/images
create:nodetest1/public/stylesheets
create:nodetest1/public/stylesheets/[Link]
create:nodetest1/routes
create:nodetest1/routes/[Link]
create:nodetest1/routes/[Link]
create:nodetest1/views
create:nodetest1/views/[Link]
create:nodetest1/views/[Link]
create:nodetest1/views/[Link]
create:nodetest1/bin
create:nodetest1/bin/www
installdependencies:
>cdnodetest1&&npminstall
runtheapp:
>SETDEBUG=nodetest1b:*&npmstart
STEP4EDITDEPENDENCIES
OK,nowwehavesomebasicstructureinthere,butwe'[Link]'llnotethattheexpress
[Link]
editorandit'lllooklikethis:
C:\NODE\NODETEST1\[Link]
{
"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"
}
}
[Link].
Specifically,[Link]'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"
}
[Link],andyouwon'tbeabletoinstall!
ImportantNote:[Link]
thisolderversionofthemongodbmodule(1.4.4)ormonkwillnotworkandyourappwill
[Link],butthisshouldkeepyourunningfornow.
STEP5INSTALLDEPENDENCIES
Nowwe'vedefinedourdependenciesandwe'[Link]
twomodulesarecurrentasofthelatestupdate,butnewversionsofNPMmodulesarefrequentlyrolled
[Link],I'mafraid
you'reonyourown.
Returntoyourcommandprompt,cdtoyournodetest1directory,andtypethis:
COMMANDC:\NODE\NODETEST1\
C:\node\nodetest1>npminstall
It'[Link]'sbecauseit'sreadingtheJSONfilewejusteditedand
installingallthestufflistedinthedependenciesobject(yes,includingExpressweinstalledthe
generatorglobally,butwestillhavetoinstalltheactualmoduleinsidethisoneparticularproject).Once
NPMhasrunitscourse,youshouldhaveanode_modulesdirectorywhichcontainsallofour
dependenciesforthistutorial.
[Link],though,weneedto
doonequickthingtoprepareforsettingupourdatabaselater.Stillinyournodetest1directory,type
this:
COMMANDC:\NODE\NODETEST1\
C:\node\nodetest1>mkdirdata
That'swherewe'[Link]'texist,the
[Link]'renotdoinganythingwithitrightnow,
though,solet'stestoutourwebserver!Typethefollowing:
COMMANDC:\NODE\NODTEST1\
C:\node\nodetest1>npmstart
Note:inpreviousversions,youused"[Link]"thishasbeendeprecatedinfavorofaskeletal
[Link],thatdoesn'treallymatter,sincewe'renotworyingabout
[Link],using"npmstart"isessentiallyidenticaltopreviousversionsofthistutorial.
Anyway,[Link]'llgetthis:
NODECONSOLE
>[email protected]:\sites\node\nodetest1
>node./bin/www
Everythingworking?Awesome!Openabrowserandheadfor[Link]
seeawelcometoExpresspage.
YouarenowrunningyourownNodeJSwebserver,withtheExpressengineandJadeHTML
[Link],huh?
PART2OK,FINE,LET'SDO"HELLO,WORLD!"
[Link].Pointitatyournodetest1directoryand
[Link],well,[Link]'sabreakdownof
whatyou'regoingtosee:
C:\NODE\NODETEST1\[Link]
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,[Link]
setuptheydirecttrafficandalsocontainsomeprogramminglogic(youcanestablishamoretraditional
[Link]'soutsideofthescopeofthisarticle).Backwhenweset
upthisproject,[Link]'regoingtototallyignoretheuserroutefor
nowandjustworkinthetoplevelroute(controlledbyc:\node\nodetest1\routes\[Link]).
C:\NODE\NODETEST1\[Link]
varapp=express();
Thisone'[Link]
thisvariabletoconfigureabunchofExpressstuff.
C:\NODE\NODETEST1\[Link]
//viewenginesetup
[Link]('views',[Link](__dirname,'views'));
[Link]('viewengine','jade');
//uncommentafterplacingyourfaviconin/public
//[Link](favicon(__dirname+'/public/[Link]'));
[Link](logger('dev'));
[Link]([Link]());
[Link]([Link]({extended:false}));
[Link](cookieParser());
[Link]([Link]([Link](__dirname,'public')));
[Link]('/',routes);
[Link]('/users',users);
Thistellstheappwheretofinditsviews,whatenginetousetorenderthoseviews(Jade),andcallsa
[Link]
objectsfromthe/public/dir,buttomakethemactuallyseemlikethey'recomingfromthetoplevel(it
alsodoesthiswiththeviewsdirectory).Forexample,theimagesdirectoryis
c:\node\nodetest1\public\imagesbutitisaccessedat[Link]
C:\NODE\NODETEST1\[Link]
///catch404andforwardingtoerrorhandler
[Link](function(req,res,next){
next(err);
});
///errorhandlers
//developmenterrorhandler
//willprintstacktrace
if([Link]('env')==='development'){
[Link](function(err,req,res,next){
[Link]([Link]||500);
[Link]('error',{
message:[Link],
error:err
});
});
}
//productionerrorhandler
//nostacktracesleakedtouser
[Link](function(err,req,res,next){
[Link]([Link]||500);
[Link]('error',{
message:[Link],
error:{}
});
});
Theseareerrorhandlersfordevelopmentandproduction(and404's).We'renotreallyworryingabout
thedifferentbetweenthosetworightnow,butbasicallyifyourappisindevelopmentmode,yourerrors
[Link]'twanttoprintastacktraceoutonaproductionsite
thatanyoneonthewebcansee.
C:\NODE\NODETEST1\[Link]
[Link]=app;
AcorepartofNodeisthatbasicallyallmodulesexportanobjectwhichcaneasilybecalledelsewherein
[Link].
Nowthen,let'[Link]'renotgoingtojuststick"Hello,World!"[Link]
we'regoingtousethisasanopportunitytolearnabitmoreaboutroutesandtotakealookathow
Jadeworksforputtingpagestogether.
We'[Link]:
C:\NODE\NODETEST1\[Link]
[Link]('/',routes);
[Link]('/users',users);
[Link],normallyI'dadvocatesettingup
[Link],theusersroutefilemightcontain
routesforaddingusers,deletingthem,updatingthem,andsoforth,whileanewroutefilecalled
"locations"mighthandleadding,editing,deletinganddisplayinglocationdata(inanappforwhichthat
wasrequired).Inthiscase,tokeepthingssimple,we'[Link]
meansyoucancompletelyignorethe/usersline.
RememberthattheExpressscaffoldingalreadydefinedthe"routes"variableandpointeditattheindex
[Link],openupyourroutesfolder,[Link],[Link]
this:
C:\NODE\NODETEST1\ROUTES\[Link]
varexpress=require('express');
varrouter=[Link]();
/*GEThomepage.*/
[Link]('/',function(req,res){
[Link]('index',{title:'Express'});
});
[Link]=router;
Prettysparse,right?Basicallywe'rerequiringourExpressfunctionality,thenattachinga"router"
variabletoExpress'sroutermethod,thenusingthatmethodwhenanattemptismadetoHTTPgetthe
[Link].
Wecaneasilyclonethatgetfunctionforanotherpage,solet'[Link],
[Link],addthiscode:
C:\NODE\NODETEST1\ROUTES\[Link]
/*GETHelloWorldpage.*/
[Link]('/helloworld',function(req,res){
[Link]('helloworld',{title:'Hello,World!'});
});
That'sallittakestohandleroutingtheURI,butwedon'[Link]
[Link]'[Link],andthengoaheadandopen
[Link],[Link].
Nowtakealookatthecode:
C:\NODE\NODETEST1\VIEWS\[Link]
extendslayout
blockcontent
h1=title
pWelcometo#{title}
[Link]("extends")[Link],andthenwithinthe
contentblockdefinedinthelayoutfile,[Link]"title"
variablewhichwesetabove,[Link]'tevenhavetochangethetextat
[Link]'schangeitanywayto:
pHello,World!Welcometo#{title}
Savethefile,gotoyourcommandprompt,ctrlctokillyourserverifit'salreadyrunning,andthentype:
COMMANDC:\NODE\NODETEST1\
[Link],thisseemsagoodtimetomention:changestoJade
templatesdonotrequireaserverrestart,butbasicallywheneveryouchangeajsfile,[Link]
theroutefiles,you'llneedtorestarttoseechanges.
SOwiththeserverrestarted,navigateto[Link]
asininetextthatgetsdisplayed:
OK!Sonowwe'vegotourrouterroutingustoourview,[Link]'sdosomemodeling.
I'llgiveyouamomentifyouneedtofixyourhairormakeup.
PART3CREATEOURDBANDREADSTUFFFROMIT
STEP1INSTALLMONGODB
We'[Link],firstwe'regoingto
ourwebbrowser,pointingitto[Link]
inthemainmenuandsnagtheproductionreleasethatfitsyoursystem.ForWindows8ona64bit
processor,wewant"64bit*2008R2+".ThiswillgiveyouanMSIfilethatwillrunthroughastandard
[Link](ina\server\3.0\subfolder),
[Link],though,I'mgoingtoinstallintoC:\[Link]'t
reallymatterMongoitselfisquitesmall,andwe'llbestoringourdatabaseinournodetest1directory.
Anyway,copythefilesinthebinfolderwithinyourtempdirectorytowhereveryouwantMongotolive,
andyou'[Link]'[Link]'smakeitdostuff.
STEP2RUNMONGODANDMONGO
Inyournodetest1directory,createasubdircalled"data".Thennavigatetothedirectoryinwhichyou
placedyourMongoDBfiles(let'ssayC:\mongofornow),andthenintothe"bin"[Link]
directory,typethefollowing:
COMMANDC:\MONGO\BIN\
mongoddbpathc:\node\nodetest1\data\
You'[Link]'sthefirsttime,becauseithasto
[Link]"[initandlisten]waiting
forconnectionsonport27017",you'[Link]'snothingmoretodoheretheserverisrunning.
[Link]
directory,andtype:
COMMANDC:\MONGO\BIN\
mongo
You'llseesomethinglikethefollowing:
MONGOCONSOLE
c:\mongo\bin>mongo
MongoDBshellversion:2.4.5
connectingto:test
Additionally,ifyou'repayingattentiontoyourmongodinstance,you'llseeitmentionthataconnection
[Link],you'vegotMongoDBupandrunning,andyou'veconnectedtoitwiththe
[Link]'llusethisclienttomanuallyworkonourdatabase,forabit,butit'snotnecessaryforrunning
[Link](mongod)isneededforthat.
STEP3CREATEADATABASE
Don'tworryabout"connectingto:test"that'sjustthedefaultdatabaseMongodecidestouseifyou
don'tspecifyoneonthecommandline,whichwedidn'tbecauseit'[Link]'t
actuallyevencreatethe"test"[Link]'dbetotallyfinetojustworkinthat
databaseforrightnow,butlet'[Link],typethefollowing:
MONGOCONSOLE
usenodetest1
Nowwe'reusingthedatabase"nodetest1."Likewith"test",[Link]
databaseexist,[Link]'regoingtostartoffbydoingthatrightinsideofthe
Mongoclient.
STEP4ADDSOMEDATA
MyfavoritethingaboutMongoDBisthatitusesJSONforitsstructure,whichmeansitwasinstantly
[Link]'renotfamiliarwithJSON,you'llneedtodosomereading,asI'mafraidthat's
outsidethescopeofthistutorial.
Let'[Link],we'rejustgoingtohaveasimple
[Link]:
MONGOCONSOLE
{
"_id":1234,
"username":"cwbuecheler",
"email":"cwbuecheler@[Link]"
}
Youcancreateyourown_idassignmentifyoureallywant,butIfindit'sbesttoletMongojustdoits
[Link],typethis:
MONGOCONSOLE
[Link]({"username":"testuser1","email":"testuser1@[Link]"})
Somethingimportanttonotehere:that"db"standsforourdatabase,whichasmentionedabovewe've
definedas"nodetest1".The"usercollection"[Link]'tastepwhere
wecreatedthe"usercollection"[Link]'sbecausethefirsttimeweaddtoit,it'sgoingtobe
[Link],[Link],[Link]'s
notveryexciting,sotypethis:
MONGOCONSOLE
[Link]().pretty()
Incaseyou'recurious,[Link]()[Link]:
MONGOCONSOLE
{
"_id":ObjectId("5202b481d2184d390cbf6eca"),
"username":"testuser1",
"email":"testuser1@[Link]"
}
Except,ofcourse,yourObjectIDwillbedifferent,sinceasmentioned,Mongoisautomatically
[Link]'sallthereistowritingtoMongoDBfromtheclientapp,andifyou'veever
workedwithJSONservicesbefore,youareprobablygoing"oh,wow,that'sgoingtobeeasyto
implementontheweb."you'reright!
AquicknoteonDBstructure:obviouslyinthelongrunyou'reunlikelytobestoringeverythingatthe
[Link]
friend!
Nowthatwe'vegotonerecord,let'[Link],typethefollowing:
MONGOCONSOLE
newstuff=[{"username":"testuser2","email":"testuser2@[Link]"},{"username":"testuser3","em
[Link](newstuff);
Notethat,yes,[Link]!Anotheruseof
[Link]().pretty()willshowallthreerecords:
MONGOCONSOLE
{
"_id":ObjectId("5202b481d2184d390cbf6eca"),
"username":"testuser1",
"email":"testuser1@[Link]"
"_id":ObjectId("5202b49ad2184d390cbf6ecb"),
"username":"testuser2",
"email":"testuser2@[Link]"
}
{
"_id":ObjectId("5202b49ad2184d390cbf6ecc"),
"username":"testuser3",
"email":"testuser3@[Link]"
}
Nowwe'regoingtostartactuallyinteractingwiththewebserverandsitethatwesetupearlier.
STEP5HOOKMONGOUPTONODE
[Link]'sstartbybuildingapagethatjustspitsoutourDBentries
[Link]'stheHTMLwe'reshootingtogenerate:
<ul>
<li><ahref="[Link]
<li><ahref="[Link]
<li><ahref="[Link]
</ul>
Iknowthisisn'trocketscience,butthat'[Link]'rejustdoingasimpleDBreadandwriteinthis
tutorial,[Link],weneedtoaddafewlinestoourmain
[Link]
C:\node\nodetest1\[Link]'llsee:
C:\NODE\NODETEST1\[Link]
varexpress=require('express');
varpath=require('path');
varfavicon=require('servefavicon');
varlogger=require('morgan');
varcookieParser=require('cookieparser');
varbodyParser=require('bodyparser');
Nowaddthesethreelines:
C:\NODE\NODETEST1\[Link]
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
[Link]'vechangedit,obviouslyusethatportinstead.
Nowlookatthebottomofthefile,whereyouhavethis:
[Link]('/',routes);
[Link]('/users',users);
[Link](alongwiththeothersyou'[Link])
[Link],simpleexplanationis:they'reprovidingcustom
[Link]'sprettystraightforward,butduetochainingit
needstocomebeforeourroutedefinitions,sothattheycanmakeuseofit.
Abovethetwolinesjustmentioned,addthefollowing:
C:\NODE\NODETEST1\[Link]
//Makeourdbaccessibletoourrouter
[Link](function(req,res,next){
[Link]=db;
next();
});
NOTE:Ifyoudon'tputthisabovetheroutingstuffmentionedabove([Link]('/',routes)),
yourappWILLNOTWORK.
Wealreadydefined"db"[Link]'[Link]
[Link],we'readdingthatobjecttoeveryHTTPrequest(ie:"req")ourapp
[Link]:thisisprobablysuboptimalforperformancebut,again,we'regoingquickndirtyhere.
So,again,[Link],now:
C:\NODE\NODETEST1\[Link]
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
[Link]('views',[Link](__dirname,'views'));
[Link]('viewengine','jade');
//uncommentafterplacingyourfaviconin/public
//[Link](favicon(__dirname+'/public/[Link]'));
[Link](logger('dev'));
[Link]([Link]());
[Link]([Link]({extended:false}));
[Link](cookieParser());
[Link]([Link]([Link](__dirname,'public')));
//Makeourdbaccessibletoourrouter
[Link](function(req,res,next){
[Link]=db;
next();
[Link]('/',routes);
[Link]('/users',users);
///catch404andforwardingtoerrorhandler
[Link](function(req,res,next){
varerr=newError('NotFound');
[Link]=404;
next(err);
});
///errorhandlers
//developmenterrorhandler
//willprintstacktrace
if([Link]('env')==='development'){
[Link](function(err,req,res,next){
[Link]([Link]||500);
[Link]('error',{
message:[Link],
error:err
});
});
}
//productionerrorhandler
//nostacktracesleakedtouser
[Link](function(err,req,res,next){
[Link]([Link]||500);
[Link]('error',{
message:[Link],
error:{}
});
});
[Link]=app;
Nextthingweneedtodoismodifyourroutesothatwecanactuallyshowdatathat'sheldinour
database,usingourdbobject.
STEP6PULLYOURDATAFROMMONGOANDDISPLAYIT
OpenupC:\node\nodetest1\routes\[Link]'sstillgottheindexroute,andthegoofy
/[Link]'saddathird:
C:\NODE\NODETEST1\ROUTES\[Link]
/*GETUserlistpage.*/
[Link]('/userlist',function(req,res){
vardb=[Link];
varcollection=[Link]('usercollection');
[Link]({},{},function(e,docs){
[Link]('userlist',{
"userlist":docs
});
});
});
OKthat'[Link]'sreallydoing,though,isextractingthe"db"objectwe
passedtoourhttprequest,andthenusingthatdbconnectiontofillour"docs"variablewithdatabase
documents,ie:[Link]"gets"inthisroutefile.
Basically,wetellourappwhichcollectionwewanttouse('usercollection')anddoafind,thenreturnthe
resultsasthevariable"docs".Oncewehavethosedocuments,wethendoarenderofuserlist(which
willneedacorrespondingJadetemplate),givingittheuserlistvariabletoworkwith,andpassingour
Nextlet'[Link]:\node\nodetest1\views\[Link]
again,[Link]:
C:\NODE\NODETEST1\VIEW\[Link]
extendslayout
blockcontent
h1.
UserList
ul
eachuser,iinuserlist
li
a(href="[Link]
Thisissayingthatwe'regoingtopullinthesetofdocumentswejustcalleduserlistoverintheroute
file,andthenforeachentry(named'user'duringtheloop),gettheemailandusernamevaluesfromthe
[Link]'vealsogotthecountihandyincaseweneedit,thoughin
thisinstancewedon't.
We'[Link],andlet'[Link]?Gotoyour
commandprompt,headforC:\node\nodetest1\andctrlctokillyourserverifit'sstillrunningfromway
[Link]:
COMMANDC:\NODE\NODETEST1\
C:\node\nodetest1>npmstart
TIP
Gettingthefollowingerror?
{[Error:Cannotfindmodule'../build/Release/bson']code:'MODULE_NOT_FOUND'}jsbson:Failedtoloadc++
bsonextension,usingpureJSversion
ClickHereforHelp
Nowopenyourbrowserandheadto[Link]
You'[Link]!
TIP
Gettingthefollowingerror?
ClickHereforHelp
ThereonemorethingIbadlywantedtocoverinthistutorial,butbecauseit'salreadyaboutaslongas
theBible,I'[Link]
[Link]
accessthiswithAJAXandmanipulateitontheclientside,withjQueryforexample,insteadofonthe
[Link],[Link]
findthelinkattheendofthisone!
Let'sfinishthisup.
PART4THEHOLYGRAIL:WRITINGTOTHEDB
[Link]
POST,ratherthanaGET.
STEP1CREATEYOURDATAINPUT
We'regoingquickanddirtyhere:twougly,unstyledtextinputsandasubmitbutton.1996style,but
beforewegettothat,we'[Link]'sstartbyquicklywiringuparoutefor
[Link]/routes/[Link]:
C:\NODE\NODETEST1\ROUTES\[Link]
/*GETNewUserpage.*/
[Link]('/newuser',function(req,res){
[Link]('newuser',{title:'AddNewUser'});
});
[Link]/views/[Link],[Link],andreplacethe
wholefilecontentswiththis:
C:\NODE\NODETEST1\VIEWS\[Link]
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'[Link]'sapersonalquirk).Methodispost,[Link]
we'vedefinedourtwoinputsandourbutton.
Ifyourestartyournodeserverandgoto[Link]
glory.
[Link]'reabouttofixthat.
STEP2CREATEYOURDBFUNCTIONS
OK,[Link]'[Link]
sincewe'vealreadywrappedourdatabaseobjectintoeveryrequest(seeabove).Thatmeansit'llbe
[Link]
/adduser.
Gobackto/routes/[Link]'[Link],you'llwanttoput
[Link](itdoesn'tREALLYmatter,butitmakesthingscleanertowrap
upwiththeexport).Thisisabigone,soI'[Link]:
C:\NODE\NODETEST1\ROUTES\[Link]
/*POSTtoAddUserService*/
[Link]('/adduser',function(req,res){
//SetourinternalDBvariable
vardb=[Link];
//[Link]"name"attributes
varuserName=[Link];
varuserEmail=[Link];
//Setourcollection
varcollection=[Link]('usercollection');
//SubmittotheDB
[Link]({
"username":userName,
"email":userEmail
},function(err,doc){
if(err){
//Ifitfailed,returnerror
[Link]("Therewasaproblemaddingtheinformationtothedatabase.");
}
else{
//Andforwardtosuccesspage
[Link]("userlist");
}
});
});
Obviouslyintherealworldyouwouldwantatonmorevalidating,errorchecking,[Link]'d
wanttocheckforduplicateusernamesandemails,[Link]
[Link]'[Link],onsuccessfullyaddingtotheDB,
Aretheresmootherwaystodothis?[Link]'[Link],let's
goaddsomedata!
STEP3CONNECTANDADDDATATOYOURDB
Makesuremongodisrunning!Thenheadtoyourcommandprompt,killyournodeserverifit'sstill
running,andrestartit:
COMMANDC:\NODE\NODETEST1\
C:\node\nodetest1>npmstart
Assumingyourserverisrunning,whichitshouldbe,returntoyourwebbrowserandpointit
at[Link]
[Link]"noderocks"andemail
"noderocks@[Link]"...youcangowithwhateveryou'dlike.
Clicksubmit,andcheckitout...we'rebackat/userlistandthere'sournewentry!
[Link],Express,[Link]
arenowwhatthekidscalla"fullstack"developer(probablynotaGOODone,justyet,butIdidn't
promisethat).
[Link],andifyoureallypaidattentionto
whatyouweredoinganddidn'tjustpastecode,youshouldhaveareallysolidgrasponroutesand
views,readingfromtheDB,[Link]
[Link]'tknowaboutyou,butIthinkthat'sreallycool.
PART5NEXTSTEPS
Fromhere,there'[Link],whichis
anotherMongomanipulationpackageforNode/Express(here'sagoodtutorialforbeginners).It'sbigger
thanMonk,[Link],theCSSpreprocessorthatcomeswith
[Link]"NodeExpressMongoTutorial"[Link]
andkeepbuilding!
Ihopethistutorial'[Link]'veuseditwhenIgotstarted,andIcouldn't
seemtofindsomethingthatwasquiteatthislevel,orthatbrokethingsdowninsuchlong,
long,[Link],thanksforstickingwithit!
NEW:The"sequel"tothistutorialisnowavailable!Finditat:CreatingaSimpleRESTfulWebAppwith
[Link],Express,andMongoDB.
Resource:thefolksatUdemyhaveputupanincrediblyextensiveMEANstackintroductionthat'swell
worthcheckingout.
MERCIBEAUCOUP