angularjs web application development blueprints1.droppdf.com › files › kezln ›...

496

Upload: others

Post on 04-Jul-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

  • AngularJSWebApplicationDevelopmentBlueprints

  • TableofContents

    AngularJSWebApplicationDevelopmentBlueprints

    Credits

    AbouttheAuthor

    AbouttheReviewers

    www.PacktPub.com

    Supportfiles,eBooks,discountoffers,andmore

    Whysubscribe?

    FreeaccessforPacktaccountholders

    Preface

    AboutJavaScriptMVCframeworks

    HowAngularJSwasborn

    Theideabehindthisbook

    Whatthisbookcovers

    Whatyouneedforthisbook

    Softwareversions

    Copyingthecodefiles

    Whothisbookisfor

    Conventions

    Readerfeedback

    Customersupport

    Downloadingtheexamplecode

    Errata

    Piracy

    Questions

    1.IntroductiontoAngularJSandtheSinglePageApplication

    DelvingintoSinglePageApps

    AnatomyofasimpleAngularJSapp

    Modelsandviews

    BuildinganAddressBookApp

  • UnderstandingthescopeinAngularJS

    Stylingtheapp

    Sortingthecontactsalphabetically

    AddingcontactstotheAddressBook

    Theng-showandng-hidedirectives

    Summary

    2.SettingUpYourRig

    SettingupNode.js

    CreatingasimpleNode.jswebserverwithExpressJS

    SettingupGrunt

    InstallingGrunt-cli

    Creatingthepackage.jsonfile

    CreatingyourGrunttasks

    Grunttaskstomergeandconcatenatefiles

    RunningshellcommandsviaGrunt

    Yeoman–theworkflowtool

    InstallingYeoman

    Runningyourapp

    UnittestingwithKarma

    UsingProtractorforEnd-to-Endtests

    InstallingSeleniumServer

    Understandingtheexample_spec.jsfile

    Understandingtheconf.jsfile

    WritingyourownProtractortestcases

    Summary

    3.RapidPrototypingwithAngularJS

    UnderstandingtheapplicationthatwewillPrototype

    IntroducingGridLayoutsandBootstrap

    Understandingthegridsystem

    IntroducingAngularUI

    UI-Utils

  • UI-Modules

    UI-Bootstrap

    NG-Grid

    UI-Router

    IDEPlugins

    PrototypingtheHealthyLivingwebsite

    Addingtheui.bootstrapdependency

    Creatingthenavigationbar

    Addingthecarousel

    Tweakingtheherounit

    Addingthethreecontentblocks

    Creatinganewview

    Understandingroutes

    Buildingthearticlesview

    AccordionsusingAngularBootstrap

    Buildingtheimagegallery

    GalleryviewusingBootstrapThumbnail

    Addingthestarrating

    BuildingdatagridsusingNG-Grid

    AddingtheNG-Gridcomponent

    GroupingdatainNG-Grid

    Excel-styleeditinginNG-Grid

    Creatingamodalwindowtoaddsubscribers

    Real-timeformvalidations

    Summary

    4.UsingRESTWebServicesinYourAngularJSApp

    UnderstandingtheresponsefromaRESTAPI

    TestingaRESTfulwebservice

    JumpstartingyourappdevelopmentwithAngularSeed

    FilesandfoldersinAngularSeed

    AddingBootstraplibraries

  • StartingyourNodewebserver

    Mark-upourLayout

    Creatingtheroutes

    UnderstandingAngularJSservices

    Writingyourfirstfactoryservice

    DependencyInjection

    Codingthepartial

    CallingtheRESTwebserviceusing$http

    Usingpromiseforasynchronouscalls

    DisplayingdatafromtheJSONresponse

    Unittestingourapplication

    Mocking$httpduringUnittesting

    CreatingaPintereststylelayout

    Addingactionstothebuttons

    Summary

    5.FacebookFriends’BirthdayReminderApp

    UnderstandingtheFacebookSDK

    TheSocialGraph

    TheGraphAPI

    TheGraphAPIExplorer

    CreatingyourFacebookapp

    Settingupourproject

    Runningyourapplication

    DelvingintoAngularJSdirectives

    Whatisadirective?

    Importanceofnamingconventionsfordirectives

    Theanatomyofadirective

    Writingourfirstdirective

    AddingaFacebooklogin

    Addingthefb-rootdivelement

    LoadingtheFacebookSDK

  • Understanding$watchand$digest

    Whentouse$apply

    Gettingtheuser’sfriendlist

    Gettingyourfriends’profilepicturesandbirthdays

    RequestingadditionalpermissionwithFB.login

    Understandingisolatedscope

    AddingsomeCSSstyles

    Changingtheroutes

    Addinginthelogoutlink

    Writingautomatedtests

    WritingUnittestswithKarma

    WritingEnd-to-EndtestsusingProtractor

    Summary

    6.BuildinganExpenseManagerMobileApp

    UnderstandingHTML5WebStorage

    localStorage

    sessionStorage

    BuildingtheExpenseManagerApp

    BuildingtheAddExpenseform

    Whatis$rootScope?

    Understandingthe.runblock

    CreatingavalueservicetostoreCategoryList

    ValidatingtheAddExpenseform

    UsinglocalStoragetosavedata

    BuildingabarchartdirectivebasedonD3

    Summarizingtheexpensesbycategories

    Creatingourbarchartdirective

    Makingtheappresponsive

    AddingtheCSSmediaquery

    ScalingtheD3chartbasedonwindowsize

    Addingtouchevents

  • EnablingswipegesturesusingngTouch

    AddingpagetransitionsusingngAnimate

    LoadingthengAnimatemodule

    AddingCSS3transitions

    Makingtheappfeellikeanativeapp

    Addingtouchicons

    Runningtheappinfullscreenmode

    Addingadditionalfeatures

    Summary

    7.BuildingaCMSontheMEANStack

    WhytheMEANstack?

    GettingstartedwiththeMEANstack

    SettingupMongoDB

    SettingupExpressJSandMongooseJS

    Buildingtheserver-sideapp

    CreatingtheMongooseschemas

    CreatingCRUDroutes

    Addinganewentrytothecollection

    Updatingacollection

    Deletingacollectionitem

    Displayingasinglerecord

    Securingyouradminsection

    Usingbcrypttoencryptpasswords

    Addinganewadminuser

    Creatingtherouteforauthenticatinglogin

    Creatingthelogoutroute

    WritingthesessionCheckmiddleware

    IntegratingAngularJSwithanExpressJSproject

    GeneratingSEO-friendlyURLsusingHTML5mode

    BuildingtheadminsectionforCRUDoperations

    Creatingtheroutesfortheadminsection

  • Buildingthefactoryservices

    Buildingthecontrollersfortheadminsection

    Settinguptheadminpagelayout

    Buildingthelistingviewfortheadminsection

    SettingupauthenticationinAngularJS

    Creatingourloginpage

    Buildingacustommoduleforglobalnotification

    Buildingandinitializingthemessage.flashmodule

    Buildingthemessage.flashfactoryservice

    Settingup$broadcasts

    Buildingthedirectiveforthemessage.flashmodule

    Settingaflashmessage

    CreatingourAdd-Editpagecontroller

    CreatingourAdd-Editview

    WritingacustomfiltertoautogeneratetheURLfield

    AddingtheWYSIWYGeditor

    SettingupanInterceptortodetectresponses

    BuildingthefrontendofourCMS

    Buildingournavigationbardirective

    Buildingtheadmin-logindirective

    Displayingthecontentofapage

    Settingthedefaulthomepage

    Summary

    8.ScalableArchitectureforDeploymentsonAWS

    UnderstandingthevariousservicesinAmazonAWS

    DelvingintoAWSdeploymentarchitectures

    TheEC2server-basedarchitecture

    TheServer-lessArchitecture

    DeployingourappinaServer-lessArchitectureonAWS

    MappingadomaintoS3

    MappingtheS3buckettoaCloudFrontdistribution

  • Gettingyourappreadyforproductiondeployment

    Improvingthepage-loadtimeofyourapp

    SettingExpiresheaders

    Performance

    Summary

    9.BuildinganE-CommerceStore

    BackendasaService

    BuildingaBaaSplatformonAWS

    SettingupanS3Bucketwithpublicreadaccess

    SettinguptheCORSpolicyonyourS3bucket

    CreatingourDynamoDBtables

    CreatingtheIdentityandAccessManagement(IAM)role

    Creatingoure-commerceapp

    BuildingnestedviewsusingUI-Router

    MappingstatestoURL,views,andcontrollers

    Prototypingourapplication

    Settingupourindex.htmlfile

    Creatingthecontrollers

    Creatingtheproductpartials

    Addinganimationstotheviewtransitions

    AddingintheCSStransitioneffects

    Creatingourapplication-levelcontroller

    AddingaFacebooklogin

    IntegratingAWSJSSDKwithourapplication

    CreatingtheAWSserviceprovider

    BuildingourAddProductspage

    SavingdatainDynamoDBtables

    Creatingtheviewfortheaddproductform

    Buildingthecontrollerfortheaddproductsview

    UploadingimagestoS3

    Fetchingtheproductslistsforacategory

  • Usingresolvestopreloaddata

    Creatingourproductdetailspage

    Addingproductstocart

    Thecheckoutpage

    Savingtheorders

    Summary

    A.AngularJSResources

    Officialresources

    RecommendedAngularJSmodules

    Boilerplates

    Learningresources

    GoodfriendswithAngularJS(third-partytoolsandservices)

    Coreteammembersandknowledgeablepeopletofollow

    Index

  • AngularJSWebApplicationDevelopmentBlueprints

  • AngularJSWebApplicationDevelopmentBlueprintsCopyright©2014PacktPublishing

    Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.

    Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.

    PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.

    Firstpublished:August2014

    Productionreference:1180814

    PublishedbyPacktPublishingLtd.

    LiveryPlace

    35LiveryStreet

    BirminghamB32PB,UK.

    ISBN978-1-78328-561-7

    www.packtpub.com

    CoverimagebyFaizFattohi()

    http://www.packtpub.commailto:[email protected]

  • CreditsAuthor

    VinciRufus

    Reviewers

    JeffCunningham

    AshutoshDas

    AJKerrigan

    CiroNunes

    YacineRezgui

    CommissioningEditor

    AkramHussain

    AcquisitionEditor

    RichardHarvey

    ContentDevelopmentEditor

    VaibhavPawar

    TechnicalEditors

    ShashankDesai

    MenzaMathew

    CopyEditors

    KarunaNarayanan

    AlfidaPaiva

    LaxmiSubramanian

    ProjectCoordinators

    BinnyK.Babu

    KrantiBerde

    Proofreaders

    BridgetBraund

    PaulHindle

    LucyRowland

    Indexers

    HemanginiBari

  • MariammalChettiyar

    RekhaNair

    PriyaSubramani

    Graphics

    ValentinaD’silva

    ProductionCoordinator

    AparnaBhagat

    CoverWork

    AparnaBhagat

  • AbouttheAuthorVinciRufushasbeenworkingwithfrontendtechnologiesforcloseto14yearsnow.HestartedhiscareerbuildinggameswithFlashActionScriptandlatermovedontoJavaScriptandHTML5.Duringhissparetime,heenjoysconductingworkshopsandtrainingpeople.

    Foraliving,hementors,guides,andhelpsgrowthetechnologyteamatRazorfishNeev,primarilyintheareaofcommerce,usability,andemergingtechnologies.

    AsincerethankstotheawesometeamatRazorfishNeev.I’velearnedsomuchworkingwithyouall.

    Mydeepestregardstothetechnicalreviewers,JeffCunningham,AshutoshDas,AJKerrigan,CiroNunes,andYacineRezgui,andalsotothecontentdevelopmenteditor,VaibhavPawar,whoseinsightsandfeedbackgreatlyhelpedinaddingthefinishingtouchesforthisbook.

    Abigthankyoutomyfamily;mydad,Rufus,wholearnedcomputersonlysothathecouldteachme;mymom,Anne,whohasalwaysencouragedmetotakeupchallengeseverytimeIthoughtitwasn’tpossible;myawesomekids,ShannonandJaden,whosacrificedalotoftheirplaytimesothatIcouldwritethisbook;mywife,Raina,forallthesupportthatwasinstrumentalinthisbookreachingitscompletion;andfinally,mysister,Blaisy,whowasalwaystheretogivefeedbackandcritiquemywork,andwithwhomIcouldbrainstormanddiscussideas.

  • AbouttheReviewersJeffCunninghamisamobileappdeveloperatComdatainNashville,TN.After15yearsofworkinginthefieldofJavawebdevelopment,henowenjoysthechallengesoffrontendandmobiledevelopment.Healsoreviewedthebook,AngularJSDirectives,PacktPublishing,andmaintainsthepopularreponamedAngularJS-LearningonGitHub(https://github.com/jmcunningham/AngularJS-Learning).

    AshutoshDas,whohailsfromBangladesh,worksmainlyasabackenddeveloperandhisexperienceincludesworkingwithDjango,Node.js,Laravel,andsoon.HealsolikestoworkwithAngularJS.HespendshissparetimewritingforGitHub.Healsoworksasafreelancerandisapart-timejobholder.Heiscurrentlyintheprocessofreviewingthebook,AngularJSUIDevelopment,PacktPublishing.

    AJKerriganisasystemsanalystwithasmallITdepartmentinNewJersey.Histechnicaldutiesandinterestsincludeserveranddatabaseadministration,command-linescripting,andwebdevelopment.

    AngularJSWebApplicationDevelopmentBlueprints,PacktPublishing,representsAJ’sfirstexperienceasatechnicalreviewer.

    Iwouldliketothankmywife,daughter,anddogfortheirlove,support,andendlesssupplyofhugs.Thankstomyfatheraswell,whoprovidedmewithmyfirstexposuretoprogramming(BASIConthefamilyTI-99/4acomputer).Hehasbeenaconsistentsourceofencouragementandguidance.

    CiroNunesisa22-yearoldfrontendengineer,test-firstevangelist,andspecialistinlarge-scalearchitecturesforheavyclient-sideapplications.Atsuchayoungage,hehasbeenresponsibleforthedevelopmentofthebiggeste-commercewebsitesfromLatinAmerica.He’salsotheorganizeroftheAngularJSSPMeetupwhichhasmorethan400members.

    Nowadays,he’sworkingonapplicationsforthefinancialmarketthatpushestheboundariesofAngularJS.

    Iwanttothankmyfamilyandfriendsfortheirpatience,withmebeingsoabsentlately.IpromisethatI’mgoingtowalkmorewiththedogandspendmoretimewithyouwhomIlove.

    YacineRezguiisaFrench-Tunisianwebdeveloper.Hestartedwebdevelopingattheageof12,andsincethen,hasmadehispassionhisjob.He’sspecializedinwebdevelopmentandstronglybelievesthatitisthebestcross-platformenvironment.He’scurrentlytheorganizeroftheLondonPhonegapMeetup.

    HeworkedindifferentcompaniessuchasMédiamétrieeStat,TequilaRapido,andGovernorHubasafreelancer.

    Iwouldliketothankmyfriends,JamesNocentini,JamesSharp,CédricFerretti,andXavierKressforsupportingmeonmywork,myfamilyforalltheirencouragement,andXuxuforhelpingmetofocus.

    https://github.com/jmcunningham/AngularJS-Learning

  • www.PacktPub.com

  • Supportfiles,eBooks,discountoffers,andmoreYoumightwanttovisitwww.PacktPub.comforsupportfilesanddownloadsrelatedtoyourbook.

    DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusatformoredetails.

    Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.

    http://PacktLib.PacktPub.com

    DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcanaccess,readandsearchacrossPackt’sentirelibraryofbooks.

    http://www.PacktPub.comhttp://www.PacktPub.commailto:[email protected]://www.PacktPub.comhttp://PacktLib.PacktPub.com

  • Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,printandbookmarkcontentOndemandandaccessibleviawebbrowser

  • FreeaccessforPacktaccountholdersIfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccessPacktLibtodayandviewnineentirelyfreebooks.Simplyuseyourlogincredentialsforimmediateaccess.

    http://www.PacktPub.com

  • PrefaceThemostannoyingpartofusinganywebsiteorwebapplicationisthetimewewaitforpagestoload.Sure,everybodyisworkingonmakingtheWebfast,butthose2-3secondsthatittakesforaroundtriptotheserverdoesnotstopyoufromopeningmultipletabsandoftenforgettingwhichtabyouoriginallywereon.

    TherapidpopularityofJavaScriptframeworksandtechnologiessuchasAJAXclearlyshowthedesperateneedtosavethose1or2,second-roundtripstotheserver,andprovidetheuserswithamoredesktop-likeuserexperience.

  • AboutJavaScriptMVCframeworksTheseJavaScriptframeworksaren’tsomenewrevolutionarytechnologyoranewdiscovery;theyareallstillusingthesameoldfaithfulJavaScript.TheseJavaScriptframeworksmerelyprovidealayerofabstraction(ifImay)oramoreModel-View-Controller-likearchitecture,sothatwecanbemoreproductivewhilebuildingappsanddon’treallyhavetoworryaboutmundanethings.

    ThecreditfortherisingpopularityoftheseJavaScriptframeworkswouldgotothissurgeofJavaScript-basedhighlyinteractiveandrichInternetapplicationsthatnowadaysdosomuchmorethanjustdisplayingdatareceivedfromabackendserver.AllofthisispossiblethankstothemoderndaybrowserandtheirJavaScriptenginesthathavebecomefasterandpowerful.

    TherehasnearlybeenanexplosionoftheseJavaScriptMVCframeworks,andeveryotherday,weseeanewframeworkbeinglaunched.WhilemostpeopleconsiderBackbone.jsorSproutCoretobeoneofthefirstJavaScriptframeworks,IwouldsayExtJSbySenchahasbeenamongthefirstJavaScriptframeworksandonethatisstillbeingextensivelyusedinthecorporateworldmainlytobuildfinanceapps.WhileBackbone.jsandSproutCorewerelaunchedin2010,Version2.0ofExtJSwaslaunchedtowardstheendof2007.

    AngularJStoowaslaunchedsomewherein2010.Aroundthesametime,otherJavaScriptframeworksweresproutingup.However,itisprobablythefastestgrowingframeworkintermsofuseradoption,mainlyduetothe“wow”factorandalsothebackingfromthebigG.

    Eachframeworkhasitsownprosandcons,andideallythechoiceoftheframeworkwoulddependonthenatureofyourproject.

    Notehttp://www.todomvc.com/isaverynicesitetounderstandandcomparethefunctioningoftheseJavaScriptframeworks.

    AngularJSiscurrentlythemostpopularJavaScriptMVCframework.Someofthereasonsforthiswouldbeasfollows:

    It’samongthesimplesttolearnItfollowssomeofthebestsoftware-engineeringconcepts,andisidealtobuildlarge,scalableappsIthasarobusttestingframeworktorunUnittestsandEnd-to-Endtests,thusmakingiteasytowriteandrunautomatedtestcasesItalsoallowsforteamstoworkinparallelonasingleapplicationwithoutsteppingovereachother’sworkIthasthefastestgrowingcommunityofadaptors,andtheAngularJSGoogleGroupsandIRCchatsareagreatplacetointeractwithothers

    http://www.todomvc.com/

  • HowAngularJSwasbornAngularJSstartedasaninternalGoogleprojectbyMiskoHevery,sometimein2009.Asthestorygoes,Misko’steamwasworkingonaprojectcalledGoogleFeedback;evenaftersixmonthsofdevelopmentandabout17,000linesofcode,theywerestillunhappywiththepaceofdevelopmentandtheinabilitytowriteautomatedtests.That’swhenMiskodecidedtorewritethat.Ittookhimabout3weeksandhemanagedtowritethewholethinginjustabout1,500linesofcode.

    That’swhenAngularJSgotsomeseriousattentioninternallyatGoogle,andateamwasputtogethertohelpfurtherdevelopit.Around2010,GoogledecidedtodeclareitasopensourceundertheMITlicense.

  • TheideabehindthisbookTheideabehindwritingthisbookistoshowcasethedifferenttypesofapplicationsthatcanbebuiltonAngularJS.BesidesexplainingAngularJSandhowtowritemodularandtestablecode,thereisafairamountofemphasisonmakingthoseappslookbeautiful.So,bereadyforsomeCSSstuffanddesign-relateddiscussions.

    I’vetriedtocoveravarietyofapplicationsrangingfromasimpleaddressbook,anHTML5mobileapp,ane-commercestore,aCMSframework,andalsoideasonhowtodeployappsonAmazonAWS.

  • WhatthisbookcoversThisbookisbrokendownintoninechapters.

    Chapter1,IntroductiontoAngularJSandtheSinglePageApplication,talksabouttheconceptofaSinglePageAppandhowtheyaredifferentfromtheregularwebapps.We’llalsolearnaboutthebasicsofAngularJSbybuildingasimpleAddressBookApp.

    Chapter2,SettingUpYourRig,talksabouthowhavingtherightsetoftoolscanbeahugeproductivitybooster.ItalsomakesyoufeellikeaprowhenbuildingyourAngularJSapp.ThischapterwilltalkaboutsomeofthetoolssuchasNode.js,ExpressJS,Grunt,Yeoman,andKarma.

    Chapter3,RapidPrototypingwithAngularJS,talksabouttheeasewithwhichonecancreateclickableprototypestogetafeelofhowanapplicationwouldlookandfeelbeforeworkingonanybackendcode.

    Chapter4,UsingRESTWebServicesinYourAngularJSApp,willshowyouhowtoconsumedatafromthird-partyRESTwebservicesusingfactoriesandthe$httpservice.

    Chapter5,FacebookFriends’BirthdayReminderApp,willexplaindirectivesandhowwecancreateourFacebooklogindirective.Wewillalsosetupsomeautomatedteststoensureeverythingisworkingfine.

    Chapter6,BuildinganExpenseManagerMobileApp,willwalkyouthroughtheprocessofbuildingaresponsiveandtouch-friendlymobileappusingngAnimateandHTML5featuressuchaslocalStorage.

    Chapter7,BuildingaCMSontheMEANStack,talksabouthowtosetupanentirebackendandfrontendsystemandhowAngularJSinteractswithanodeserverandMongoDBdatabase.Wewillalsolookatsessionmanagementandinterceptors.

    Chapter8,ScalableArchitectureforDeploymentsonAWS,willteachyouaboutAWSanditsvariousservices,andhowwecandeployourappinaServer-lessArchitecturethatcaninherentlyscale.

    Chapter9,BuildinganE-CommerceStore,willshowyouhowtodirectlyreadandwritedatafromAWS’sDynamoDBdatabase,anduploadimagestoS3directlyfromourJavaScriptapp.

    Appendix,AngularJSResources.Well,youknowwhattoexpecthere.

  • WhatyouneedforthisbookYouobviouslydon’tneedtoreadtheentirebookbeforeyoucanstartworkingonyourfirstAngularJSproject.I’mafirmbelieveroflearningthingsthepracticalway,andthat’swhyfromtheveryfirstchapter,youwillfindyourselffiringupyourIDE/Texteditor,andwritingcodeandtestingitonyourbrowser.

    WhileyouwilllearnacoupleofnewfeaturesofAngularJSineachofthechapters,eachchapterisstillself-contained,andyoucancomfortablyjumptoanyofthechaptersthatinterestyouorthatyouneedtorefertoforyourproject.

    However,ifyouarejuststartingoffwithAngularJS,thenIstronglyrecommendthatyoureadthroughthefirstthreechaptersbeforeyoustartjumping.

  • SoftwareversionsThecurrentstableversionofAngularJSwhilewritingthisbookis1.2,andunlessspecified,wewillbeusingthestableversionof1.2.17foralltheexamplesinthisbook.

    YoucangetthelatestversionofAngularJSusinganyofthefollowingmethods:

    Downloadthecompiledminifiedversionfromhttp://www.angularjs.org.ForkorclonethesourcecodefromtheGitHubURLhttps://github.com/angular/angular.js.TherecommendedoptionforbothdevelopmentandproductioncodeistocalltheAngularJSfiledirectlyfromtheGoogleCDN.ThelinktotheAngularJSsectionontheCDNishttps://developers.google.com/speed/libraries/devguide#angularjs.

    http://www.angularjs.orghttps://github.com/angular/angular.jshttps://developers.google.com/speed/libraries/devguide#angularjs

  • CopyingthecodefilesThecodeexamplesmentionedinthisbookcanbeusedinyourprograms.However,ifyouchoosetoburnthemontoCDsforredistributionorareputtingupthecodeexamplesfordownloads,youarerequiredtogetexplicitpermissionfromPacktPublishing.

  • WhothisbookisforThisbookismainlyaimedatprofessionals,bothdesignersandprogrammers.Thankfully,AngularJSisevolvingtobeaframeworkwherebothdesignersandprogrammersworktogetherwithoutdiscriminatingeachotherasbackenddevelopersorfrontenddesigners.

    ThebookobviouslyassumesthatyouknowyourbasicsinHTML,CSS,andJavaScript.Youunderstandtheimportanceandneedforwritingmodular,scalable,testable,andgood-lookingapplications.Youdon’tneedtohaveworkedwithAngularJSoranyotherJavaScriptframeworktounderstandthetopicscovered.ThebookassumesyoujustmetAngularJSonablinddate.

    ThebookstartsoffwithgettingyoucomfortablewiththebasicconceptsthatyoucomeacrossveryoftenwhileworkingwithAngularJS.We’llwritesomesimplecodejusttoseehowAngularJSworks,understandingitbetter,andthenwe’llgraduatetowritingcleanerandmodularcode.

    Also,Ihaveachapterdedicatedtosettingupyourdevelopment“rig”withasetoftoolsandpluginsthatwillhelpyouboostyourproductivitywhilebuildingAngularJSapps.

  • ConventionsInthisbook,youwillfindanumberofstylesoftextthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestyles,andanexplanationoftheirmeaning.

    Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“Now,angular-bootstrapwillbeavailableforuseacrossourapplication.”

    Ablockofcodeissetasfollows:

    Whenwewishtodrawyourattentiontoaparticularpartofacodeblock,therelevantlinesoritemsaresetinbold:

    {{myName}}is{{2014-1968}}yearsold.

    Anycommand-lineinputoroutputiswrittenasfollows:

    yoangular:routesubscribers

    Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,inmenusordialogboxesforexample,appearinthetextlikethis:“ClickontheDownloadbuttonandselectthefollowingoptionsfromthepop-upwindow:”

    NoteWarningsorimportantnotesappearinaboxlikethis.

    TipTipsandtricksappearlikethis.

  • ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedormayhavedisliked.Readerfeedbackisimportantforustodeveloptitlesthatyoureallygetthemostoutof.

    Tosendusgeneralfeedback,simplysendane-mailto,andmentionthebooktitleviathesubjectofyourmessage.

    Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideonwww.packtpub.com/authors.

    mailto:[email protected]://www.packtpub.com/authors

  • CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.

  • DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesforallPacktbooksyouhavepurchasedfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.

    http://www.packtpub.comhttp://www.packtpub.com/support

  • ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyouwouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheerratasubmissionformlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedonourwebsite,oraddedtoanylistofexistingerrata,undertheErratasectionofthattitle.Anyexistingerratacanbeviewedbyselectingyourtitlefromhttp://www.packtpub.com/support.

    http://www.packtpub.com/submit-erratahttp://www.packtpub.com/support

  • PiracyPiracyofcopyrightmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.Ifyoucomeacrossanyillegalcopiesofourworks,inanyform,ontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.

    Pleasecontactusatwithalinktothesuspectedpiratedmaterial.

    Weappreciateyourhelpinprotectingourauthors,andourabilitytobringyouvaluablecontent.

    mailto:[email protected]

  • QuestionsYoucancontactusatifyouarehavingaproblemwithanyaspectofthebook,andwewilldoourbesttoaddressit.

    mailto:[email protected]

  • Chapter1.IntroductiontoAngularJSandtheSinglePageApplicationInthischapter,we’lllearnwhatSinglePageAppsareandhowtheydifferfromtheregularwebapplications.WewillalsolearnthefundamentalsofAngularJSandgoaboutbuildingasimpleAddressBookAppusingit.

    Thelistoftopicstobecoveredinthechapterareasfollows:

    WhatareSinglePageApps?AnatomyofanappModelsandviewsBuildinganAddressBookAppStylingtheappwithCSSAddingitemstotheAddressBook

  • DelvingintoSinglePageAppsBesidesotherthings,AngularJSisprimarilyusedtobuildSinglePageApps(SPAs),soletusfirstunderstanditscharacteristics.

    SinglePageAppsareappsorwebsiteswhereintheentiresiteorappcontentloadswithinasinglepage.Thisessentiallymeansthatoncetheapporwebsiteisloadedinthebrowser,clickingonanylinkwouldnotreloadtheentirepagebutwouldsimplyupdatecertainsectionswithinthemainpageitself.Thisgivesusersaverydesktop-likefeelwhileusinganSPA.

    AlthoughSPAshavebecomeverypopularnowadays,theconcepthasbeendiscussedasearlyas2003,andthetermSinglePageAppwascoinedin2005.

    SomeofthetechnologiesthatplayapredominantroleinbuildingSPAsareHTML,CSS,JavaScript,AJAX,andwebservicesusuallyRESTful.Ofthese,JavaScriptplaysthemostcrucialroleinbuildinganSPA,soifyouhavebeenprocrastinatingonsharpeningyourJavaScriptskillsthiswouldbethebesttimetogetupandgetstarted.

    OneofthefundamentaldifferencesinthewaySPAsworkagainstregularwebsitesisthewaythepagesarebuilt,whichtheusersees.Refertothefollowingdiagram:

  • Intraditionalwebapplicationsthatarebuiltontheserver-sidetechnologiessuchasJava,PHP,and.NET,wheneverapageisrequested,thewebserverwouldmakearequesttothedatabase,fetchtheresultofthequery,thenloadthetemplate,anddynamicallygeneratethefinalpage,whichissentdowntothebrowser.Asyoucanseehere,thewebserverisdoingalltheheavylifting,andasthetraffictotheserverincreases,thewebserverbecomesabottleneck.Thisiswhypopularhigh-trafficsitesneedalotofservers.

    SinglePageApps,especiallythosebuiltonJavaScriptframeworkssuchasAngularJSworkinaslightlydifferentfashion.Refertothefollowingdiagram:

    InanSPAarchitecture,theentiretemplatealongwiththeHTML,JavaScript,andCSSisdownloadedtotheuser’sbrowser,sowhenarequestismade,contentissentfromthewebserverandthepageisbuiltontheclientsideontheuser’sbrowser.Here,thebrowserisdoingtheheavylifting.Insuchanarchitecture,thewebserverismerelypassingrawdataandisnotinvolvedinbuildingthepages.Thepagesarebuiltoneachuser’sbrowserandhenceevenifthetraffictothesiteincreases,theserverdoesn’tgetoverloaded,asitwouldhaveinaregularwebapparchitecture.

    AnotherthingthatmakesSPAswonderfulisthatthepresentationlayercanbecompletelydecoupledfromthebackendlayer.

  • AnatomyofasimpleAngularJSappPerformthefollowingsteps:

    1. Tostart,let’sfirstdownloadaversionofAngularJSfromhttp:www.angularjs.org.2. ClickontheDownloadbuttonandselectthefollowingoptionsfromthepop-up

    window:

    Branch:SelectStableBuild:SelectMinified

    3. DownloadtheJSfileandplaceitinyourproject’sfolder.

    LetusstartbywritingasimpleAngularJSapp.Createanindex.htmlfilewiththefollowingcode:

    AngularJSBasic

    {{myName}}is{{2014-1968}}yearsold.

    ThisisaregularHTMLpagewiththeHTML5doctypeandtheAngularJSJavaScriptfilebeingcalledin.Now,letuslookatspecificsyntaxesofAngularJSandwhattheymean.Thesyntaxesareasfollows:

    ng-app:ThisdefinestheelementwithinwhichAngularJSwillbootstrapitself.Inmostcases,wewouldaddittotheortag.ItisalsopossibleyouwouldbebuildingaregularapplicationinJava,PHP,or.NETandonlyasectionofitwouldberunninganAngularJSapp,insuchcasesyouwouldaddng-apptothetagwrappingtheappcomponent.ng-init:Thisisusedtodefinetheinitializationtasks.Inthisexample,wearecreatingamodelcalledmyNamewiththevalueJohnDoe.

    NoteUsingng-initisnotrecommendedforproductionapps.Aswewillseelaterinthischapter,theidealwaytoinitializethevariablewouldbeinthecontrollerinsteadofdirectlywritingitintheview.

    {{}}:Thedoublecurlybracketsareusedtooutputthedatastoredinmodels.Inthiscase,{{myName}}outputsthevalueJohnDoe.Thesecurlybracketscanalsobeusedforexpressions,asintheexample{{2014-1968}}outputstheresult46.ThisisverysimilartohowothertemplatingenginessuchasMustacheorSmartywork.Directives:Theng-appandtheng-inittagsthatyouseeintheprecedingsample

    http://www.angularjs.org

  • codearecalledDirectives.TheyareanintegralpartofanyAngularJSappanditisthroughthesedirectivesthatAngularJSisabletomodifytheDOMelementofanapplication.AngularJScomeswithawholesetofpredefineddirectivesmanyofwhichwewilluseaswegothroughthisbook.ThegoodthingaboutAngularJSisthatyoucanalsocreateyourowncustomdirectivesthatcanmeetyourspecificrequirements.

  • ModelsandviewsInAngularJS,amodelcouldbeaprimitive,ahashtable,oraJavaScriptobject.Thedatafromthemodelcanbedisplayedintheviewusingthe{{}}expression.

    Modelscanbedefinedinmultipleways.Likewesawinthefirstexample,wecandefinethemodelwithintheng-initdirective.Itcanbecreatedinthetemplatewithintheexpressionasfollows:

    click

    Alternatively,itcouldalsobecreatedwithinacontrollerusingthescope,whichistheidealwaytodoit.Refertothefollowingcode:

    ModelinScope

    {{person.name}}livesin{{person.city}}functionPeopleController($scope){$scope.person={name:"JohnDoe",city:"NewYork"}}

    Intheprecedingexample,wecreatedacontrollercalledPeopleControlleranddefinedthemodelperson,whichisstoringthedataasahashtable.The$scopeisanAngularJSobjectthatisabletoreferencetheJavaScriptobjectmodelasaproperty.

  • BuildinganAddressBookAppIntheearlierexamples,wesawthedifferentwaysofcreatingmodels.Whencreatingproductiongradeorlarge-scaleapplications,whichinvolvegraphicalinterfaces,itiscompulsorytofollowtheModelViewController(MVC)designpattern.

    Buildingonthepreviouscodeexample,we’llgoaheadandbuildasimpleAddressBookApp.

    Let’sstartbycreatingourmodelsinacontrollercalledPeopleController.We’llnowwriteallourJavaScriptsinafilecalledscripts.js.Yourscripts.jsfileshouldlooklikethis:

    functionPeopleController($scope){$scope.people=[{name:"JohnDoe",phone:"3452345678",city:"NewYork"},{name:"SarahParker",phone:"1236548769",city:"Chicago"},{name:"LittleJohn",phone:"4567853432",city:"LosAngeles"},{name:"AdamDoe",phone:"9025673152",city:"LasVegas"}];}

    HerewearedefiningthecontrollercalledPeopleControllerandcreatingourmodelcalledpeople.Themodelcontainsthreeattributes:name,phone,andcity.

    Now,letusgetourmarkupinplace.Letuscallthefileindex.htmlusingthefollowingcode:

    AddressBookAddressBook{{person.name}}-{{person.phone}}{{person.city}}

    TipItisalwaysagoodpracticetoloadyourJSfilesattheendofthepagejustabovethebodytagandnotinthehead.Youcanreadmoreaboutwhythismattershereathttps://developer.yahoo.com/performance/rules.html.

    https://developer.yahoo.com/performance/rules.html

  • Asyoucanseehere,wearedefiningtheHTML5doctypeinthefirstline,andthenweinitializetheAngularJSapplicationbyusingtheng-appdirective.You’llalsonoticethatweareusingtheng-controllerdirectiveandassigningPeopleControllertoit.Bydoingso,wearedefiningthesectionoftheDOMthatisnowwithinthescopeofthiscontroller.

    You’llalsonoticeanewdirectivecalledng-repeat;thisisthebuilt-indirectiveusedtodisplayalistofitemsfromacollection.Theng-repeatdirectivewouldsimplyduplicatetheDOMelementandbindthedefinedpropertiesofthedataobject.

    Asyoucansee,ng-repeatmakesitsoeasyandcleantodisplayrecordsetsascomparedtodoingthisinjQueryorplainvanillaJavaScript.

    Now,runyourindex.htmlinthebrowserandyoushouldbeseeingthenameswiththeirphonenumbersandcitiesbeingdisplayed.Thedatafromourmodelisshowingup,whichisgood.LetusalsoinspectthecodetohavealookatthechangesAngularJSismakingtoourmarkup.

    Allmodernbrowsersallowyoutoinspectthesource.Andinmostcasesyoucansimplyright-clickonthepageandselectInspectElement.IncaseyouarenotcomfortablewithInspect,youcanalsodoViewSource.Refertothefollowingscreenshot:

  • TipBytheway,hereI’musingFirebug,anawesomeadd-onforMozillaFirefox.

    Asyoulookthroughthecode,you’llnoticethatAngularJSismakingafairbitofchangetothemarkup.

    Thefirstthingyou’llnoticeisthatAngularJSaddsaclasscalledng-scopetoeveryDOMelementwherethescopeisinitialized(wewillgettowhatascopeis,injustabit).ItduplicatestheentireDOMpresentwithintheng-repeatdirective.Itisalsoaddingaclasscalledng-bindingtoeveryelementwherethedataisbound.

    AngularJSwilladddifferentCSSclassesdependingonthedirectivebeingused.Thesecancomeinhandywhenyouwanttostyle,forexample,thevalidationmessageswhileworkingwithforms.We’llseemoreaboutthisinthechaptersahead.

  • UnderstandingthescopeinAngularJSLetusnowlookatthisthingcalledthescope.Asyoumighthavenoticed,wedefinedourpeoplecontrollerwitha$scopeparameter.Wealsohadtodefineourpeoplemodelasapartofthisscope.Whileinspectingtheelements,wealsonoticedmultipleng-scopeclassesbeingdefined.So,whatexactlyisthisscopeandisitreallythatimportant?

    AsperAngularJS’sdocuments,thescopeobjectreferstotheapplicationmodelandprovidesanexecutioncontextfortheexpressionsintheviews.

    Theexpression{{person.name}}isabletodisplaythecontentonlybecausethenameisapropertythatcanbeaccessedbythescope.

    AnotherimportantthingtonoteisthateveryAngularJSappwillhavearootscopecreatedattheng-appdirective.Manyotherdirectivescouldalsocreatetheirownscope.ScopesarearrangedinahierarchicalfashionfollowingtheDOMstructureofthepage.ChildScopesprototypicallyinheritfromtheirparentscope.

    Theexceptiontothisisincaseswhereadirectiveusesascopeoption,itcreatesanisolatedscope.MoreinformationaboutthedirectivesandisolatedscopeisavailableinChapter5,FacebookFriends’BirthdayReminderApp.

    We’llgetabetterunderstandingofitasweseeotherexamples.

  • StylingtheappNow,letusstyletheapplicationtomakeitlookalittlebetter.We’llgobacktoourindex.htmlandaddafewCSSclassesasfollows:

    AddressBook

    AddressBook

  • padding:10px;

    }.contact-item{border-bottom:thinsolid#ccc;padding:10px;}

    AsyoucanseefromtheCSSstyles,wefirststylethebodytogiveitalightgraybackgroundcolorusingthe#ccc(#cccistheshortcodefor#cccccc)hexcode.

    TheH1headingtagisstyledtoaligncenter,withadarkgraytextcolorandatextshadow.Thestylingfor.nameand.cityisstraightforward.Now,letuslookatthestylesfor.wrapperusingthefollowingcode:

    .wrapper{width:650px;margin:0auto;box-shadow:5px5px5px#555;background:#fff;border-radius:15px;padding:10px;

    }

    Here,wearesettingwidthofthedivto650px.Themarginwith0autoisusedtoplacethedivtothecenterofthescreenirrespectiveofthescreenresolution.

    TipDownloadingtheexamplecode

    YoucandownloadtheexamplecodefilesforallPacktbooksyouhavepurchasedfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.

    Nowtomakeitlookalittlebetter,we’llgiveitabox-shadowandborderradius.Thefollowingdiagramexplainswhattheoptionsoftheborderradiusmean:

    Forthe.contact-itemlist,wegiveaborder-bottomandsomepaddingsothatthingsstayalittlespacedout.

    http://www.packtpub.comhttp://www.packtpub.com/support

  • WithallthisCSSinplace,yourappshouldbelookinglikethis:

  • SortingthecontactsalphabeticallyThislooksnice,butitwouldbeagoodideatohavethenamessortedalphabetically.Forthis,wewilluseAngularJS’sbuilt-infiltercalledorderBy.

    InAngularJS,filtersareusedtoformatthedata.OnecanuseAngularJS’spredefinedfiltersorcreateyourown.We’lllearnmoreaboutfilterslaterinthisbook.

    Allweneedtodoismodifythefollowingsectionoftheindex.htmlasfollows:

    {{person.name}}-{{person.phone}}{{person.city}}

    RefreshyourIndex.htmlinthebrowserandyoushouldnoticethenamesarenowsortedalphabetically.

  • AddingcontactstotheAddressBookNowthatwehaveourAddressBookdisplayingourcontactsnicely,let’snowcreateaformtoaddcontacts.

    LetusaddthemarkupfortheAddaContactformintheindex.htmlfilewithinthebodytagasfollows:

    AddaContactName:Phone:City:Save

    Theprecedingcodeisratherstraightforward.Wecreateanewdivandreusethewrapperclasstostyleit.

    Weareaddingthethreetextboxesforthename,phone,andcityattributes.WebindthesethreetextboxestoamodelobjectcallednewPersonasfollows:

    ng-model='newPerson.name'ng-model='newPerson.phone'ng-model='newPerson.city’

    WearealsoaddingabuttoncalledSaveandusingtheng-clickdirectivethatwillcalltheSave()functionwhenthebuttonisclicked.

    Now,letuslookattheJavaScriptcodethatwewillbewritinginourscripts.jsfile:

    $scope.Save=function(){$scope.people.push({name:$scope.newPerson.name,phone:$scope.newPerson.phone,city:$scope.newPerson.city});}

    TipSincetheSave()functionisaccessingthescopewithinthePeopleControllerfunction,itisimperativethattheSave()functioniswrittenwithinthePeopleControllerfunctioninthescripts.jsfile.

    Inthe$scope.Savefunction,wesimplycapturethevaluesfromtheinputboxesandpushthisintoourmainpeoplemodel.

    Letusnowrefreshourindex.htmlandtryitout.FilluptheformandsaveitandyouwillimmediatelyseeitgetaddedtotheAddressBook.ThishappensthankstooneofthemanycoolfeaturesofAngularJScalledtwo-waydatabinding.

  • Theng-showandng-hidedirectivesWhiletheappisgoodasitis,maybeit’sagoodideatohaveabuttoncalledAddContactanddisplaytheAddContactformonlywhenthatbuttonisclicked.

    LetusmakeuseofAngularJS’sng-showandng-hidedirectivestocontrolthevisibilityofourAddContactform.

    Thewaytheyworkisverystraightforward.Iftheattributeng-show='true',thenthedivisvisibleandviceversa.Apointtonoteisthatng-showandng-hidemerelycontrolthevisibilityoftheDOMelement.

    Let’saddourbuttoncalledAddContactandsetuptheng-showandng-hidedirectivessuchthatwhenyouclickonAddContact,theformshowsupandatthesametimethisbuttondisappears.AndwhentheSavebuttonisclicked,theformishiddenandtheAddContactbuttonshowsupagain.

    Let’smodifyourindex.htmlasfollows:

    AddContactAddaContactName:Phone:City:Save

    Wesetthebuttontong-hide='formVisibility'becausewhenthevalueofformVisibilitybecomestrue,itwillhidethebutton.Similarly,ng-show=formVisibilitywillmaketheAddContactformdisplaywhenthevalueofformVisibilityistrue.

    Now,let’saddthepieceofJavaScripttosettheformVisibilityvalues.Addthefollowingcodetoyourscripts.jsfileasfollows:

    $scope.ShowForm=function(){$scope.formVisibility=true;}

    TipMakesurethisnewfunctioniswrittenwithinthemainPeopleControllerfunction.

    Wewillalsoaddonelineinourexisting$scope.SavefunctiontosetthevalueofformVisibilitytofalse.

    Pleaseupdatethe$scope.Save()functionashighlightedinthefollowingcode:

    $scope.Save=function(){

    $scope.people.push({name:$scope.newPerson.name,

  • phone:$scope.newPerson.phone,city:$scope.newPerson.city});$scope.formVisibility=false;

    }

    Reloadyourindex.htmlandseethebuttonsinaction.

    Ohandjustbecausewedon’tlikethewaythosedefaultbuttonslook,letsaddalittlebitofstyletoit.

    AddthefollowingCSSclassestoyourstyles.cssfile:

    button{background:#080;color:#fff;padding:5px15px;border-radius:5px;border:thinsolid#060;"margin:5pxauto;"}button:hover{background:#0A0;}

    Whatwearesimplydoinghereissettingadarkgreencolorbackgroundforthebutton,givingthetextawhitecolor,andgivingitsomepaddingfivepixelsfromthetop-andbottom-sideand15pixelsfromtheleft-handsideandright-handsideandaddingsomeborderradius.

    Thebutton:hoverisalightgreenbackgroundcolorjusttoshowthehighlightwhentheuserhoversthecursoroverthebutton.

    Reloadyourindex.htmlpageandwehaveourveryfirstworkingandreasonablygood-lookingAddressBookApplication.

  • SummaryThisconcludesourfirstchapter.Toquicklysummarize,wewentaboutbuildingourAddressBookAppandindoingsolearnedaboutthevariousAngularJSdirectivessuchasng-appandng-repeat.Wesawhowtwo-waydatabindingsandexpressionsworkandtheimportanceofscope.Wealsosawhowwecanhideandshowcertainelementsusingtheng-showandng-hidedirectives.Lastbutnotleast,weusedsomesimpleandeasyCSS3featurestostyleourapp.

    Inthenextchapter,wewillseethevarioustoolsthatfrontenddevelopersshouldideallyhaveintheirtoolboxandhowtogoaboutusingthem.

  • Chapter2.SettingUpYourRigI’msureyouwouldhaveheardthesaying,“Atoolmanisknownbythetoolshekeeps.”OKfine,Ijustmadethatup,butthat’sactuallytrue,especiallywhenitcomestoprogramming.SureyoucanbuildcompleteandfullyfunctionalAngularJSappsjustusingasimpletexteditorandabrowser,butifyouwanttoworklikeaninja,thenmakesurethatyoustartusingsomeofthesetoolsasapartofyourdevelopmentworkflow.

    DonotethatthesetoolsarenotmandatorytobuildAngularJSapps.Theiruseisrecommendedmainlytohelpimprovetheproductivity.

    Inthischapter,wewillseehowtosetupandusethefollowingproductivitytools:

    Node.jsGruntYeomanKarmaProtractor

    SincemostofusarerunningaMac,Windows,Ubuntu,oranotherflavoroftheLinuxoperatingsystem,we’llbecoveringthedeploymentstepscommonforallofthem.

  • SettingupNode.jsDependingonyourtechnologystack,IstronglyrecommendyouhaveeitherRubyorNode.jsinstalled.

    IncaseofAngularJS,mostoftheproductivitytoolsorpluginsareavailableasNodePackageManager(npm),and,hence,wewillbesettingupNode.jsalongwithnpm.Node.jsisanopensourceJavaScript-basedplatformthatusesanevent-basedInput/outputmodel,makingitlightweightandfast.

    Letusheadovertowww.nodejs.organdinstallNode.js.Choosetherightversionasperyouroperatingsystem.

    ThecurrentversionofNode.jsatthetimeofwritingthisbookisv0.10.xwhichcomeswithnpmbuiltin,makingitabreezetosetupNode.jsandnpm.

    TipNode.jsdoesn’tcomewithaGraphicalUserInterface(GUI),sotouseNode.js,youwillneedtoopenupyourterminalandstartfiringsomecommands.NowwouldalsobeagoodtimetobrushuponyourDOSandUnix/Linuxcommands.

    AfterinstallingNode.js,thefirstthingyou’dwanttocheckistoseeifNode.jshasbeeninstalledcorrectly.

    So,letusopenuptheterminalandwritethefollowingcommand:

    node–-version

    ThisshouldoutputtheversionnumberofNode.jsthat’sinstalledonyoursystem.Thenextwouldbetoseewhatversionofnpmwehaveinstalled.Thecommandforthatwouldbeasfollows:

    npm–-version

    Thiswilltellyoutheversionnumberforyournpm.

    http://www.nodejs.org

  • CreatingasimpleNode.jswebserverwithExpressJSForbasic,simpleAngularJSapps,youdon’treallyneedawebserver.YoucansimplyopentheHTMLfilesfromyourfilesystemandtheywouldworkjustfine.However,asyoustartbuildingcomplexapplicationswhereyouarepassingdatainJSON,webservices,orusingaContentDeliveryNetwork(CDN),youwouldfindtheneedtouseawebserver.

    ThegoodthingaboutAngularJSappsisthattheycouldworkwithinanywebserver,soifyoualreadyhaveIIS,Apache,Nginx,oranyotherwebserverrunningonyourdevelopmentenvironment,youcansimplyrunyourAngularJSprojectfromwithinthewebrootfolder.

    Incaseyoudon’thaveawebserverandarelookingforalightweightwebserver,thenletussetoneupusingNode.jsandExpressJS.

    OnecouldwritetheentirewebserverinpureNode.js;however,ExpressJSprovidesanicelayerofabstractionontopofNode.jssothatyoucanjustworkwiththeExpressJSAPIsanddon’thavetoworryaboutthelow-levelcalls.

    So,let’sfirstinstalltheExpressJSmoduleforNode.js.

    Openupyourterminalandfirethefollowingcommand:

    npminstall-gexpress-generator

    ThiswillgloballyinstallExpressJS.Omitthe–gtoinstallExpressJSlocallyinthecurrentfolder.

    WheninstallingExpressJSgloballyonLinuxorMac,youwillneedtorunitviasudoasfollows:

    sudonpminstall–gexpress-generator

    Thiswillletnpmhavethenecessarypermissionstowritetotheprotectedlocalfolderundertheuser.ThenextstepistocreateanExpressJSapp;letuscallitmy-server.Typethefollowingcommandintheterminalandhitenter:

    expressmy-server

    You’llseesomethinglikethis:

    create:my-servercreate:my-server/package.jsoncreate:my-server/app.jscreate:my-server/publiccreate:my-server/public/javascriptscreate:my-server/public/imagescreate:my-server/public/stylesheetscreate:my-server/public/stylesheets/style.csscreate:my-server/routescreate:my-server/routes/index.js

  • create:my-server/routes/user.jscreate:my-server/viewscreate:my-server/views/layout.jadecreate:my-server/views/index.jade

    installdependencies:$cdmy-server&&npminstall

    runtheapp:$DEBUG=my-server./bin/www

    Thiswillcreateafoldercalledmy-serverandputinabunchoffilesinsidethefolder.

    NoteThepackage.jsonfileiscreated,whichcontainstheskeletonofyourapp.Openitandensurethenamesaysmy-server;also,notethedependencieslisted.

    Now,toinstallExpressJSalongwiththedependencies,firstchangeintothemy-serverdirectoryandrunthefollowingcommandintheterminal:

    cdmy-servernpminstall

    Now,intheterminal,typeinthefollowingcommand:

    npmstart

    Openyourbrowserandtypehttp://localhost:3000intheaddressbar.You’llgetaniceExpressJSwelcomemessage.NowtotestourAddressBookAppcreatedinChapter1,IntroductiontoAngularJSandtheSinglePageApplication,wewillcopyourindex.html,scripts.js,andstyles.cssintothepublicfolderlocatedwithinmy-server.

    NoteI’mnotcopyingtheangular.jsfilebecausewe’llusetheCDNversionoftheAngularJSlibrary.

    Openuptheindex.htmlfileandreplacethefollowingcode:

    WiththeCDNversionofAngularJSasfollows:

    Aquestionmightarise,astowhatiftheCDNisunreachable.Insuchcases,wecanaddafallbacktousealocalversionoftheAngularJSlibrary.

    WedothisbyaddingthefollowingscriptaftertheCDNlinkiscalled:

    window.angular||document.write('');

    Savethefileinthebrowserandenterlocalhost:3000/index.html.YourAddressBook

  • isnowrunningfromaserverandtakingadvantageofGoogle’sCDNtoservetheAngularJSfile.

    TipReferencingthefilesusingonly//isalsocalledtheprotocolindependentabsolutepath.Thismeansthatthefilesarerequestedusingthesameprotocolthatisbeingusedtocalltheparentpage.Forexample,ifthepageyouareloadingisviahttps://,thentheCDNlinkwillalsobecalledviaHTTPS.

    Thisalsomeansthatwhenusing//insteadofhttp://duringdevelopment,youwillneedtorunyourappfromwithinaserverinsteadofafilesystem.

  • SettingupGruntGruntisaJavaScript-basedtaskrunner.Itisprimarilyusedforautomatingtaskssuchasrunningunittests,concatenating,merging,andminifyingJSandCSSfiles.Youcanalsorunshellcommands.Thismakesitsupereasytoperformservercleanupsanddeploycode.Essentially,GruntistoJavaScriptwhatRakewouldbetoRubyorAnt/MavenwouldbetoJava.

  • InstallingGrunt-cliInstallingGrunt-cliisslightlydifferentfrominstallingotherNode.jsmodules.WefirstneedtoinstalltheGrunt’sCommandLineInterface(CLI)byfiringthefollowingcommandintheterminal:

    npminstall-ggrunt-cli

    MacorLinuxuserscanalsodirectlyrunthefollowingcommand:

    sudonpminstall–ggrunt-cli

    Makesureyouhaveadministrativeprivileges.UsesudoifyouareonaMacorLinuxsystem.IfyouareonWindows,right-clickandopenthecommandpromptwithadministrativerights.AnimportantthingtonoteisthatinstallingGrunt-clidoesn’tautomaticallyinstallGruntanditsdependencies.

    Grunt-climerelyinvokestheversionofGruntinstalledalongwiththeGruntfile.Whilethismayseemalittlecomplicatedatstart,thereasonitworksthiswayissothatwecanrundifferentversionsofGruntfromthesamemachine.ThiscomesinhandywhenyourprojecthasdependenciesonaspecificversionofGrunt.

  • Creatingthepackage.jsonfileToinstallGruntfirst,let’screateafoldercalledmy-projectandcreateafilecalledpackage.jsonwiththefollowingcontent:

    {"name":"My-Project","version":"0.1.0","devDependencies":{"grunt":"~0.4.5","grunt-contrib-jshint":"~0.10.0","grunt-contrib-concat":"~0.4.0","grunt-contrib-uglify":"~0.5.0","grunt-shell":"~0.7.0"

    }}

    Savethefile.Thepackage.jsoniswhereyoudefinethevariousparametersofyourapp;forexample,thenameofyourapp,theversionnumber,andthelistofdependenciesneededfortheapp.

    HerewearecallingourappMy-ProjectwithVersion0.1.0,andlistingoutthefollowingdependenciesthatneedtobeinstalledasapartofthisapp:

    grunt(v0.4.5):ThisisthemainGruntapplicationgrunt-contrib-jshint(v0.10.0):Thisisusedforcodeanalysisgrunt-contrib-concat(v0.4.0):Thisisusedtomergetwoormorefilesintoonegrunt-contrib-uglify(v0.5.0):ThisisusedtominifytheJSfilegrunt-shell(v0.7.0):ThisistheGruntshellusedforrunningshellcommands

    Visithttp://gruntjs.com/pluginstogetalistofallthepluginsavailableforGruntandalsotheirexactnamesandversionnumbers.

    NoteYoumayalsochoosetocreateadefaultpackage.jsonfilebyrunningthefollowingcommandandansweringthequestions:

    npminit

    Openthepackage.jsonfileandaddthedependenciesasmentionedearlier.

    Nowthatwehavethepackage.jsonfile,loadtheterminalandnavigateintothemy-projectfolder.ToinstallGruntandthemodulesspecifiedinthefile,typeinthefollowingcommand:

    npminstall--save-dev

    You’llseeaseriesoflinesgettingprintedintheconsole,letthatcontinueforawhileandwaituntilitreturnstothecommandprompt.EnsurethatthelastlineprintedbythepreviouscommandendswithOKcode0.

    OnceGruntisinstalled,aquickversioncheckcommandwillensurethatGruntis

    http://gruntjs.com/plugins

  • installed.Thecommandisasfollows:

    grunt–-version

    Thereisapossibilitythatyougotabunchoferrorsanditendedwithanotokcode0message.Therecouldbemultiplereasonswhythatwouldhavehappened,rangingfromerrorsinyourcodetoanetworkconnectionissueorsomethingchangingatGrunt’sendduetoanewversionupdate.

    Ifgrunt--versionthrowsupanerror,itmeansGruntwasn’tinstalledproperly.ToreinstallGrunt,enterthefollowingcommandsintheterminal:

    rm–rfnode_modulesnpmcachecleannpminstall

    Windowsusersmaymanuallydeletethenode_modulesfolderfromWindowsExplorer,beforerunningthecachecleancommandinthecommandprompt.

    TipRefertohttp://www.gruntjs.comtotroubleshoottheproblem.

    http://www.gruntjs.com

  • CreatingyourGrunttasksTorunourGrunttasks,we’llneedaJavaScriptfile.So,let’scopyourscritps.jsfromthepreviouschapterandplaceitintothemy-projectsfolder.

    ThenextstepistocreateaGruntfilethatwilllistoutthetasksthatweneedGrunttoperform.

    Fornow,wewillaskittodofoursimpletasks,firstcheckifourJScodeiscleanusingJSHint,thenwewillmergethreeJSfilesintooneandthenminifytheJSfile,andfinallywewillrunsomeshellcommandstocleanup.

    NoteUntilVersion0.3,theinitcommandwasapartoftheGrunttoolandonecouldcreateablankprojectusinggrunt-init.WithVersion0.4,initisnowavailableasaseparatetoolcalledgrunt-initandneedstobeinstalledusingthenpminstall–ggrunt-initcommandline.Alsonotethatthestructureofthegrunt.jsfilefromVersion0.4onwardsisfairlydifferentfromtheearlierversionsyou’veused.

    Fornow,wewillresorttocreatingtheGruntfilemanually.Refertothefollowingscreenshot:

    Inthesamelocationaswhereyouhaveyourpackage.json,createafilecalledgruntfile.jsasshownearlierandtypeinthefollowingcode:

    module.exports=function(grunt){//Projectconfiguration.grunt.initConfig({jshint:{all:['scripts.js']}});

    grunt.loadNpmTasks('grunt-contrib-jshint');

  • //Defaulttask.grunt.registerTask('default',['jshint']);};

    Tostart,wewilladdonlyonetaskwhichisjshintandspecifyscripts.jsinthelistoffilesthatneedtobelinted.Inthenextline,wespecifygrunt-contrib-jshintasthenpmtaskthatneedstobeloaded.Inthelastline,wedefinethejshintasthetasktoberunwhenGruntisrunningindefaultmode.Savethefileandintheterminalrunthefollowingcommand:

    grunt

    Youwouldprobablygettoseethefollowingmessageintheterminal:

    SoJSHintissayingthatwearemissingasemicolononlines18and24.Oh!DidImentionthatJSHintislikeyourverystrictmathteacherfromhighschool.

    Let’sopenupscripts.jsandputinthosesemicolonsandrerunGrunt.Nowyoushouldgetamessageingreensaying1filelintfree.Donewithouterrors.

    Let’saddsomemoretaskstoGrunt.We’llnowaskittoconcatenateandminifyacoupleofJSfiles.Sincewecurrentlyhavejustonefile,let’sgoandcreatetwodummyJSfilescalledscripts1.jsandscripts2.js.

    Inscripts1.jswe’llsimplywriteanemptyfunctionasfollows:

    //Thisisfromscript1functionScript1Function(){//------//}

    Similarly,inscripts2.jswe’llwritethefollowing:

    //Thisisfromscript2functionScript2Function(){//------//}

    Savethesefilesinthesamefolderwhereyouhavescripts.js.

  • GrunttaskstomergeandconcatenatefilesNow,let’sopenourGruntfileandaddthecodeforboththetasks—tomergetheJSfile,andminifythemasfollows:

    module.exports=function(grunt){//Projectconfiguration.grunt.initConfig({jshint:{all:['scripts.js']},concat:{dist:{src:['scripts.js','scripts1.js','scripts2.js'],dest:'merged.js'}},

    uglify:{dist:{src:'merged.js',dest:'build/merged.min.js'}}});

    grunt.loadNpmTasks('grunt-contrib-jshint');grunt.loadNpmTasks('grunt-contrib-concat');grunt.loadNpmTasks('grunt-contrib-uglify');

    //Defaulttask.grunt.registerTask('default',['jshint','concat','uglify']);};

    Asyoucanseefromtheprecedingcode,afterthejshinttask,weaddedtheconcattask.Underthesrcattribute,wedefinethefilesseparatedbyacommathatneedtobeconcatenated.Andinthedestattribute,wespecifythenameofthemergedJSfile.

    TipItisveryimportantthatthefilesareenteredinthesamesequenceastheyneedtobemerged.Ifthesequenceofthefilesenteredisincorrect,themergedJSfilewillcauseerrorsinyourapp.

    TheuglifytaskisusedtominifytheJSfileandthestructureisverysimilartotheconcattask.Weaddthemerged.jsfiletothesrcattributeandinthedestattribute,wewillplacethemerged.min.jsfileintoafoldercalledbuild.

    Note

  • Gruntwillautocreatethebuildfolder.

    Afterdefiningthetasks,wewillloadthenecessaryplugins,namelythegrunt-contrib-concatandthegrunt-contrib-uglify,andfinallywewillregistertheconcatanduglifytaskstothedefaulttask.

    SavethefileandrunGrunt.Andifallgoeswell,youshouldseeGruntrunningthesetasksandinformingthestatusofeachofthetasks.

    Ifyougetthefinalmessagesaying,Done,withoutanyerrors,itmeansthingswentwell,andthiswasyourluckyday!

    Ifyounowopenyourmy-projectfolderinthefilemanager,youshouldseeanewfilecalledmerged.js.Openitinthetexteditorandyou’llnoticethatallthethreefileshavebeenmergedintothis.Also,gointothebuild/merged.min.jsfileandverifywhetherthefileisminified.

  • RunningshellcommandsviaGruntAnotherreallyhelpfulplugininGruntisgrunt-shell.Thisallowsustoeffectivelyrunclean-upactivitiessuchasdeleting.tmpfilesandmovingfilesfromonefoldertoanother.

    Let’sseehowtoaddtheshelltaskstoourGruntfile.AddthefollowinghighlightedpieceofcodetoyourGruntfile:

    module.exports=function(grunt){//Projectconfiguration.grunt.initConfig({jshint:{all:['scripts.js']},concat:{dist:{src:['scripts.js','scripts1.js','scripts2.js'],dest:'merged.js'}},

    uglify:{dist:{src:'merged.js',dest:'build/merged.min.js'}},

    shell:{multiple:{command:['rm-rfmerged.js','mkdirdeploy','mvbuild/merged.min.jsdeploy/merged.min.js'].join('&&')}}});

    grunt.loadNpmTasks('grunt-contrib-jshint');grunt.loadNpmTasks('grunt-contrib-concat');grunt.loadNpmTasks('grunt-contrib-uglify');grunt.loadNpmTasks('grunt-shell');//Defaulttask.grunt.registerTask('default',['jshint','concat','uglify','shell']);};

    Asyoucanseefromthecodeweadded,wearefirstdeletingthemerged.jsfile,thencreatinganewfoldercalleddeployandmovingourmerged.min.jsfileintoit.WindowsuserswouldneedtousetheappropriateDOScommandsfordeletingandcopyingthe

  • files.

    Notethat.join('&&')isusedwhenyouwantGrunttorunmultipleshellcommands.Thenextstepsaretoloadthenpmtasksandaddshelltothedefaulttasklist.ToseeGruntperformallthesetasks,runtheGruntcommandintheterminal.

    Onceit’sdone,openupthefilesystemandverifywhetherGrunthasdonewhatyouhadaskedittodo.Justlikeweusedtheprecedingfourplugins,therearenumerousotherpluginsthatyoucanusewithGrunttoautomateyourtasks.

    ApointtonoteiswhilethedefaultGruntcommandwillrunallthetasksmentionedinthegrunt.registerTaskstatement,ifyouwouldneedtorunaspecifictaskinsteadofallofthem,thenyoucansimplytypethefollowinginthecommandline:

    gruntjshint

    Alternatively,youcantypethefollowingcommand:

    gruntconcat

    Alternatively,youcantypethefollowingcommand:

    gruntugligy

    Attimesifyou’dliketorunjusttwoofthethreetasks,thenyoucanregisterthemseparatelyasanotherbundledtaskintheGruntfile.Openupthegruntfile.jsfile,andjustafterthelinewhereyouhaveregisteredthedefaulttask,addthefollowingcode:

    grunt.registerTask('concat-min',['concat','uglify']);

    Thiswillregisteranewtaskcalledconcat-minandwillrunonlytheconcatanduglifytasks.

    Intheterminalrunthefollowingcommand:

    gruntconcat-min

    VerifywhetherGruntonlyconcatenatedandminifiedthefileanddidn’trunJSHintoryourshellcommands.

    TipYoucanrungrunt--helptoseealistofallthetasksavailableinyourGruntfile.

  • Yeoman–theworkflowtoolYeomanpreferstobeknownasaworkflowratherthanjustatool.Itisactuallyacollectionofthreetoolsthathelpyoumanageyourworkflowefficiently.ThetoolsthatcomeasapartofYeomanareasfollows:

    Yo:Thisisascaffoldingtoolandusingthenumerousgeneratorsavailable,onecanquicklycreatetheskeletonofyourproject.YohasageneratortobuildAngularJSappsandwewillbeusingthatlaterinthischapter.Grunt:Thisisusedtorunthetasksthatwillhelpyoupreview,test,andbuildtheapp.Bower:Thisisanidealtoolfordependencymanagement.Yeomanusesittoautomaticallysearchanddownloadthenecessaryscripts.

    Let’sgoaboutinstallingYeomanandplayingaroundwithitabit.

  • InstallingYeomanToinstallYeoman,makesureyouarerunningitwithadministrativeprivileges.Enterthefollowingcommandintheterminal:

    sudonpminstall–gyo

    Next,let’sinstalltheAngularJSgeneratorusingthefollowingcommand:

    sudonpminstall-ggenerator-angular

    Now,let’screateourprojectdirectoryandcreatetheskeletonforourproject.WewillcallourappYoho;so,firstlet’screateafoldercalledyoho.Enterthefollowingcommandintheterminal:

    mkdiryohocdyohoyoangular

    It’snowgoingtostartaskingaseriesofquestions,answerYforallexceptthequestion,“WouldyouliketouseSass(withCompass)?”.AnswerNforthisone.

    NoteThereasonwesaynohereisbecausefornowwewillusevanillaCSS.UsingSaasandCompassishoweverstronglyrecommendedwhilebuildinglargeapplications.

    Onceyo-angularhasfinisheddoingwhateverithadtodo,gointoyouryohofolderandyou’llnoticeawholebunchoffilesandfolders,asshowninthefollowingscreenshot:

  • YeomanhascreatedtheskeletonofyourAngularJSappalongwitheverythingyouwillneedforthisproject.

    Beforewegointothedetailsofthedifferentfiles,onethingtonoteisthatyournode_modulesfolderisempty.ThismeansYeomanhasonlycreatedthepackage.jsonfilewithalldevdependencieslistedout,buthasn’tdownloadedthemyet.

    Wewillneedtorunthefollowingcommand:

    npminstall

  • Thiswilldownloadandinstallallthedependencieslistedoutinthepackage.jsonfile.Onceit’sfinishedinstalling,verifythatthenode_modulesfoldernowhasfolderssuchasgrunt-contrib-cleanandgrunt-contrib-concatwithinit.

    Ok,now,let’stryandmakesenseofallthefilesthatYeomanhascreated.Refertothefollowingtable:

    Filename Description

    app/404.html Thisisthe404errorpagethatwillshowup,whentheusertypesinawrongURLortheAngularappcouldn’tfindthepagementionedintheURL.

    app/favicon.ico

    Thisistheiconthatwillshowupinthebrowsertabofyourapp.Makesureyoureplacethisdefaultonewithaniconthatrepresentsyourapp.Feelfreetouseanyofthosenumerousonlinefavicongeneratorstocreateyourfavicon.Rememberthatthisfaviconhelpsuserstoquicklyidentifyyourappwithinthemultipletabsofanopenbrowser.

    app/index.html

    Thiswillbethehomepageforyourapp.Youcanopenitinatexteditortoseewhatitcontains.Asyouwouldhavenoticed,otherthanthatonelineofcodewiththeng-viewsdirective,therestofthefileismostlybrowserchecksandinclusionofthevariousJavaScriptfiles.NotethatthereisnoactualAngularJScodeotherthanng-viewsandthat’showitneedstobekepttoo.

    robots.txtThisisthefilewhereyousetrulesforthesearchenginerobotsorcrawlers,tellingthemwhatpagestheycanindexandwhichsectionsoftheappshouldnotbeindexed.

    scripts/app.js

    Thisistheroute’sfilewhereyou’lldefinethetemplateviewandthecontrollerthatshouldloadforagivenURL.ControllersandviewsarelooselycoupledinAngularJS;thismeansyoucanhaveasinglecontrollertalktodifferentviews,orswapthetemplatesforacontrollerbysimplyeditingtheroutesinthisapp.jsfile.

    scripts/controllers/main.jsscripts/controllers/about.js

    Thisiswhereyou’llbewritingthecontrollersforthisapp.Asapartofthescaffolding,YeomanwouldhavealreadycreatedadefaultMainCtrlandAboutCtrlcontrollerswithamodelcreatedineach.Feelfreetomodifyitand/orwritetherestofyourcontrollersinthesamefile.

    styles/main.cssAllyourCSScodewouldgointothisfile.Thestylesfolderwouldalsocontainthebootstrap.cssfile.ThiscontainsalltheBootstrapclasses.Makesureyoudon’tmodifyanyofthecodehereoraddanyadditionalCSSinthebootstrapfile.

    views/about.htmlviews/main.html

    Theviewsfolderwouldcontainallthetemplateviewsorpartialsastheyarealsocalledtoloadwithintheng-viewstagoftheindex.htmlfile.Theroutesdefinedinthescripts/apps.jsfilewouldcontrolwhatviewwillbedisplayedforthegivenURL.

    Bower_components:ThiscontainsfoldersforthevariousvendorlibrariessuchasAngularJS,AngularAnimate,jQuery,andBootstrapanditisusedfordependencymanagementoftheselibraries.

    bower.json Thebower.jsonfilekeepsatrackofthedependenciesanddevdependenciesofthevariousmodulesandpluginsforthisapp.

    YouknowwhattheGruntfileisforright?Openitinatexteditorandbeoverwhelmedbythe300pluslinesofcodeinthefile.You’llseeabunchof

  • Gruntfile.js predefinedtasksandyou’llalsonoticethatbesidesthedefaultbundledtask,youalsohavetaskscalledtestandbuild.Thesecanbeusedtopreviewyourappandfinallybuilditreadyfordeployment.

    test/karma.conf.js

    Thekarma.conf.jsfileistheconfigurationfileforrunningKarmaunittests.Openingthisfilewillshowthetestingframeworkweareusing,listfilesthatwewanttoincludewithinthescopeoftheseunittests,whatporttouse,thebrowsertouse,andsoon.

    node_modules

    Asself-explanatoryasitcanbe,thisfoldercontainsthevariousNode.jsmodulesthatweredefinedinthepackage.jsonfile.Notethatthesemodulesdonotgetinstalledwhenyouruntheyo-angularcommand.Thesewoulddownloadandinstallonlyafteryourunthenpm-installcommandafterthecreationofthepackage.jsonfile.

    package.jsonThisfilelistsoutalltheNode.jsmodulesthatneedtobeinstalled.Youmayeditthisfilewithcautiontoaddmoreorremovedependenciesthatyouthinkarenotneededforyourapp.

    test/spec/controllers/main.js

    Thisisthefilewhereyou’dwritetheunittestsforyourcontrollers.Themain.jsfilewouldalreadyhaveasimpleunittestinit.

    ThedefaultconfigurationofYeomanusesJasmine;youcanchangetheconfigurationstouseMochaorQunitframeworks.

    Let’sinstallourNode.jsmodulesbyrunningthefollowingcommandintheterminal:

    npminstall

  • RunningyourappEarlierinthischapter,wesawhowtosetupaserverusingNode.jsandExpressJS.Yeomancomeswithitsownserverandrunningitisassimpleasrunningthefollowingcommandinyourterminal:

    gruntserve

    TipThegruntservercommandisdeprecatedalthoughitmightstillworkforsome.

    Thiswillopenupanewbrowserwindowandwillshowyouthedefaultwelcomescreen,asshowninthefollowingscreenshot:

    Ifyourecollectlookingatthemain.jsfile(underscripts/controllers)andthe

  • main.htmlfile(underviews),you’llnoticethepagethatisbeingrendered.Let’splayaroundabit.

    Openthescripts/controllers/main.jsfileandyou’llfindacontrollercalledMainCtrlandamodelcalledawesomeThings.Let’saddsomemoreitemstothisarrayasfollows:

    'usestrict';

    angular.module('yohoApp').controller('MainCtrl',function($scope){$scope.awesomeThings=['HTML5Boilerplate','AngularJS','Karma','E2E','Protractor'

    ];});

    Let’sdisplayourawesomeThingsarrayintheview.Pleaseaddthefollowingcodetothemain.htmlfileasfollows:

    {{things}}

    Savethefileandswitchtothebrowser.VOILA!Thepageupdatedonitsown,youdidn’thavetoreloadthepageinthebrowser.

    Thebrowserupdatesthemomentyousaveyourfile,nomorehittingtherefreshbutton.Isn’tthatabigreliefandaproductivityboost!

    ThisworksthankstoaniftymodulecalledLiveReload.You’llfindthisbeinginstalledasapartofdevDependenciesinthepackage.jsonfile.You’llalsonoticeGrunttasksforitcreatedinyourgruntfile.jsfile.

    Sonowyoucanhavetheserverrunningandplaceyourbrowserwindowandyourtexteditorarrangedside-by-side,andwatchyourappupdateasyouwriteyourcodeandsavethefile.

  • UnittestingwithKarmaWritingautomatedunittestsforyourAngularJSappisoneofthebestpractices,theAngularJSteamhasbeenstronglyadvocatingthisrightfromthestart.Everysamplecodeonthewww.Angularjs.orgsitehasautomatedtestcasesalongwithit.

    Keepinginlinewiththesamephilosophy,YeomantoobakesinsomesampleunittestsusingKarma.WhileYeomanwouldautomaticallyinstallKarmaanditsdependencies,letus,nevertheless,makesurethefollowingmodulesarepresentinthenode_modulesfolder:

    karmakarma-chrome-launcherkarma-jasmine

    Incaseyoudon’tfindtheminyournode_modulesfolder,installthemusingthenpminstallcommand.Next,makesureyourkarma.conf.jsfilelookslikethefollowing:

    module.exports=function(config){config.set({basePath:'',frameworks:['jasmine'],files:['bower_components/angular/angular.js','bower_components/angular-mocks/angular-mocks.js','bower_components/angular-animate/angular-animate.js','bower_components/angular-resource/angular-resource.js','bower_components/angular-cookies/angular-cookies.js','bower_components/angular-route/angular-route.js','bower_components/angular-sanitize/angular-sanitize.js','bower_components/angular-touch/angular-touch.js','app/app.js','app/scripts/*.js','app/scripts/**/*.js','test/spec/**/*.js'],exclude:[],preprocessors:{},reporters:['progress'],port:9876,colors:true,logLevel:config.LOG_INFO,autoWatch:true,browsers:['Chrome'],singleRun:false});};

    Torunyourunittests,simplyrunthefollowingcommandintheterminal:

    grunttest

    http://www.Angularjs.org

  • ThiswillfireupanewChromebrowserwindowandintheterminalstartrunningthroughyourtests.Refertothefollowingscreenshot:

    Oh!WegotanerrorinMainCtrl.ItwouldsaysomethinglikeExpected5tobe3andpointyoutoanerrorinthefilelocatedattest/spec/controllers/main.js.

    Let’sopenupthisfileandseewhat’sgoingoninthere.Thetestcasethat’sfailingisasfollows:

    it('shouldattachalistofawesomeThingstothescope',function(){expect(scope.awesomeThings.length).toBe(3);});

    Ifyourecollect,earlierwehadmodifiedourawesomeThingscontrollerandaddedsomeadditionalelementstothearray,theprecedingtestcaseisexpectingthelengthofthatarraytobe3.Let’snowmodifythatstatementtothefollowingcode:

    expect(scope.awesomeThings.length).toBeGreaterThan(3);

    Let’ssavethisfileandrerunthefollowingcommand:

    grunttest

    ThetestcasesshouldrunfinewithamessagesayingExecuted2of2SUCCESS…….Done,withouterrors.WewillbewritingmoreunittestswithKarmaintheforthcomingchapters.

  • UsingProtractorforEnd-to-EndtestsAswesawearlierwithKarma,wecanwriteunitteststhatwillmakesurethatourcodeinthecontrollersisworkingwell;however,itwouldfallshortifyouwantedtorunautomatedUserAcceptanceTests(UAT)orrunteststhatsimulateuser-driveninteractionswiththebrowser.Forrunningsuchtests,we’llneedtouseanothernewtoolcalledProtractor.

    ProtractorreplacestheearlierAngularJSscenariosasthedefaultEnd-to-EndtestingframeworkfortestingAngularJSapps.

    ProtractorrunsonWebDriver.js,whichinturnmakesuseoftheSeleniumServer.Seleniumisoneofthemostpopularbrowser-automationtools.Inthissection,wewillseehowtosetupastandaloneinstanceofSeleniumServer,installProtractor,andrunadefaultsetofEnd-to-Endtestswithit.

    Let’sfirstinstallProtractorbyrunningthefollowingcommandintheterminal:

    sudonpminstall–gprotractor

    ThiswillinstallProtractorglobally.

  • InstallingSeleniumServerProtractorcomeswithahandyscriptcalledwebdriver-managerthatcanbeusedtodownloadandruntheSeleniumServer.

    Intheterminal,typeinthefollowingcommandtodownloadSeleniumServer:

    webdriver-managerupdate

    Tostarttheserver,typeinthefollowingcommand:

    webdriver-managerstart

    ThisshouldstartyourSeleniumServer.Nowopenyourbrowserandtypeinthehttp://localhost:4444/wd/hub/static/resource/hub.htmladdressintheaddressbar.ThiswillshowyouthecurrentstatusoftheSeleniumServer.

    Theprotractorfolderwithinthenode_modulescomeswithacoupleofdefaultteststhatcanhelpyoujumpstart,writingyourEnd-to-Endtests.Thesetestsarelocatedintheusr/local/lib/node_modules/protractor/examplefolder.

    Dependingonwhatyouarecomfortablewith,youcanchoosebetweenJasmineandMochaforwritingyourtestcases.Fromtheexamplefolderunderprotractor,copytheconf.jsandtheexample_spec.jsfilesandpastethemintoanewtest/protractor-testsfolder.

  • Understandingtheexample_spec.jsfileTheexample_spec.jsfileisthespecsfilewherethetestcasesarewritten.Let’sopenthisfileinaneditorandtryandmakesenseofwhatitisgoingtodo.

    Wefirstdescribeourtestsuiteasfollows:

    describe('angularjshomepage',function(){})

    Next,let’slookatthetestcase.Thefirsttestcaselookssomethinglikethefollowing:

    it('shouldgreetthenameduser',function(){browser.get('http://www.angularjs.org');

    element(by.model('yourName')).sendKeys('Julie');

    vargreeting=element(by.binding('yourName'));

    expect(greeting.getText()).toEqual('HelloJulie!');});

    Thefirstlinedescribesthetestcase.Inthenextline,wenavigatetothedefinedURL;inthiscaseweloadthewww.angularjs.orghomepage.

    Oncethehomepageisloaded,inthenextstepthecodeistryingtolocateaninputfieldboundtoamodelcalledyourNameandtypeinthetextJulie.ItthenlooksfortheexpressioncalledHello{{yourName}}andverifiesthatthetextreadsHelloJulie.

    Let’slookatthesecondtestsuite,whichhastwotestcasesasfollows:

    describe('todoList',function(){vartodoList;

    WedefinethesuitenameandinitializetodoList.NowsinceboththetestcasesneedtogotothesameURLandwillbebasedontodoList,weusebeforeEachtosettheURLandloadthecontentintoourtodoListarrayasfollows:

    beforeEach(function(){browser.get('http://www.angularjs.org');

    todoList=element.all(by.repeater('todointodos'));});

    ThefirsttestcasecheckstoseeifwehavetwoitemsintodoListandthattheseconditemiscalledbuildanangularapp.Refertothefollowingcode:

    it('shouldlisttodos',function(){expect(todoList.count()).toEqual(2);expect(todoList.get(1).getText()).toEqual('buildanangularapp');});

    ThesecondtestcasewillsimulateaddinganitemtotodolistbylocatingthetodoTextmodel,andaddinginandverifyingthetextbeingaddedasfollows:

    it('shouldaddatodo',function(){varaddTodo=element(by.model('todoText'));

    http://www.angularjs.org

  • varaddButton=element(by.css('[value="add"]'));

    addTodo.sendKeys('writeaprotractortest');addButton.click();

    expect(todoList.count()).toEqual(3);expect(todoList.get(2).getText()).toEqual('writeaprotractortest');});

    })

  • Understandingtheconf.jsfileTheconf.jsfileistheconfigurationfile.Openitinaneditorandyou’llseetheconfigurationsettingssuchasthedefaultaddressfortheSeleniumServer,thebaseURL,thebrowsertobeusedfortesting,andthelocationofyourtestcases.Now,sincewehavetheexample_spec.jsfileinthesamepathasourconf.jsfile,let’scorrectthepathofthespecstoreadasfollows:

    specs:[example_spec.js'],

    Torunourtestsuite,opentheterminalandnavigatetotheyohofolderandtypeinthefollowingcommand:

    protractortest/protractor-tests/conf.js

    Thiswilllaunchabrowserinstanceandseethestepsbeingperformedbythescript.Thebrowserwillautomaticallycloseoncethescriptisexecutedandtheterminalwindowshoulddisplaythefollowingmessage:

    Finishedinxxx.xxxxseconds

    2tests,2assertions,0failures

    NoteSometimesyoumightstartgettingerrorslikeError:ECONNREFUSEDconnectECONNREFUSED.InsuchacaserestartyourSeleniumStandaloneServerandwebserver.

  • WritingyourownProtractortestcasesNowthatweknowhowtestcasesarewritteninProtractorandhowtorunthem,let’squicklywriteacoupleofourowntestcasesagainstthedefaultscaffoldapplicationthatYeomancreatedforus.

    Let’screateanewfilecalledmytests.jsinthetestfolderunderyoho/protractor-tests.Nowwecanstartwritingoutourtestcasesasfollows:

    describe('ourhomepage',function(){})

    Thefirsttestcasewewillwriteistheonewherewe’llchecktoseeifthepageheadingwithintheh1tagssays‘AlloAllo!'.Thetestcaseforthatwouldlooksomethinglikethefollowing:

    it('shouldsayAllo',function(){browser.get('http://localhost:9000/#/');varheading=element(by.tagName('h1'))expect(heading.getText()).toEqual("'Allo,'Allo!")});

    Thebrowser.getfunctiondefinestheURLofthepageyou’dwantProtractortonavigateto.Weusetheby.tagNameselectortolocatetheh1tagandgetthetextwithinitandverifythatitmatches"'Allo,'Allo!".

    Let’swriteoursecondtestcase.Here,wewanttoensurethatthewidthofourpageiswithintherecommendedlimitsandisn’tgoingbeyondthescreensizeofmostcommonusers.Refertothefollowingcode:

    it('shouldnotbegreaterthan940px',function(){browser.get('http://localhost:9000/#/')element(by.className('container')).getSize().then(function(size){expect(size.width).toBeLessThan(950)})})

    Here,weareusingtheby.classNameselectortoidentifythecontainerdivandusingthegetSizepropertywechecktomakesurethatthewidthisnotgreaterthan950px.

    Noticethatthe.then()functionisapartofapromise,whichensuresthatthecodewaitsfortheresulttobereturned.We’llseepromisesindetailinChapter4,UsingRESTWebServicesinYourAngularJSApp.Fornow,savethefile.

    Nowthatwehaveourtestcase’sspecsfileready,weneedtocallitwithintheprotractorconfigurationfile.Let’sopentheconf.jsfileandchangethefilenameinthespecsarraytopointtoourmytest.jsfileasfollows:

    specs:['mytests.js'],

    Wearenowsettotestourscripts.First,let’sstartourserverbyrunningthefollowingcommand:

    cdyohogruntserve

  • Thisshouldstartourserver.Now,let’srunourprotractortestscriptbyrunningthefollowingcommandfromwithintheyohofolder:

    protractortest/protractor-tests/conf.js

    MakesureyouhaveyourSeleniumStandaloneServerrunning;ifnot,startitusingthefollowingcommand:

    webdriver-managerstart

    Ifallgoeswell,youcouldseetheChromebrowserbeinglaunched,andseethescriptnavigatetothelocalhost:9000/#/URLandthebrowserwindowclosingdownaftersometime.

    Switchtoyourterminaltoseethestatussayingthefollowingingreenthatmeansourtestcasesworked:

    Finishedinx.xxxseconds

    2tests,2assertions,0failures

    NoteIncaseyou’dliketorunyourtestcaseswithouthavingtolaunchthebrowserwindoweachtimeorifyou’dwanttorunitheadlessonaserver,thenhavealookatPhantomJS(http://phantomjs.org/),whichisanexcellentheadlessbrowserthatrunsontheWebKitengine.

    http://phantomjs.org/

  • SummaryThiscompletesourchapteronsettingupyourrig.Weworkedthroughquiteafewtools,namelyNode.js,Grunt,Yeoman,Karma,andProtractor.WhileIstronglyrecommendmakinguseofallofthemwhenyoubuildyourAngularJSprojects,youmayfeelfreetochoosetheonesthatsuityourprojectthebest.

    AnotherthingtonoteisthatmostofthesetoolssuchasNode.js,ExpressJS,andGruntcanbeusedforanynon-AngularJSprojects.Sogettingfamiliarwiththesetoolsissurelybeneficialforallfrontenddevelopers.

    Inthenextchapter,wearegoingtoseehowtoquicklybuildaclickableprototypeusingAngular-UI.

  • Chapter3.RapidPrototypingwithAngularJSInthepreviouschapter,wesawhowtosetupthevarioustoolsthatwillaidinbuildingourAngularJSapp.Inthischapter,wewillseehowAngularJSlendsitselfasanexcellenttooltocreateprototypes.

    RapidPrototypingisanexcellentwayofvalidatingthegoalsofthewebapplicationyouareplanningtobuild.Itgivesusefulandimportantfeedbackfromusersandstakeholdersonvariousaspectsoftheapplication,suchasuserclickflows,usabilityissues,andusefulnessoftherequirementspecificationsthatwereinitiallyoutlined.

    Inthepast,prototypeswerebuiltusingeitherwireframingtools,ordeveloperswouldcreateaseriesofHTMLpageslinkedwitheachotherthatwouldmimicthefunctioningofthewebapplication.Whiletheformernevergavetherightfeelofhowtheappwouldlookandbehave,thelatterwouldtakeamuchlongertimetobuild,especiallyifitwasalargeapplication.

    Now,thankstoAngularJS,buildingsuchprototypeshasbecomealoteasier,andonecanbuildnearlyfunctionalprototypewithinashorttimeframeandwithsignificantlylesscode.

    Inthischapter,wewilldothefollowing:

    RunthroughthevariouscomponentsoftheapplicationthatwearegoingtoprototypeUnderstandGridLayoutsandseehowBootstrapworksAddUIcomponentssuchascarousels,accordions,andmodalwindowsusingAngularUILearnthemodularwaytobuildpagesusingpartialsCreatedummydatamodelstosimulatedynamicdataUseroutestolinkthecontrollerstotheviews

  • UnderstandingtheapplicationthatwewillPrototypeWewillcreateaclickableprototypeofapseudowebappnamedHealthyLiving.Itwillconsistoffourpages.Theyareasfollows:

    Homepage:Thiswillconsistofacarousel,herounit,andthreemaincontentblocks.Articles:Thisdisplayalistofarticlesinanaccordionview.Gallery:Thisisanimagegallerypagewithpictures,atitle,ashortdescription,andastarrating.Subscribers:ThispagewilldisplaythelistofsubscribersinaninteractivedatagridwithfeaturestogroupbyacolumnandExcel-styleinlineediting.Thesubscriptionpagewillalsohaveabuttonthatwillallowustoaddanewuserviaamodalwindow.

  • IntroducingGridLayoutsandBootstrapBuildingHTMLpageshadalwaysbeenawebdesigner’sjob,andprogrammerswouldrunmilesawayifaskedtobuildanHTMLpage.

    AnotherproblemwithdesigningHTMLpagesisthateverydesignerhastheirownsecretrecipetocreateanHTMLpage,usingtheirownstructuretolayouttheDOMelementsandtheirfavoriteCSSclassnames.ThiscausesquiteananguishwhendeveloperstakeoverHTMLtoputinthedynamiccode,orwhentwodesignersareworkingonthesameproject.

    TheGridLayoutsevolvedasameanstohelpgeteverybodyonthesamepageintermsofnamingconventionsandtheDOMstructure,andmoreimportantly,toreducethetimetakentobuildHTMLpageswhileensuringafairamountofbrowsercompatibilityatthesametime.

    Whilegridsystemssuchasthe960GridSystemandBlueprintwereamongtheearlygridsystemsavailable,nowadays,Bootstrap,Foundation,andSemanticUIhavebecomeverypopulartoolstobuildfrontendpages.

    Atthetimeofwritingthisbook,theversionofBootstrapthatiscompatiblewithAngularUIis3.1.x,andwewillbeusingthistobuildourprototype.

  • UnderstandingthegridsystemOflate,gridsystemshavebeenextensivelyusedinweb-developmentworkflows.GridsystemsaimtostreamlinetheHTMLmarkupprocessbyprovidingastandardsetofdimensionsanddisplaystylesforthecommonlyusedUIelements.Thefollowingscreenshotshowsagridsystem:

    Bootstraphasadefault12-columngridsystemthatisavailableasaresponsive,fluid,andfixedlayout.ItcomeswithacompletesetofpredefinedclassesthatmeetsnearlyallyourUIstylingneeds.

    Someofthemostcommonlyusedclassesarementionedinthefollowingtable:

    Class Description

    .col-md-* Thisisforcolumnwidthsthatareappliedtoacontentblockformediumscreendevicessuchasdesktopswithresolutionsgreaterthanorequalto992pxwide.

    .col-xs-* Thisisforsmalldeviceswithawidthof768pxorless.

    .col-sm-* Thisisfortabletdeviceswithasizeof768pxormore.

    .col-lg-* Thisisforlargedeviceswithsizesgreaterthanorequalto1200px.

    .col-md-offset-* Theoffsetclassisusedtoleavecolumnspacingfromtheleft.

    .row

    .row-fluidThe.rowclassisusedtoseparatethedatarowwise.The.row-fluidclassisusedincaseofafluidlayout.

    .container

    .container-fluid

    The.containerclasswillsettheelementwidthto940pxandwillcenterithorizontallywithrespecttothepage.The.container-fluidclassisusedincaseofafluidlayout.

    .lead Thisisusedtomakeaparagraphstandout.Itismostcommonlyusedwithinaherounitortodisplaythepagesummaryunderthepageheading.

    .text-left

    .text-center

    .text-rightTheseareusedtoalignthetexttotheleft,centerandrightrespectively.

  • Theandtagsareusedtoquotesomebody,andtheandtagsareusedtowrapthenameofthesource.

    .pull-left

    .pull-rightTheseareusedtofloatanelementandpushiteithertotheleftorrightofitsboundingcontainer.

    .btnprimary

    .btn-success

    .btn-info

    .btn-warning

    .btn-danger

    .btn-inverse

    Theseareusedtostylethebuttonsoranchorelements;theseclassesapplydifferentcolorstothebuttonrangingfrombluetoblack.

    Atthemostminimum,BootstrapcomeswithaCSSandJavaScriptfilealongwithanimage(/img)foldercontainingtheglyphicons.TheCSSfilecontainsallthestylesforthegridsystemandthepredefinedclassesforthevariousUIcomponents.JavaScriptcontainsthelibrariestobuildUIwidgetssuchasaccordions,tabs,modalwindows,progressbars,datepickers,andsoon.

  • IntroducingAngularUIAngularUIisabunchofminiprojectsthathelpsyoubemoreproductivewithyourAngularappdevelopment.Atthetimeofwritingthisbook,AngularUIconsistedofprojectsdiscussedinthefollowingsections.

  • UI-UtilsUI-Utilsisautilitypackagethatallowsyoutoaddawidevarietyofutilitiesintoyourapplication.Theutilitiesareexplainedasfollows:

    IEShiv:ThisisusedtoallowsupportforcustomtagsinIE8andbelow.jQueryPassthrough:TheuiJqdirectiveallowsustousejQuerypluginsdirectlyinsteadofhavingtocreatenewdirectivestousethem.EventBinder:ThisallowsyoutobindcallbackstoeventsthatarenotnativelysupportedinAngularJS.Keypress:Thisallowsyoutobindeventstoakeypress.Mask:Thisallowsyoutomaskdatabasedoncertainconditionsset.Validate:ThisallowsyoutocreatecustomvalidatorsandexpressionsReset:Thisallowsyoutodisplayaniconorlink;ifyouclickonit,themodelwillbecomeempty.Scrollfix:Thisaddsaui-scrollfixclasstotheelement.Show/Hide/Toggle:Thisallowsyoutouseasingledirectiveofui-toggleinsteadofusingng-showandng-hide.RouteMatching:Thisisaniftylittledirectivethatcanbeusedtomatchtherouteofthecurrentpage.Highlight:Thisisusedtohighlightastringofcharacterswithinascopemodel.Inflector:ThiswillhelpyouconvertastringintoalternativeformatssuchasreplacespaceswithunderscoresorconvertthestringintoacamelCasesyntax.Unique:Thiscanbeusedtoremoveallduplicateitemsfromwithinanarray.Format:Thisfiltercanbeusedtodoanykindofstringreplacement.

  • UI-ModulesTheUI-ModulesprojectallowsyoutoeasilyaddCalendarControls,GoogleMaps,andabunchofeditorssuchasTinyMCEandCodeMirrorAce.

  • UI-BootstrapUI-BootstrapisthenativeimplementationofTwitterBootstrapwithinAngular.Aswe’llseefurtherinthischapter,addingUIcontrols,suchascarousels,accordions,andtabs,isabreezeusingUI-Bootstrap.ItisworthnotingthatUI-BootstrapusestheoriginalCSSandglyphiconsofBootstrapastheyare.It’sonlytheJavaScriptfilethathasbeenrewrittentousenativeAngulardirectives.

  • NG-GridNG-GridallowsyoutoadddatagridsinyourAngularapp.NG-GridcomeswithquiteafewcustomizationoptionsthatallowyoutoplacegridswithsortablecolumnstofeaturessuchasExcel-styleediting,inplace.

  • UI-RouterUI-RouterisanewwayofroutingthatallowsyoutocreateNestedRouting.

  • IDEPluginsIDEPluginsareabunchofpluginsorextensionsthatprovideAngularJSsupportinvarioustexteditors.

    Aswemoveaheadinthechapter,wewillmakeextensiveuseoftheUI-BootstrapandNG-Gridprojects.

  • PrototypingtheHealthyLivingwebsiteForthisexercise,wearegoingtocreateafour-pageclickableprototypeofapseudowebsitecalledHealthyLiving.Thehomepagewillconsistofafullyfunctionalcarousel,herounit,andthreecontentsectionswithcalltoactions.Thefollowingscreenshotisthatofthehomepage:

    Let’sgetstartedwiththecreationofourapplication.We’llstartbyperformingthefollowingsteps:

    1. Createafoldernamedhl,shortfor“HealthyLiving”.2. AssumingthatyouhavealreadyinstalledYeoman,openuptheterminal.Let’screate

    thescaffoldingforourappusingthefollowinglinesofcode:

  • mkdirhlcdhlyoangular

    NoteGenerator-AngularmustbeinstalledbeforeyoucanrunyourAngularapp.Incaseyouhaven’tinstalleditduringChapter2,SettingUpYourRig,pleaseinstallitusingthefollowingcommand:

    sudonpminstall–ggenerator-angular

    3. Intheprompt,pressYforthequestion,WouldyouliketoincludeTwitterBootstrap?.

    4. Forthequestion,WouldyouliketouseSass(withCompass)?,pressN.5. Forthethirdquestion,pressEntertoacceptthedefaultsettings.

    NoteUsingaCSSpreprocessorsuchasSASSorLESSisalwaysagoodpracticeasitallowsyoutousevariablesandmixinsinCSS,ensuringthatyourCSSremainsmodularandfollowsDRY(Don’tRepeatYourself)principals.However,coveringthemisbeyondthescopeofthisbook.

    Youshouldbeseeingnpmpullingabunchoffilesandcreatingthescaffoldofyourapp.Waitpatientlyuntilitisalldoneandyouarereturnedbacktothecommandprompt.

    Youshouldnowbeabletoseethestructureofyourapplicationwiththedefaulthomepage.

    AswearegoingtobeusingUI-Bootstrap,let’sinstallitusingBower.

    6. Firethefollowingcommandintheterminal:

    bowerinstallangular-bootstrap

    Thiswillcreatetheangular-bootstrapfolderwithintheapp/bower_componentsfolder.

    TobeabletouseAngularBootstrapinourapplication,weneedtoincludetheJSfile.

    7. Let’sopenuptheapp/index.htmlfileandaddthefollowinghighlightedline.

    Ifyoulookintothebower_components/angular-bootstrapfolder,you’llnoticetherearethefollowingtwotypesoffilesalongwiththeirminifiedversions:

    ui-bootstrap.js:Thiscontainsallthedirectives,butitdoesn’tcontainanytemplates.Itmakessensetousethisfileifyoudonotwanttousethedefaulttemplatesbutwanttocustomizeyourtemplatesfromscratch.

  • ui-bootstrap-tpls.js:Thiscontainsallthedirectivesalongwiththedefaulttwitterbootstraptemplatecode.Ifyouarenotlookingtomakeanycustomization,thenitsbesttoincludethisfileinyourproject.

  • Addingtheui.bootstrapdependencyThenextstepistoaddtheAngularBootstrapdependencytotheAngularapp.

    Wedothisbymodifyingthefollowinglineintheapp/scripts/app.jsfile:

    angular.module('hlApp',['ui.bootstrap'])

    Now,angular-bootstrapwillbeavailableforuseacrossourapplication.

  • CreatingthenavigationbarTocreatethenavigationbar,let’sopenuptheapp/index.htmlfileandaddthepartofthecode,whichisshownasfollows:

    HealthyLiving

    ArticlesGallerySubscribers

    Asyoucanseefromtheprecedingcode,wedefinedtheheadertagandappliedtheCSSclasses,navbarandnavbar-fixed-top,toit.ThesearepredefinedbootstrapCSSclassesthatareusedtostylethenavigationbar.

    ThenavbarclassisadefaultcontainerthatsetstheoverflowtovisibleforallelementswithinthenavbarDOM.

    Thenavbar-fixed-topclasswillmakethenavigationbarsticktothetopofthepage,anditwillstayfixedevenasthepagescrolls.Youcanalsousenavbar-fixed-bottomtomakeyournavigationbarsticktothebottomofthepage.

    Now,we’lladdthetagwithaclassnamedcontainer.Thecontainerclasswillsetthewidthofthiselementto940pxandalsocentertheelementhorizontallyonthepage.

    WewilladdourHealthyLivingwebsitewithinananchortagandgiveitaclassnamednavbar-brand,asthisiswhatourbrandnameissupposedtobe.

    NavigationlinksfortheArticles,Gallery,an