Wewilldevelop a landingpagewherewecollectandmanagesalesleads.
Youcanfreelyusetheresultingsourcecodeas a startingpointtodevelopyourproduct.
Andwewillcoverallofftheconceptsthatyouneedtoknowtobuild a fullyfledgedWebapplicationusingKnowJsweassumeintermediatesprogrammingknowledge, butnobackgroundinbailapplicationdevelopmentornogenius.
Okay, let's getstarted.
So a littlebitofbackgroundonNoJacemanyyearsback, developerRyanDoleexploredtheideaofusinggeneralscriptforservicesideprogrammingwiththemainmotivationthatexistinghttpserverscouldnothandlelotsoffsimultaneousconnectionsefficiently.
Meanwhile, also, Google's Chromebrowserteamdeveloped a newjealousscriptchangingfromscratchcalled V eightandtheuniquepropertyof V eightisthatitwasbuilttobemuch, muchfasterininterpretingandrunningJavaScriptcomparedtotheotherbrowsers.
Andno J s tookGooglesoptimized V eightjealousscriptengineforserversideprogramming, alsocreating a setupthatallowedformuchmorescalablehandlingoffrequestsandalso a packagemanagerormanagingtheopensource.
Andasoffthisvideoitis 10.15 pointzeroistheversionthatweneed, Sowegobacktoourterminaltype N V M install 10 15 thatzeroofthisstepmaytakeyou a littlebitlonger.
ExpressJsupcomeexpresschases, a Webframeworkandthepoweroffitis.
Initssimplicity, youcandevelopverycomplexWebapplications, yetitis a minimalistWebframeworkthatisveryeasytograsp, andthisistheinstallcommandsforexpress, yes, butwe'regoingtouseanothertoolcalledtheExpressgeneratorthatwillgiveus a goodstartingpointsand a directorystructure.
Nowhereinthiscomment, NPM, as I mentioned, isthepackagemanager.
Wewillusethistoinstallpackagesandhearthedash G standsfor a globalinstall, whichmeanstheinstallationisgoingtohappenthecomputerwideandnotjustoneparticleproject.
So I'm gonnacopyPastethiscommandhere, DashDashFewequalsPuckmeanswe'regoingtousepugasourHTMLtemptingengine.
So I'm justgoingtopressenterandwehavenowcreated a directorystructureforourapplication.
NowthatwehaveJanuarytotheskeletondirectorystructureforourapplication, I wanttogoovereachfolder V creates.
Well, let's goaheadandstartourtexteditorandlet's take a lookundermyapp.
Thepublicfoldercontainsourassetsasit's ourstaticfilesthatyourHTMLfilesmakesreferencestoeachHTMLFileswillrefertocertainimagessuchaslogosandsomejealousscriptfilesthatneedtoberunontheWebpageorstylesheetsthatdescribethestyleon a Webpage.
TheRalphsfoldercontainstherouter.
Logicwillgettoroutersin a littlebit, andit's oneofthekeypartsofourapplication.
GetconvertedtoseparatehtmlpagetheBINthatthedoublingfilecontainstheinitializationscriptforourWebserver, andoneoffthenotablefilesisActUp J.
S.
Thisisthemainentrypointforourentireliveapplication, andalsowehavethepackagethatJasonFile, whichis a recipethatcontainsthelistoffopensourcepackagesweneedtoinstalltorunourapplication.
Theonewe'reinterestedinisthisexpressvariableasyouseetherequirestatementsincludestheexpresspackage, assignsitto a variableandthenlateron, wecalltheconstructorforexpressand a signtheresultsto a variablecalledupandupisaninstanceoffonexpressapplication.
Typically, thisis a vanillainstance, andthenwemakecertainmethodcoalstomodifyandconfigureourapplicationandalsouseandincludeothermodules.
Inthisparticularcase, we'redefininggetmethodandhowtohandlethisslashpathwith a function.
AndthenweexporttherouterinstancethatwehavecreatedtobeincludedbyanothermoduleandactupJsincludesthatrotterhereandthat's howweconnectedandtherouterobjectstorecapis a vanillainstancethatwemakesomemodificationsonitandthenwell, weexportedandthispatternisusedthroughouttheapplication.
Iftherearenoroutesthatmatchfor a givenpathorhttpmethodourapplicationgenerates a 44 error, whichmeansnotfoundsoas a recapunderroutesindexthatJswerecreatinganexpressinstance.
Andthenwe'recallingExpressthatroutertocreate a routerinstanceandonthisrotterweredefiningthatforthehttpgetsmethodIfwearelookingforthepathslashanditgetsmatched, wecallthisfunctionasourhandlerforthisrouteandunderappdotJswehaveindexTrotterrepresentingourexportsfromroutesslashindexfile.
Andthenwehavethisstatementhereatthatuseandfortheslashpathwe'reusingindextractoreffectivelymeaningthatwhenwetypethisroute a pathwithnoslashorslashit, itmeansthesamething.
Oneoftheissueswithourroutehandleristhatthelogicthatmatches a your L patternishere, butalsothehandlerfunction.
ThehandlerlogicitselfisdefinedaspartoftheroomChandler, andwhatwewanttodoisseparatethesetwosothatwehave a modularapproach.
Sowegotoourterminaland I'm goingtocreate a directorycalledControllers.
Controllersessentiallyare a collectionoffroute.
Chandler's.
I'm goingtocopydysfunctionfromhereandplaceitundercontrollersin a newfilesavedhereandgiveit a namecalledIndexandSaveitwiththenameintheextraJs.
Andif I gobacktothecouchdefinedIndexasaninstanceoffwhatwehaveexportedfromourcontroller's indexJsfile, I cannowrefertothehandlerthat I'vedefinedfromthisroutefile.
Soif I gobacktocontrollersas a recap, wehaveanindexofJs, andwehave a methodcalledIndexthatwereexportingasourhandlerandunderourroutes, letlet's savethisfileagainonunderourroutes.
Let's take a closerlookatwhatourcontrollerfunctiondoes, Soifyougoundercontroller's indexofJs, wenamedourfunctionasIndex, andtheonlycallithasisto a coalcalledrezthatrendertheresurrectedERcalledRendersanHTMLpagefrom a template.
Wealsopassthisas a perimetertopug, soifyoulookatindexthatpark, itwillusevariableandreplaceitwithitsvalue.
Therearetwocaseswherethevalueisbeingusedhere.
We'llgettothiswhenwelookat a parkinmoredetail, butessentially, ourcontrollerfunctionsimplyrendersanHTMLpagesrespondswith a HTMLpagebacktotherequestingbrowser.
Nowis a goodtimetouseversioncontrolandcheckingallthefilesthatwehavecreatedbyassumingthatyou'veinstalledgetsand I'm goingtoinitialize a gitrepositoriesherebytypinggetsinit d be.
NowweinitializetherepertoryandyoucancheckthatwehavecreatedTheygotSkidfileinthecurrentdirectorythatstoresallthefilesby R V.
Andifyouhavequestions, youcanclickonthisbuttononthesamepage, become a member, it's free, andthenyouwillbeabletoaddcommentsfortutorialsandgetanswers.
Now, oneoftheproblemswehaveisthateverytimewemake a modificationinoneoffoursourcefiles, weneedtorestartourWebserverbecausethechangesmadetosourcefilesarenotbeingrecognized.
Andinordertoremedythisproblem, there's a toolcallednoDimonthatwe'regoingtoinstall.
So I'm goingtostopourWebserver, and I'm goingtoinstallnomomentbytypingandPMinstallnooldaloneandthenalsotypingsave a dashdeath.
Whatthisdoesisthesafethatwillsavenormalas a developerdependency, meaningthatweonlyneedtoinstallitwhenwearedevelopingourapplication.
SoifwegounderpackagedonJason, wenowseethatNormanis a developerdependency.
Nowis a goodtimetomake a goodcommentsbecausewe'vebeenstolennormal.
So I'm goingtogetatPackagedJasonandthengetcommits.
Dashcam.
Youstillknowmore.
Now I'm goingtocoverthemostcommonapplicationdevelopmentbetterwherewearegoingtobuild a landingpagewithvariousroutestocollectsalesleads, managethem, viewthem, deletethemandlet's goaheadandrenamethevariableindexaslending.
Nowwhenwefixthisfile, we'regoingtodisplay a formwhereif a visitorlikesourservice, whereourvalueproposition, theywillentertheiremailaddressandsendusthatinformationin A So I gounderviews, landingthepuck, andrightbelowthisparagraph, I'm goingtodesigned a fourofftheformelementtakesoneperimetercalledtheaction.
Sowe'reinterestedinusingthepostman, and I'm goingtodefineimprovedelementsofftypeemail, andwe'regoingtouse a placeholderthat's righthere.
Enteryouremailaddress.
Noticehowthereisanindentationhere.
Pugnestshtmlelementsbyusingindentationsoinsideformwehavenestedoninput, andalso, typically, wewanttonest a buttoninside a formsothatthebuttonisassociatingwiththatfor, so I'm goingtodefine a bottomelementsofftypeSubmitwhenthisis a submitbuttonthatindicatesthatwe'regoingtosubmittheformthatthebottomisnestedin.
We'regoingtouse a nameforthebuttoncalledsubmits, and I'm goingtonowsavethisform.
Let's makesureallofthefilesaresaved.
Andif I nowrestartmyapplication, I shouldseetheformbeingservedbythecenterhere.
Right?
Sowehavethisinternalemailaddressformwithaninputandthen a summit.
Sowe'regoingtoinstall a databaseSQLdatabaseparticularPostgraceforourapplication.
Goaheadandopenupyourbrowserandtypeofhomebrew.
HomeBrewis a packagemanagerforMacOS, andoneoffthepackagesmaintainedisthePostRescue L package, soyoucancopyandpastethisinstallationscriptonyourterminal.
Ifyou'reon a questtoinstallHomebrew, let's goaheadandjustdothat.
Andit's goingtoinstall a commandlinetoolcalledBrew, whichwillallowyoutotheninstallveryspecages, including a postrescue.
Now I haveitalreadyinstalled, so I'm goingtoskipthisstep.
Assumingyouhavestolethis, wecantheninstallpostdressbytypingbrewstallpostrescue L Soafteryou'vedonethat, youcanstartyourdatabasebytypingbrewService's startsPostgracequeWell, thisisgoingtostartsteeples.
Thiswillinstallseekalliesas a package I recommenddoingthatstashissafesothatit's safetoourpackage.
JasonFILE.
We'realsointerestedinthedatabasedriverlibraryinKnowJsforPostRescueEarl, whichissimplycalledPG, So I'm goingtogoaheadandtypeMPMinstall P g DashDashSaveaswell.
SeeEqualized.
WillinvokePGinordertoaccessthePostGradSchool.
AlDavisThisis a lowlevellibraryforaccessingPostGradschooldatabases.
Theothertoolsthatweneedis a commonlinetoforceequalizecalledsequelae.
See, ELISA, I'm workingstolethataswell.
Bytyping, MPMstolesequeleyesthatcliand I'm goingtouseDash G sothatCokeloseourinstallationformostpressing, C equalized.
Solet's goaheadintoourtexteditorandcreates a newboulder, holdsmigrationsandlet's create a newvialundermodelsdirectorynamedleadTheJssincewerecollectingsalesleads.
OurtableandmodelwillbenamedLeedsMigrations.
Allowustocreaterecipestotakeourdatabasestatesthedatabasedefinitionfrompoint A toPoint B, forexample.
And, incontrast, migrationsareusedformanipulatingthedatabasetabledefinitionsthemselves, suchascreating a table, adding a newcolumnorchangingthetypeofftheColeLiaminthattable.
Seekrelieshassolittlemethodsforaccessingandmanyplating a postChriscomeoutdatabase.
Butthemigrationitselfisfile a recipethat's specifictoequalize, andsoisthemodelthatwe'regoingtodefine.
Solet's goaheadandcreates a newmigrationfile.
Andlet's defineourfirsttable.
I'm goingtocopyandpastethiscodethat I havealreadypreparedasourfirstmigration.
Let's firstsavethisfile.
Migrationsare a sequentialinthesensethattheyneedtoberuninorder.
Theydon't makesenseiftheyaroundwithoutanorder.
Soweneedtoorderthembythefilename.
Andwedothatbyincluding a date, startingwiththeyearamongandthehourandeventheminuteswhenthemigrationiscreated.
Soasofnow, we'reinJanuary 4th 2019.
So I'm goingtonamemymigrationas 2019 0104 andthenthehouris 1917 and I'm goingtoincludetheactionthatthismigrationisgoingtotake, whichiscreating a table.
Nameslead, socreateleadstable, andthey'refinallythat's a Js.
Hereisourfirstmigrationsaved, andthemigrationsarebidirectional, soyoucanapply a migrationrepresentedbytheupmethods, andthenyoucanrollback a migrationbyusing a downmethod.
Sointhiscase, theupmethodstandsforcreating a newtableColdleadswithsoandsofields, andthenthedownmethodsoractionrepresents.
Wejustranfortheleadstable, andweomittedthecreatorthatupdatedthatfieldsinthemodelbecause, see, equalizedassumestheyalwaysexist.
Whenweruntheapplication.
SecretallieswillrunmodelsindexdotJsIfyouwillgetthisforeachsection, itwillgoovereachmodeldefinitionundertheModelsdirectorytoimportanduseforaccessingtherespectivedatabaseThingsundermodelsdirectoryforeachdayof a stableredefine a modelsuchastheonewecreatedforleaderJsforleadstableandsequelEyeswillgoovereachofthosetogeneratethemethodssothatitcanaccessthosetables.
And I'm goingtolifereturnmodelsthatleadthatcreates.
Notthatcreateis a sequel.
Eyesmethodsfortheemailfield.
We'regoingtousethevaluerevoltingfromwreckbodyleads e mail, thentaketheresultsandredirectbacktothelandingstageandletshiselitethislastlineofthefirstlinesafeandrerunourapplication.
If I gobacktothelandingpagetypeofemailaddressyearisrunningatgmaildotcomandsubmitnoticethatthebrowserreloadedthelandingpatient.
We'reinserting a newrollintotheleaguestable, particularly I'd emailcreatedthatupdatedthatFieldsknew a unique I d fortheroleandthentheemailaddresswejustsubmittedandthenthedates.
A fewthingstoknowthisColehereis a promiseWe'regonnacoverpromisesindetaillater.
Butfornow, whatyouneedtoknowisthatthiscallisgoingtoexecute a synchronously, andthethenhereensuresthattheresultswithinthisbodyareavailableaftertheexecutionoffthisColehascompleted.
Sothere's a guaranteethatthisbodyisgoingtobeavailableafterthisexecution.
Eventhoughthecoalis a synchronous, we'llgettothoselater.
That's nameitasshowlead, andwhatweneedtodonowisquerythedatabasefor a leagueswith a given I D.
So I needtodoreturnmodels.
That's leadfindsone.
Andthenthewearclausehelpsusqueryfor a particularfeeling.
We'regoingtousetheideaFields, andwe'regoingtopasstherequestperimeterthatwereceivednamedaslead I d tofindtheparticulartheleadrecordinthedatabasecorrespondingtoeourleads?
Let's defineon H oneleadHeatherandlet's simplydefine a paragraphwiththeleadinformation.
Leavetheemail.
NowLet's gotolandingthatpark.
Wewanttogivetheuserandopportunitytoclickon a linkthattakesustotheindividualdetailspageforthatlink, andwedon't havethatleakhere, so I'm goingtoaddthattothisparagraph.
But I wouldliketodisplayboththeleadsemailandalsothatlinkon a singlelinethesamelife.
So I'm goingtonestthelinkandthe E mailunderthesameparagraphas a reminder.
WenestHTMLelementswithindentationinpug, so I'm goingtofirstdefineundertheparagraph a spendelementsthatwilldisplayouremail.
So I'm goingtoincludeonespacecharacteranddefineourlinkwiththeankletagwithan H refpropertyoffslashleadslashAndnowhereWealreadyhaveaccesstotheleadobjectthathasbeenobtainedfromthedatabasesowecanincludetheideaofftheleadherebytypingleadthat I D.