javascript for .net developers - programmer-books.com · he wrote a book in 2013 on web development...

447

Upload: others

Post on 15-Oct-2019

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer
Page 2: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

JavaScriptfor.NETDevelopers

Page 3: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

TableofContents

JavaScriptfor.NETDevelopersCreditsAbouttheAuthorAbouttheReviewerwww.PacktPub.com

eBooks,discountoffers,andmoreWhysubscribe?

PrefaceWhatthisbookcoversWhatyouneedforthisbookWhothisbookisforConventionsReaderfeedbackCustomersupport

DownloadingtheexamplecodeDownloadingthecolorimagesofthisbookErrataPiracyQuestions

1.JavaScriptforModernWebApplicationsImportanceofJavaScript

WhatisJavaScript?Comparingruntimes

SettingupyourenvironmentNeweditingexperienceofJavaScriptinVisualStudio2015IDE

ProgramminginJavaScriptCorefundamentalsofJavaScript

AddingJavaScripttoanHTMLpageStatementsinJavaScriptLiteralsandvariablesDatatypes

ArrayinJavaScriptWhatisJSON?

SimpleobjectsinJSONDeclaringarraysinJSONNestingdatainJSON

ConversionsindatatypesElementsofJavaScript

ConstantsinJavaScriptCommentsCasesensitivity

Page 4: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CharactersetExpressions

ThethiskeywordSequenceofcodeexecutioninJavaScriptUsingthethiskeywordonacallingmethodThefunctionstatementandexpressionClassstatementandexpressionGroupingoperatornewsuper

OperatorsAssignmentoperatorsArithmeticoperatorsUnaryoperatorsComparisonoperators

StrictequaloperatorStrictnotequaloperator

LogicaloperatorsLogicalANDLogicalORLogicalNOT

BitwiseoperatorsBitwiseANDBitwiseORBitwiseNOTBitwiseXOR

BitwiseshiftoperatorsBitwiseleftshiftBitwiserightshift

ThetypeofoperatorThevoidoperatorThedeleteoperatorMiscellaneousoperators

ConditionaloperatorsSpreadoperator

Built-indisplaymethodsinJavaScriptDisplayingmessages

AlertboxConfirmboxPromptbox

WritingonapageWritingintothebrowser'sconsolewindow

BrowserObjectModelsinJavaScriptWindow

Page 5: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DocumentNavigator

PropertiesScreen

PropertiesHistory

MethodsLocation

PropertiesMethods

Summary2.AdvancedJavaScriptConcepts

Variables–scopeandhoistingDeclaringlet

ConditionswhereletisefficienttouseFunctionsinloops

EventsinJavaScriptFunctionargumentsObject-orientedprogramminginJavaScript

CreatingobjectsDefiningobjectsusingobjectliteralnotationDefiningobjectsusingaconstructorpattern

UsingtheclasskeywordProperties

DefiningpropertiesusingobjectliteralnotationDefiningpropertiesusingaconstructorpatternDefiningpropertiesusingsetters/gettersinECMAScript6JavaScriptpropertydescriptors

DisplaypropertydescriptorsManagingpropertydescriptorsUsinggettersandsetters

MethodsDefiningmethodsthroughobjectliteralnotationapproachDefiningobjectsusingtheconstructorfunctionapproach

ExtendingpropertiesandmethodsPrivateandpublicmembersInheritance

ChainingconstructorsinJavaScriptInheritanceusingObject.create()PredefinedpropertiesofObject.create()Defininginheritanceusingclass

EncapsulationAbstractionnew.target

Page 6: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

NamespaceExceptionhandling

ErrorRangeErrorReferenceErrorSyntaxErrorTypeErrorURIError

ClosuresPracticaluse

JavaScripttypedarraysTypedarrayarchitecture

ThearraybufferCreatingabuffer

Maps,sets,weakmaps,andweaksetsMapsandweakmapsSetsandweaksetsThestrictmode

Summary3.UsingjQueryinASP.NET

GettingstartedwithjQueryUsingacontentdeliverynetwork

TheuseofCDNThedocumentreadyeventThejQueryselectors

SelectingtheDOMelementsusingtheIDSelectingtheDOMelementsusingTagNameSelectingnodesbytheclassnameSelectingbytheattributevalueSelectinginputelementsSelectingalltheelementsSelectingthefirstandlastchildelementsThecontainsselectorinjQuerySelectingtheevenandoddrowsselectors

ManipulatingDOMModifyinganelement'spropertiesCreatingnewelementsRemovingelementsandattributes

EventhandlinginjQueryRegisteringeventsinjQueryBindingeventsusingonandoffUsingthehoverevents

Summary4.AjaxTechniques

Page 7: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

IntroducingAjaxHowAjaxworks

AjaxrequestsusingtheclassicXHRobjectXHRmethodsXHReventsXHRproperties

MakinganAjaxrequestusingjQueryjQuery.ajax()

AjaxpropertiesPre-filteringAjaxrequestsSettingdefaultvaluesforallfutureAjaxrequests

LoadingdatathroughthegetfunctionsinjQueryUsingjQuery.get()UsingjQuery.getJSON()UsingjQuery.getScript()

PostingdatatoserverusingthepostfunctionAjaxevents

LocaleventsGlobalevents

Cross-originrequestsJSON-P

UsingJSON-PCORS

SpecifyingtheCORSpolicyatserviceslevelEnableCORSattheConfiguremethod

CallingWCFservicesfromJavaScriptSummary

5.DevelopinganASP.NETApplicationUsingAngular2andWebAPITypeScript

CompilationarchitectureofTypeScriptAdvantagesofTypeScript

SupersetofJavaScriptSupportforclassesandmodulesStatictypecheckingECMAScript6featuresupportOptionaltypingDeclaringtypesinTypeScript

CoreelementsofTypeScriptDeclaringvariablesTypesClassesandinterfaces

DefininginterfacesDerivingclassesandinterfacesGenericclasses

Page 8: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

FunctionsGenericfunctions

IteratorsModulesandnamespaces

IntroductiontoAngular2Angular2architecture

EventsofcomponentlifecycleModulesComponents

CorepropertiesofAngular2componentsTemplatesandselectorsInputsandoutputs

UsinginputsUsingoutputs

DirectivesCreatingasimpleHelloWorlddirective

StructuraldirectivesAttributedirectiveProviders

DependencyinjectioninAngularRoutinginAngular

Developingato-doapplicationinASP.NETCoreCreatingaCommonprojectCreatingaTodoServiceAppproject

EnablingMVCinaWebAPIprojectInstallingEntityFrameworkAddingAppSettingstostoreaconnectionstringConfiguringAppSettingsintheStartupclassAddingdataaccessinWebAPIEnablingCORSintheASP.NETWebAPIRunningdatabasemigrationCreatingacontroller

CreatingaTodoWebAppprojectConfiguringAngular2intheTodoWebAppprojectDependencies

DevelopmentdependenciesConfiguringTypeScriptConfiguringGulp

AddingAngularcomponentsAddingtheto-doservicecomponentAddingato-doviewcomponent

Creatingthemainto-dopageCreatingacustomto-dotaghelperAddingato-doMVCcontroller

Page 9: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

GeneratingviewsfortheTodoControlleractionmethodsDevelopingtheCreateTodocomponent

Summary6.ExploringtheWinJSLibrary

IntroductiontoWinJSWinJSfeatures

JavaScriptcodingandlanguagepatternsStylesheetsWindowsruntimeaccessSecurityAppmodelDatabindingControlsUtilities

UsageofWinJSAddingtheWinJSlibraryintheASP.NETapplication

CDNNPMNuGet

GettingstartedwithWinJSUsingWinJSintheASP.NETapplicationExistingWindowsapptemplateinVisualStudio

ExploringWinJScorefundamentalsClassesandnamespaces

DefiningclassesinWinJSDerivingclassesinWinJSNamespacesinWinJS

MixinEventsinWinJSDatabinding

OnetimedatabindingOnewaydatabindingTwowaydatabindingAdatabindingworkingmodel

PromisesOtheroperationsofpromises

ChainingpromisesandhandlingerrorsCancelingpromisesJoiningpromisesCheckingpromiseWrappingnon-promiseintopromise

ExploringWinJScontrolsandstylesAddingWinJScontrolsSettingpropertiesofWinJScontrols

Page 10: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UsingWindowsruntimefeaturesHostedappsandaccessingthecamera

CreatingtheASP.NETcoreapplicationConvertinganASP.NETapplicationintoWindowsapplicationusingtheHostedapp

conceptSummary

7.JavaScriptDesignPatternsCreationalpatterns

SingletondesignpatternFactorypatternAbstractfactorypatternPrototypepattern

StructuralpatternsAdapterpatternDecoratorpatternFacadepatternBridgepattern

BehavioralpatternChainofresponsibilitypatternObserverpatternPub/subpatternPromises

Summary8.Node.jsforASP.NETDevelopers

IntroductiontoNode.jsRequestprocessingbytheNode.jswebserverComparisonofNode.jswith.NETNPM

InstallingNode.jsUsingNode.jswithVisualStudio2015

SimpleconsoleapplicationusingNode.jsWebapplicationswithNode.jsCreatingblankNode.jsapplicationsUsingtheExpressframeworkforwebapplicationsinNode.js

ExtendsimpleNode.jstouseExpressExpressviewengines

EJSviewengineJadeviewengineRoutingintheExpressapplication

MiddlewareMVCwiththeExpressframework

MVCpatternCreatingacontrollerCreatingdataservices

Page 11: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AccessingtheMicrosoftSQLserverinNode.jsReadingarecordfromtheMicrosoftSQLserverdatabaseCreatingarecordintheMicrosoftSQLserverdatabase

Summary9.UsingJavaScriptforLarge-ScaleProjects

ThinkbeforeproceedingDevelopinghighlyscalableandmaintainableapplications

ModularizationImplementingthemodulepatternModularizingJavaScriptcodethroughRequireJS

CreatingmodulesusingtheRequireJSAPIBootstrappingRequireJS

Event-drivenmessagingImplementingmediatorpatternforcommunicationbetweenmodules

EncapsulatingcomplexcodeGeneratingdocumentation

InstallingJSDoc3inASP.NETCoreAddingcomments

DeploymentoptimizationSummary

10.TestingandDebuggingJavaScriptTestingtheJavaScriptcode

UnittestingWritingunittests

JasmineKarmaGrunt

DevelopingunittestusingJasmine,Karma,andGruntAddingpackagesAddingtheGruntfile

AddingKarmaspecificationsLoadnpmtaskRegistertask

SourceJavaScriptfileAddingunittestscriptfileRunningtesttaskImplementingModel-View-ViewModelusingKnockoutandRuntest

AddingtheKnockoutpackageAddingProductViewModelAddtheProductviewModifyingtestconfigurationModifyingtheproduct-testingscript

DebuggingJavaScriptDebuggingoptionsinVisualStudio2015

Page 12: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DebuggingfromVisualStudiowithInternetExplorerDebuggingfromVisualStudiowithGoogleChromeDeveloperTools

DebuggingoptionsinMicrosoftEdgeStandardbreakpointsConditionalbreakpointsTracepointsEvent

AddeventtracepointAddeventbreakpoints

XHRDebuggingTypeScriptDebuggerkeywordsupportedbyallbrowsers

SummaryIndex

Page 13: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

JavaScriptfor.NETDevelopers

Page 14: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

JavaScriptfor.NETDevelopersCopyright©2016PacktPublishing

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

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

PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.

Firstpublished:July2016

Productionreference:1260716

PublishedbyPacktPublishingLtd.

LiveryPlace

35LiveryStreet

BirminghamB32PB,UK.

ISBN978-1-78588-646-1

www.packtpub.com

Page 15: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CreditsAuthor

OvaisMehboobAhmedKhan

Reviewer

NicholasSuter

CommissioningEditor

EdwardGordon

AcquisitionEditor

NitinDasan

ContentDevelopmentEditor

DeeptiThore

TechnicalEditors

PranilPathare

DeeptiTuscano

CopyEditor

VibhaShukla

ProjectCoordinator

ShwetaHBirwatkar

Proofreader

SafisEditing

Indexer

MariammalChettiyar

Graphics

Page 16: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DishaHaria

ProductionCoordinator

NileshMohite

CoverWork

NileshMohite

Page 17: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AbouttheAuthorOvaisMehboobAhmedKhanisaseasonedprogrammerandsolutionarchitectwithmorethan13yearsofsoftwaredevelopmentexperience.HehasworkedindifferentorganizationsacrossPakistan,theUSA,andtheMiddleEast.Currently,heisworkingforagovernmententitybasedinDubai,andalsoprovidesconsultancyservicestoaMicrosoftgoldpartnerfirmbasedinNewJersey.

HeisaMicrosoftMVPinVisualStudioandDevelopmentTechnologiesandspecializesmainlyinMicrosoft.NETandwebdevelopment.HehasauthorednumeroustechnicalarticlesondifferentwebsitessuchasMSDN,TechNet,DZone,andpersonalblogathttp://ovaismehboob.wordpress.com.

HeisanactivespeakerandgroupleaderofMicrosoftDevelopersUAEMeetup,MicrosoftTechnologyPractices,andDevelopersandEnterprisePracticesusergroups,andhaspresentedvarioustechnicalsessionsindifferenteventsandconferences.

Inshort,Ovaisisapassionatedeveloperwhoisalwaysinterestedinlearningnewtechnologies.Hecanbereachedat<[email protected]>andonTwitter,@ovaismehboob.

Iwouldliketothankmyfamilyforsupporting.Especiallymymother,wife,andbrother,whohavealwaysencouragedmeineverygoalofmylife.Myfather,mayherestinpeace,wouldhavebeenproudofmyachievements.

Page 18: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AbouttheReviewerNicholasSuterisa.NETsoftwarecraftsman,focusedonpatterns,practices,andqualitydevelopmentinaMicrosoftenvironment.HehasbeennominatedforMicrosoft.NETMVPsince2014.

HeworksforCellenza,aFrenchagileconsultingcompanybasedinParis,whereheleads,trains,andauditsteamsmoreontechnicalmattersthanteampractices.

Hewroteabookin2013onwebdevelopmentcalledVisualStudio2013,ConcevoiretdévelopperdesprojetsWeb,lesgéreravecTFS2013,(French)forENIEditions,andreviewedEntityFrameworkTutorial,SecondEdition,forPacktPublishingin2015.

Page 19: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

www.PacktPub.com

Page 20: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

eBooks,discountoffers,andmoreDidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusat<[email protected]>formoredetails.

Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.

https://www2.packtpub.com/books/subscription/packtlib

DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt'sonlinedigitalbooklibrary.Here,youcansearch,access,andreadPackt'sentirelibraryofbooks.

Page 21: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser

Page 22: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

PrefaceThisisabookabouttheJavaScriptprogramminglanguage,andistargetedat.NETdeveloperswhowanttodevelopresponsivewebapplicationsusingpopularclient-sideJavaScript-basedframeworksandcreatearichuserexperience.ItisalsointendedforprogrammerswhohaveabasicknowledgeoftheJavaScriptprogramminglanguageandwantedtolearnsomecoreandadvancedconceptsfollowedbysomeindustry-widebestpracticesandpatternstostructureanddesignwebapplications.

ThisbookstartswiththebasicsofJavaScriptandhelpsthereadertogainknowledgeaboutthecoreconceptsandthenproceedstowardssomeadvancedtopics.ThereisachapterthatprimarilyfocusesonthejQuerylibrary,whichiswidelyusedthroughoutwebapplicationdevelopment,followedbyachapteronAjaxtechniquesthathelpdeveloperstounderstandhowasynchronousrequestscanbemade.ThisisfollowedbytheoptionstomakerequestseitherthroughtheplainvanillaJavaScriptXHRobjectorthroughthejQuerylibrary.ThereisalsoachapterthatdevelopsacompleteapplicationusingAngular2andASP.NETCore,andintroducesTypeScript,asupersetofJavaScriptthatsupportsthelatestandevolvingfeaturesofECMAScript2015.WewillalsoexploretheWindowsJavaScript(WinJS)librarytodevelopWindowsapplicationsusingJavaScriptandHTMLandusethislibrarytobringWindowsbehavior,look,andfeeltoASP.NETwebapplications.ThereisacompletechapteronNode.jsthathelpsdeveloperstolearnhowpowerfultheJavaScriptlanguageisontheserverside,followedbyachapteronusingJavaScriptinalarge-scaleproject.Finally,thisbookwillendwithachapterabouttestinganddebugginganddiscusswhattestingsuitesanddebuggingtechniquesaretheretotroubleshootandmakeanapplicationrobust.

Thisbookhassomeverydensetopicsthatrequirefullconcentration,henceisidealforsomeonehavingsomepriorknowledge.AllthechaptersarerelatedtoJavaScriptandworkaroundJavaScriptframeworksandlibrariestobuildrichwebapplications.Withthisbook,thereaderwillgettheend-to-endknowledgeabouttheJavaScriptlanguageanditsframeworksandlibrariesbuiltontopofit,followedbythetechniquestotestandtroubleshoottheJavaScriptcode.

Page 23: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WhatthisbookcoversChapter1,JavaScriptforModernWebApplications,focusesonthebasicconceptsofJavaScriptthatinvolvedeclarationofvariables,datatypes,implementingarrays,expressions,operators,andfunctions.WewillwritesimpleprogramsinJavaScriptusingVisualStudio2015,andseewhatthisIDEoffersforwritingJavaScriptprograms.WewillalsostudyhowJavaScriptcodecanbewrittenandcomparethe.NETruntimewiththeJavaScriptruntimetoclarifytheexecutioncycleofcode-compilationprocess.

Chapter2,AdvancedJavaScriptConcepts,coverstheadvancedconceptsofJavaScriptandgivesdevelopersaninsightintotheJavaScriptlanguage.ItwillshowtheextenttowhichtheJavaScriptlanguagecanbeusedasfarasfeaturesareconcerned.Wewilldiscussvariableshoistingandtheirscope,propertydescriptors,object-orientedprogramming,closures,typedarrays,andexceptionhandling.

Chapter3,UsingjQueryinASP.NET,discussesjQueryandhowtouseitinwebapplicationsdevelopedinASP.NETCore.WewilldiscusstheoptionsjQueryprovidesandtheadvantagesithaswhencomparingitwiththeplainvanillaJavaScriptformanipulatingDOMelements,attachingevents,andperformingcomplexoperations.

Chapter4,AjaxTechniques,discussesthetechniquesofmakingasynchronousrequestsknownasAjaxrequests.WewillexplorethecoreconceptsofusingtheXMLHttpRequest(XHR)objectandstudythebasicarchitectureofhowAjaxrequestisprocessedandtheeventsandmethodsitprovides.Ontheotherhand,wewillalsoexplorewhatthejQuerylibraryprovidesincomparisonwiththeplainXHRobject.

Chapter5,DevelopinganASP.NETApplicationUsingAngular2andWebAPI,teachesthebasicconceptsofTypeScriptandusesitwithAngular2.WewilldevelopasimpleapplicationinASP.NETCoreusingAngular2asafrontendclient-sideframework,WebAPIforbackendservices,andEntityFrameworkCorefordatabasepersistence.Atthetimeofwriting,Angular2wasinabetaversion,andwehaveusedthebetaversioninthischapter.WiththefuturereleasesofAngular2,therearechancesofhavingsomechangesintheframework,butthebasicconceptswillalmostbethesame.Forfutureupdates,youcanrefertohttp://angular.io/.

Chapter6,ExploringtheWinJSLibrary,explorestheMicrosoftdevelopedWinJSlibrary,whichisaJavaScriptlibrarytonotonlydevelopWindowsapplicationsusingJavaScriptandHTML,butalsouseitwithASP.NETandotherwebframeworks.Wewilldiscussthecoreconceptsofdefiningclasses,namespaces,derivingclasses,mixins,andpromises.Wewillalsolookintothedata-bindingtechniquesandhowtouseWindowscontrolsorspecificattributesinHTMLelementstochangethebehaviour,look,andfeelofthecontrol.Moreover,wewillendupusingtheWinRTAPItoaccessadevice'scamerainourwebapplicationanddiscusstheconceptsofaHostedappthroughwhichanywebapplicationcanbetransformedintoaWindowsapplicationusingaUniversalWindowtemplateinVisualStudio2015.

Page 24: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter7,JavaScriptDesignPatterns,showsthatdesignpatternsprovideefficientsolutionstosoftwaredesign.Wewilldiscusssomeoftheindustry-widebestdesignpatternsspreadintocreational,structural,andbehavioralcategories.EachcategorywillbecoveringfourtypesofdesignpatternsthatcanbeusedandimplementedusingJavaScripttosolveaparticulardesignproblem.

Chapter8,Node.jsforASP.NETDevelopers,focusesonthebasicsofNode.jsandhowtouseittodevelopserver-sideapplicationsusingJavaScript.Inthischapter,wewilldiscussviewenginessuchasEJSandJadeandtheuseofcontrollersandservicestoimplementtheMVCpattern.Moreover,wewillendthischapterbyperformingsomeexamplesofaccessingaMicrosoftSQLServerdatabasetoperform,create,andretrieveoperationsonadatabase.

Chapter9,UsingJavaScriptforLarge-ScaleProjects,providesbestpracticesofusingJavaScriptforlarge-scaleapplications.WewilldiscusshowtostructureourJavaScript-basedprojectsbysplittingthemintomodulestoincreasethescalabilityandmaintainability.WewillseehoweffectivelywecanusetheMediatorpatterntoprovidecommunicationbetweenmodulesandthedocumentationframeworksthatincreasethemaintainabilityofyourJavaScriptcode.Finally,wewilldiscusshowtheapplicationcanbeoptimizedbycompressingandmergingJavaScriptfilesintoaminifiedversionandincreaseperformance.

Chapter10,TestingandDebuggingJavaScript,focusesonthetestinganddebuggingJavaScriptapplications.WewilldiscussoneofthemostpopulartestingsuitesofJavaScriptcodeknownasJasmine,anduseitwithKarmatorunthetestcases.Fordebugging,wewilldiscusssometipsandtechniquestodebugJavaScriptwithVisualStudioandwhatMicrosoftEdgeofferstomakedebuggingeasy.Intheend,wewillstudythebasicconceptsofhowMicrosoftEdgeenablesdebuggingforTypeScriptfilesandtheconfigurationneededtoachieveit.

Page 25: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WhatyouneedforthisbookThroughoutthebook,wewillbeusingVisualStudio2015topracticeexamples.Fortheserver-sidetechnology,wehaveusedASP.NETCoreforwebapplicationdevelopment,andusedJavaScriptontopofit.InChapter8,Node.jsforASP.NETDevelopers,weusedNode.jstoshowhowJavaScriptcanbeusedontheserverside.ForNode.js,wewillrequiresomeextensionsforVisualStudio2015tobeinstalled,andthedetailsarespecifiedinthechapter.

Page 26: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WhothisbookisforThisbookistargetedat.NETdeveloperswhohavesolidprogrammingexperienceinASP.NETCore.Throughoutthisbook,wehaveusedASP.NETCoreforwebdevelopmentandassumedthatdevelopershavethoroughknowledgeorworkingexperiencein.NETCoreandASP.NETCore.

Page 27: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ConventionsInthisbook,youwillfindanumberoftextstylesthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestylesandanexplanationoftheirmeaning.

Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:"JavaScriptcanbeplacedinthe<head>or<body>sectionsofyourHTMLpage."

Ablockofcodeissetasfollows:

<html>

<head>

<script>

alert("Thisisasimpletext");

</script>

</head>

</html>

Anycommand-lineinputoroutputiswrittenasfollows:

dotnetefdatabaseupdate–verbose

Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,forexample,inmenusordialogboxes,appearinthetextlikethis:"Whenthepageloads,itwillshowthepop-upmessageandatextasThisisasimpletext."

Note

Warningsorimportantnotesappearinaboxlikethis.

Tip

Tipsandtricksappearlikethis.

Page 28: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedordisliked.Readerfeedbackisimportantforusasithelpsusdeveloptitlesthatyouwillreallygetthemostoutof.

Tosendusgeneralfeedback,simplye-mail<[email protected]>,andmentionthebook'stitleinthesubjectofyourmessage.

Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideatwww.packtpub.com/authors.

Page 29: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.

Page 30: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

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

Youcandownloadthecodefilesbyfollowingthesesteps:

1. Loginorregistertoourwebsiteusingyoure-mailaddressandpassword.2. HoverthemousepointerontheSUPPORT tabatthetop.3. ClickonCodeDownloads&Errata.4. EnterthenameofthebookintheSearchbox.5. Selectthebookforwhichyou'relookingtodownloadthecodefiles.6. Choosefromthedrop-downmenuwhereyoupurchasedthisbookfrom.7. ClickonCodeDownload.

YoucanalsodownloadthecodefilesbyclickingontheCodeFilesbuttononthebook'swebpageatthePacktPublishingwebsite.Thispagecanbeaccessedbyenteringthebook'snameintheSearchbox.PleasenotethatyouneedtobeloggedintoyourPacktaccount.

Oncethefileisdownloaded,pleasemakesurethatyouunziporextractthefolderusingthelatestversionof:

WinRAR/7-ZipforWindowsZipeg/iZip/UnRarXforMac7-Zip/PeaZipforLinux

ThecodebundleforthebookisalsohostedonGitHubathttps://github.com/PacktPublishing/JavaScript-For-.NET-Developers.Wealsohaveothercodebundlesfromourrichcatalogofbooksandvideosavailableathttps://github.com/PacktPublishing/.Checkthemout!

Page 31: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DownloadingthecolorimagesofthisbookWealsoprovideyouwithaPDFfilethathascolorimagesofthescreenshots/diagramsusedinthisbook.Thecolorimageswillhelpyoubetterunderstandthechangesintheoutput.Youcandownloadthisfilefromhttps://www.packtpub.com/sites/default/files/downloads/JavaScriptForNETDevelopers_ColorImages.pdf

Page 32: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyoucouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedtoourwebsiteoraddedtoanylistofexistingerrataundertheErratasectionofthattitle.

Toviewthepreviouslysubmittederrata,gotohttps://www.packtpub.com/books/content/supportandenterthenameofthebookinthesearchfield.TherequiredinformationwillappearundertheErratasection.

Page 33: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

PiracyPiracyofcopyrightedmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.IfyoucomeacrossanyillegalcopiesofourworksinanyformontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.

Pleasecontactusat<[email protected]>withalinktothesuspectedpiratedmaterial.

Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluablecontent.

Page 34: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

QuestionsIfyouhaveaproblemwithanyaspectofthisbook,youcancontactusat<[email protected]>,andwewilldoourbesttoaddresstheproblem.

Page 35: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter1.JavaScriptforModernWebApplicationsThegrowthinwebdevelopmentevolvedwitharapidpaceinrecentyears.Mostofthebusinessapplicationsthatdevelopedonadesktopplatformarenowshiftedtothewebplatform,andthereasonistheeaseofaccessandcontinuousadditionofrichcapabilitiesonthewebplatform.Typically,anywebapplicationthatprovidesthecharacteristicsofthedesktopapplicationsisconsideredasrichwebapplication.Thus,itinvolvesextensiveuseofJavaScriptanditsframeworksandlibraries.

JavaScriptplaysanimportantroleindevelopingrichapplicationsandallowsdeveloperstodolessserver-sidepost-backsandcallserver-sidefunctionsthroughajaxifiedrequests.Notonlythis,butnowmanycompaniesandcommunitiesaredevelopinggoodframeworkssuchasAngular,Knockout,ReactJS,andsoontobringstate-of-the-artandgroundbreakingcapabilities.MicrosofthasalsoreleasedtheWinJSlibrarytoaccessmobilenativedevicefeaturessuchascamera,storage,andsoonfromawebapplicationrunningonmobilebrowsers.myNFCisalsoagreatJavaScriptlibrarythatallowsdeveloperstocreateapplicationsforsmartphones.

Page 36: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ImportanceofJavaScriptAlltheclient-sideframeworksarebasedonJavaScript.BeinganASP.NETdeveloper,weshouldhavesolidconceptsofJavaScriptbeforeusingorintegratingtheminourapplications.JavaScriptistheclient-sidescriptinglanguageandoneofthemostpopularprogramminglanguagesofalltimesthatrunontopofabrowser.Whenworkingonawebdevelopmentproject,thislanguageservesyouinmanybetterwaystomakeuserinterface(UI)responsive.WithJavaScript,youcanmanipulateHTMLpageDocumentObjectModel(DOM)elements,callserver-sidecodethroughajaxifiedrequestsandbringnewrichexperiencetoyourcustomers.TherearemanyinnovationsbeingdoneatthecoreJavaScriptlibrary,anddifferentframeworksandvariouslibrarieshavebeendeveloped.

Page 37: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WhatisJavaScript?JavaScriptisaprogramminglanguagecreatedin1995byBrendenEich.Initially,itwasonlysupportedbyNetscapeBrowser,butlatertheydecidedtoreleaseastandardknownasECMAspecificationtoletotherbrowsersimplementandprovideenginestoexecuteJavaScriptontheirbrowsers.Thereasonforprovidingthestandardistohavethecompletespecificationdetailsforthepartytofollowandprovideconsistentbehavior.

Earlieritwasonlytargetedtoexecuteonbrowsersandperformclient-sideoperationsthatworkwithHTMLpagesandprovidefeaturessuchasmanipulatingDOMelementsanddefiningeventhandlersandotherfunctionalities.Later,andinrecentyears,ithasbecomeapowerfullanguageandnotonlyboundedtotheclient-sideoperations.WithNode.js,wecanuseJavaScriptonserversideandtherearevariousmodulesandpluginsprovidedbyNodetoperformI/Ooperations,server-sideevents,andmore.

Page 38: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ComparingruntimesAsthisbookistargetedfor.NETdevelopers,let'scomparetheJavaScriptruntimewith.NETruntime.Thereareafewthingsincommon,butthebasicruntimeisdifferent.

In.NET,CommonLanguageRuntime(CLR)doesthejust-in-time(JIT)compilationonthecodethatisrunningandprovidesmemorymanagement.JITcompilationisdoneontheIntermediateLanguage(IL)codethatisgeneratedonceyoubuildyourproject.

IntheJavaScriptworld,browserengineistheruntimefortheJavaScriptlanguage.EverybrowserinterpretsJavaScriptinitsownway,butfollowstheECMAscriptingstandards.Differentbrowsershavedifferentimplementations,forexample,MicrosoftEdgeusesChakraengine,ChromeusesV8,andFirefoxhasMonkeyengines.Initially,JavaScriptwasimplementedasaninterpretedlanguage,butfewmodernbrowsersnowperformJITcompilation.Everyengineprovidesasetofservicessuchasmemorymanagement,compilation,andprocessing.

Thefollowingdiagramshowsthecomparisonbetweenboththearchitectures:

Page 39: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

TheJavaScriptparserparsesandtokenizestheJavaScriptcodeintoasyntaxtree.Allthebrowsers,exceptGoogleV8,parsethesyntaxtreeandgenerateabytecodethatfinallyconvertsintoamachinecodethroughJITcompilation.Ontheotherhand,GoogleV8engineparsesthesyntaxtreeandinsteadofgeneratingabytecodefirst,itdirectlygeneratesthemachinecode.

The.NETsourcecodeiscompiledbyitsownlanguagecompiler,suchasC#orVB.NET

Page 40: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

compilerandpassesthroughtheseveralstagesofthecompilerpipelinetogenerateanILcode.ThisILcodeisthenreadbytheJITcompilerthatgeneratesthenativemachinecode.

Page 41: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SettingupyourenvironmentBeforegoingthroughthisbook,let'ssetupyourenvironment.TherearemanyrenownededitorsavailableinthemarkettocreateJavaScriptprojectssuchasSublimeText,KomodoIDE,NetBeans,Eclipse,andmore,butwewilluseVisualStudio2015thatcameupwithsomegoodimprovements,helpingdeveloperstoworkonJavaScriptinabetterwaythanbefore.

Toproceed,let'sdownloadandinstallVisualStudio2015.YoucandownloadtheVisualStudio2015communityeditionfromhttps://www.visualstudio.com/,it'safreeversionandprovidescertainimprovementsasdescribedinthefollowingsection.

Page 42: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

NeweditingexperienceofJavaScriptinVisualStudio2015IDEThenewVisualStudio2015IDEprovidesmanyrichfeaturesfordevelopingwebapplicationsandvarioustemplatesareavailabletocreateprojectsondifferentframeworksandapplicationmodels.TheearlierversionalreadysupportedIntelliSense,colorization,andformattingbutthenewVisualStudio2015IDEhassomemoreimprovementsthatareasfollows:

AddedsupportfortheECMAScript6scriptinglanguage,whichisformallyknownasES2015.WiththenewES2015,manyfeatureshavebeenadded,youcannowdefineclasses,lambdas,spreadoperator,andproxyobjects.So,withVisualStudio2015,youcangetallIntelliSenseusingthesefeaturesinyourJavaScriptcode.SupportforpopularJavaScriptclient-sideframeworkssuchasAngular,ReactJS,andsoon.DocumentationcommentsthathelpyouaddcommentstoyourJavaScriptmethodsandshowthedescriptionwhenyouusethem:

IntelliSensefornewJavaScriptAPIssuchastoucheventandWebAudioAPI.Youcanusetokenssuchas//TODO,//HACK,and//UNDONE,anditgivesyoualistingintheTaskListwindowthathelpstotracetheto-doitems:

Page 43: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WithJavaScriptfiles,VisualStudio2015providesthesamenavigationbarweusedtoseewhenwritingclassesinany.NETlanguage.SelectingandnavigatingtodifferentmethodsofJavaScriptisfareasierwiththisfeature:

Page 44: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ProgramminginJavaScriptJavaScriptisoneofthemostpowerfullanguagesthatplaysavitalroleinanywebdevelopmentprojectanddeliversclient-sidesupportandrichfunctionality.Inthissection,wewilldiscussthecoreconceptsofwritingprogramsinJavaScriptandusetheminwebapplications.

Page 45: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CorefundamentalsofJavaScriptLikeanyotherprogramminglanguage,JavaScriptalsohasstatements,expressions,operators,andspecificsyntaxtowriteandrunprograms.Wewillgothroughthefollowingtopicsinthissection:

AddingJavaScripttoanHTMLpageStatementsLiteralsandvariablesDatatypesExpressionsandoperators

AddingJavaScripttoanHTMLpage

EverymodernbrowserhasaJavaScriptenginethatcompilesyourJavaScriptdefinedonthepage.JavaScriptcanbeplacedinthe<head>or<body>sectionsofyourHTMLpage.Anystatementthatisdefinedunder<script></script>tagswillbeconsideredaJavaScriptstatementandwillbeprocessedandunderstoodbythebrowser'sengine.

ThefollowingcodesnippetshowsasimpleHTMLpagecontainingthe<script></script>tagsdefinedwithinthe<head></head>section:

<html>

<head>

<script>

alert("Thisisasimpletext");

</script>

</head>

</html>

Whenthepageloads,itwillshowthepop-upmessageandatextasThisisasimpletext.Thebrowser'sJavaScriptengineexecutesanyscriptthatisdefinedunderthe<script>tagandrunsthestatementsdefinedwithinthisblock.Anystatementthatisdefineddirectlyunderthescriptingtagisexecutedeverytimethepageisloaded.

Similarly,wecanalsodefinetheJavaScriptwithinthe<body>sectionoftheHTMLpage:

<html>

<body>

<script>

alert("helloworld");

</script>

</body>

</html>

Tip

Itisagoodideatoplacescriptsatthebottomofthepagebecausethecompilationcanslowdownthepageloading.

Page 46: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Normally,ineveryproject,irrespectiveoftheprojectsize,separatingthe<script>sectionfromHTMLmakesthecodelookcleanerandeasytomaintain.JavaScriptfileextensionsarenamed.jsandyoucanalsocreatethesefilesseparatelyinsomescriptsfolderandreferencetheminourHTMLpage.

InVisualStudio,youcaneasilycreateaJavaScriptfileusingtheAdd|JavaScriptFileoptionasshowninthefollowing:

Oncethefileiscreated,wecandirectlywritetheJavaScriptsyntaxwithoutany<script></script>tags.JavaScriptfilescanbereferencedinyourHTMLpageusingthesrcattributeof<script></script>tags.Herewereferencedtest.jsintheHTMLpage:

<scriptsrc="~/test.js">

</script>

Placingthe<script>tageitherinthe<head>orinthe<body>sectiondependsonthepage.IfyourpagereferencingsomelargeJavaScriptfilestakesalongtimetoload,itisbettertodefinethemattheendofthe<body>section.Thisisabetterapproach,sowhenthebrowserstartsparsingyourpage,itisnotstuckdownloadingyourscriptsanddelayingtherendering.Ontheotherhand,wecandefineJavaScriptfilesinthe<head>sectiononlyiftheydonotimpacttheperformanceorpagelifecycle.Scriptsdefinedatthebottomgetparsedwhenthewholepageloads.Therearealsoafewattributessuchasasyncanddeferthatwecanusewithinthe<script>tagandmostofthebrowserssupportthis.

Thefollowingisanexampleshowingtheuseofasyncinthe<script>tag:

<scriptsrc="~/test1.js"async></script>

<scriptsrc="~/test2.js"async></script>

Scriptsdefinedwithasyncareexecutedasynchronouslywithoutblockingthebrowsertoloadthepage.However,ifmultiplescriptsarethere,theneachscriptwillbeexecutedasynchronouslyandatthesametime.Thismayleadtothepossibilityofcompletingthesecondscriptbeforethefirstonegetscompletedandmightthrowsomeerrorsifoneisdependentontheother.Forexample,whenworkingwithsomeclient-sideframeworks,such

Page 47: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

asAngularframework,JavaScriptcodethatisusingAngularcomponentsisdependentonAngularJSlibrary,andinthiscase,ifourcustomJSfilesareloadedbeforetheAngularJSlibraryonwhichtheyaredependent,theywillthrowanexception.

Toovercomethisscenario,wecanusedefertoexecutescriptsinasequence.Wecanusedeferasfollows:

<scriptsrc="~/test1.js"defer></script>

<scriptsrc="~/test2.js"defer></script>

ThebasicdifferencebetweenasyncanddeferisthatasyncdownloadsthefileduringHTMLparsingandpausestheHTMLparsertoexecuteituntilitiscompletelydownloaded,whereasdeferdownloadsthefileduringtheHTMLparsingandexecutesitaftertheHTMLparseriscompleted.

StatementsinJavaScript

Statementsarethecollectionofwords,expressions,andoperatorstoperformaspecifictask.Likeotherprogramminglanguages,statementsinJavaScriptcouldalsobeassigningavaluetothevariable,performingarithmeticoperations,implementingconditionallogic,iteratingthroughcollection,andsoon.

Forexample:

vara;//variabledeclaration

a=5;//valueassignment

a=5*b;//valueassignment

a++;//equivalenttoa=a+1

a--;//equivalenttoa=a-1

varmethod=function(){…}//declarefunction

alert("HelloWorld")//callingbuilt-infunction

if(…){…}else{…}

for(…){…}

while(…){…}

However,youcanusesemicolonswiththedowhileloop:

do{…}while(…);

functionstatement

function(arg){//todo}

Tip

Ifmultiplestatementsaredefinedinthesameline,theyshouldbeseparatedbyasemicolon,otherwisetheywillbetreatedasasinglestatement.Ondifferentlines,asemicolonisnotmandatorybutagoodpracticetouse.

Literalsandvariables

TherearetwotypesofvaluesinJavaScript:literalsorfixedvaluesandvariables.

Page 48: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Literalscouldbenumber,string,ordateobjects.

Forexample:

Numbers

22.30

26

Strings

"John"

"10/Jan/2015"

Variablesareusedtostorevalues.InJavaScript,wecandefinevariablesusingthevarkeyword.JavaScriptisnotatype-safelanguageandthetypeisidentifiedwhenthevalueisassigned.

Forexample:

varx=6;

varx="Samplevalue";

Datatypes

Everyprogramminglanguagehascertaindatatypesavailabletoholdspecificdata.Forexample,inC#,wecanuseStringtoholdstringvalues,inttohold32-bitintegervalue,DateTimetoholdvalueinthedateandtimeformat,andsoon.JavaScriptdoesnotprovidestrongdatatypessuchasC#andotherprogramminglanguages,andit'salooselytypedlanguage.AsperthelatestECMA6standard,JavaScriptprovidessixprimitivedatatypesandanobject.Allprimitivedatatypesareimmutable,thismeansthatassigninganewvaluewillbeallocatedintoaseparatememory.Objectismutableanditsvaluescanbechanged.

Theprimitivetypesareasfollows:

Boolean:Thisholdsthelogicalvaluetrueorfalse.Null:Thisholdsthenullvalue.Undefined:Thisisavariablethatdoesnotassignavalueandhasvalueasundefined.Number:Thisholdsnumericvalues.Thesizeofthenumbertypeisdouble-precision64bitinwhichthenumber(fraction)isstoredfrom0to51bits,theexponentin11bitsfrom52to62,andsignin1bit63.String:Thisholdsanykindoftextualvalue.

Complextypesaretermedasobject.InJavaScript,theobjectisformulatedinaJSONformat.

ArrayinJavaScript

Arrayisusedtostorecollectionsofdata.YoucansimplydefineanarrayinJavaScriptasshowninthefollowing:

varbrowsers=["MicrosoftEdge","GoogleChrome","MozillaFirefox","Safari"];

Page 49: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Youcanaccessthemthroughthearrayindex.Theindexstartsfrom0tillthenumberofitemsinthearray.

Wecanaccessthearrayitemsasfollows:

vara=browsers[0];//returnsMicrosoftEdge

varb=browsers[1];//returnsGoogleChrome

varc=browsers[3];//returnsSafari

Inordertogetthetotalnumberofitemsinanarray,youcanusethelengthproperty:

vartotalItems=browsers.length;

Thefollowingisalistofsomeofthemostcommonlyusedmethods:

Method Description

indexOf()Thisreturnsthefirstindexofanelementavailablewithinthearrayequaltothespecificvalue,returns-1ifnotfound.

lastIndexOf()Thisreturnsthelastindexofanelementavailablewithinanarrayequaltothespecifiedvalue,returns-1ifnotfound.

pop() Thisdeletesthelastelementfromanarrayandreturnsthatelement.

push() Thisaddsoneelementtoanarrayandreturnsthelengthofanarray.

reverse()Thisreversestheorderofelementsinanarray.Thefirstelementbecomesthelastandlastonebecomesthefirst.

shift() Thisdeletesthefirstelementandreturnsthatelement.

splice() Thisisusedtoaddorremoveelementsfromanarray.

toString() Thisreturnsalltheelementsinastringrepresentation.

unshift() Thisaddselementstothefrontofanarrayandreturnsthenewlength.

Tip

Page 50: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Downloadingtheexamplecode

DetailedstepstodownloadthecodebundlearementionedinthePrefaceofthisbook.Pleasehavealook.

ThecodebundleforthebookisalsohostedonGitHubathttps://github.com/PacktPublishing/JavaScript-For-.NET-Developers.Wealsohaveothercodebundlesfromourrichcatalogofbooksandvideosavailableathttps://github.com/PacktPublishing/.Checkthemout!

WhatisJSON?

JavaScriptObjectNotation(JSON)isalightweight,interchangeableformatfordefiningobjectsinJavaScript.AnykindofobjectcanbedefinedthroughJSONanditisusedtobuilduniversaldatastructures.Whetherit'sasimpleobject,arrays,nestedarrays,orcomplexobject,eachcanhandleintheJSONformat.

SimpleobjectsinJSON

Thefollowingcodesnippetshowsthepersonobjectthathasthreeproperties,namelyname,email,andphone:

varperson={

"name":"JohnMartin",

"email":[email protected],

"phone":"201892882"

}

Wecanaccesstheseobjectpropertiesasfollows:

person.name;

person.email;

person.phone;

DeclaringarraysinJSON

ThefollowingcodesnippetshowsthewayofdeclaringarraysinJSON:

varpersons=

[{

"name":"John",

"email":"[email protected]",

"phone":"201832882"

},

{

"name":"Steve",

"email":"[email protected]",

"phone":"201832882"

},

{

"name":"Smith",

"email":"[email protected]",

Page 51: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

"phone":"201832882"

}]

Accordingtotheprecedingdeclarationofanarray,itcanbeaccessedasfollows:

//returnsnameofthefirstiteminthecollectioni.e.John

Persons[0].name

//[email protected]

Persons[0].email

//returnsnameoftheseconditeminthecollectioni.e.Steve

Persons[1].name

NestingdatainJSON

TheJSONformateasilyhandlesnestedarrays.Let'slookatthecomplexobjectscontaininganemployeeobjectthatcontainstheExperiencesarraywiththenestedarraytoholdprojects,andeachprojecthasanestedarraytoholdtechnologiesusedineachproject:

varemployee=

{

"ID":"00333",

"Name":"Scott",

"DateOfJoining":"01/Jan/2010",

"Experiences":[

{

"companyName":"ABC",

"from":"Nov2008",

"to":"Oct2009",

"projects":[

{

"title":"SharepointMigration",

"noOfTeamMembers":5,

"technologyUsed":[{"name":"SharePointServer"},{"name":"C#"},

{"name":"SQLServer"}]

},

{

"title":"MessagingGateway",

"noOfTeamMembers":5,

"technologyUsed":[{"name":"ASP.NET"},{"name":"C#"},{"name":"SQL

Server"}]

}

]

},

{

"companyName":"XYZ",

"from":"Nov2009",

"to":"Oct2015",

"projects":[

{

"title":"ERPSystem",

"noOfTeamMembers":5,

"technologyUsed":[{"name":"ASP.NET"},{"name":"C#"},{"name":"SQL

Server"}]

},

{

Page 52: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

"title":"HealthcareSystem",

"noOfTeamMembers":4,

"technologyUsed":[{"name":"ASP.NET"},{"name":"C#"},{"name":"SQL

Server"}]

}

]

}

]

}

Intheprecedingscript,thearrayhasanemployeeobjectcontainingsomepropertiessuchasID,name,anddateofjoining,andthenoneexperiencespropertythatholdsanarrayofexperiencesandeachexperienceholdstheprojectsthattheemployeedidinaparticularworkplace.

Conversionsindatatypes

AsthedatatypesinJavaScriptaredynamicinnatureanddatatypeisdeterminedbasedonthevalueassignment,JavaScriptdoesnotthrowanyexceptionontypeconversionanddealsinseveralwaysasfollows.

Forexample,thefollowingistheJavaScriptcodesnippetshowingtheassignmentofdifferentexpressions.

Firstassignthestringtotheresvariable:

varres="HelloWorld";

Thenassignnumerictothesameresvariable:

res=2;

Finally,concatenatestring3totheresvariablethatholdsthefollowingnumeric,butduetothehigherprecedenceofnumericalvalue,theresultantvaluebecomes5:

varresult=res+"3"

So,nomatterwhatwasthetypeofthevariablefirstassignedtoit,itwillchangeitstypebasedontheassignmentanddynamicallyhandletheconversions.

Page 53: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ElementsofJavaScriptHerearesomeoftheimportantelementsofJavaScriptthatareessentialtolearnbeforewestartprogramminginJavaScript.

ConstantsinJavaScript

ConstantsinJavaScriptcanbedefinedwithaconstkeyword.Constantsaretheimmutablevaluesthatareknownatcompiletime,andvaluesdonotchangethroughoutthelifecycleoftheprogram.

ThefollowingistheJavaScriptcodeshowingtheassignmentofaconstantvariable.Whenusingconst,varisnotrequiredandyoucandeclareconstantvalueswithonlytheconstkeyword:

constpi=3.42

Comments

Commentscanbeaddedwith//and/**/.Tocommentasingleline,youcanuse//,otherwise/**/forablockofcode.

ThefollowingistheJavaScriptcodeshowingthewayofcommentingasinglelineorblockofcode:

<scripttype="text/javascript">

functionshowInformation(){

//varspObj=window.document.getElementById("spInfo");

spObj.innerHTML=

"AvailableHeight:"+screen.availHeight+"<br>"+

/*"AvailableWidth:"+screen.availWidth+"<br>"+

"Height:"+screen.height+"<br>"+*/

"Width:"+screen.width+"<br>"

}

</script>

Casesensitivity

JavaScriptisacase-sensitivelanguageanditfollowsthePascalnamingconventiontodefinevariablesandmethods.

Forexample,ifthemethodnameisdoWork(),itcanonlybeaccessedbycallingitwiththeexactcase,andcallingeitherDoWork()orDowork()willnotworkandthrowexception.

Characterset

JavaScriptisbasedonaUnicodecharactersetandfollowstheUnicodeStandard.

Page 54: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Note

WhatistheUnicodeStandard?

Itisaworldwidecodingstandardthatmostlanguagesuse.C#andVB.NETfollowthesameUnicodeStandard.Itprovidesauniquenumberforeverycharacter,forexample,A=41,a=61,andsoon.

ThecurrentversionoftheUnicodeStandardisUnicode8.0.0andthedocumentationcanbelocatedathttp://www.unicode.org/versions/Unicode8.0.0/.

Page 55: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ExpressionsExpressioncanberecognizedasthestatementofcodethatassignssomevaluetothevariable.Expressionsarecategorizedintotwotypes.

Thefirsttypeofexpressioncanbetermedassimpleexpressionsthatassignsavaluetothevariable:

varx=2;

Theprecedingexampledenotesthesimpleexpressionofassigningnumericvalue2toanxvariable.

Thesecondtypeofexpressioncanbetermedasanyarithmeticorstringoperationtothevaluesontherightandassigningthemtoanyvariable.Thesetypeofexpressionsperformtheoperationfirstbeforeassigningvaluetothevariable:

varx=2+3

varx="Hello"+"World";

Thisisanexampleofthesecondtypeofexpressionthataddstwonumbersandassignstheresultantvaluetothexvariable.SamegoesforthesecondstatementthatperformsthestringconcatenationoperationandassignstheHelloWorldvaluetothexvariable.

Thethiskeyword

JustlikeC#andotherobject-orientedlanguages,JavaScripthasobjectsandtherearecertainwaystodefineclasses,functions,andsoonthatwewillstudylaterinthischapter.JustlikeC#,inJavaScript,wecanaccesstheobjectanditspropertiesthroughthethiskeyword.Let'stakealookatsomeexamplesshowingthescopeofthethiskeywordinJavaScript.

Thefollowingisacustomerobjectthatcontainsafewpropertiesandtheutilizationofthethiskeyword:

varcustomer=

{

name:"JohnMarting",

email:"[email protected]",

mobile:"109293988844",

show:function(){

alert("Name:"+this.name+"Email:"+this.email+"Mobile:"+

this.mobile);

}

}

Intheprecedingexample,wehavedefinedaJavaScriptobjectthatcontainsthreepropertiesandafunction.Toaccesstheseproperties,wecanusethethiskeywordjustlikeC#.However,wecanalsoaccessthepropertiesusingthecustomervariable,asshowninthefollowing:

Page 56: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

varcustomer=

{

name:"JohnMarting",

email:"[email protected]",

mobile:"109293988844",

show:function(){

alert("Name:"+customer.name+"Email:"+customer.email+"Mobile:"+

customer.mobile);

}

}

Thescopeofthethiskeywordislimitedwithintheboundaryofanobject.Whereas,thecustomervariableintheprecedingexamplecouldbedefinedsomewhereelseonthepageandmayleadtoanincorrectbehavior.Itisabetterapproachtousethethiskeywordwhereverpossibleandavoidusingobjectvariablesdirectly.

Allvariablesandfunctionsdefineddirectlyunderthe<script>tagaretermedasglobalvariablesandfunctions.Wecanalsoaccessthemthroughthethiskeyword.Inthiscase,thiswillbereferredastheglobalwindowobjectandnotthechild,thatis,thecustomerobjectwehaveusedinthepreviousexample:

<scripttype="text/javascript">

varname="";

functionShowMessage(){

alert(this.name);

}

</script>

Unlikethis,youcanalsoreferthevariablesandfunctionsthroughthewindowkeyword.Thefollowingcodesnippetwillshowthenameofthewindowinthedialogbox:

alert(window.name);

Let'stakealookatthecompleteexample,wherewehaveglobalvariablesdefined,aswellaschildobjects,andthescopeofthiswillbedeterminedbasedonthecontextofitscall:

<scripttype="text/javascript">

varname="ScottWatson";

varcustomer=

{

name:"JohnMarting",

email:"[email protected]",

mobile:"109293988844",

show:function(){

alert("Name:"+this.name+"Email:"+this.email+"Mobile:"+

this.mobile);

}

}

functionShowMessage(){

alert("Globalnameis"+this.name);

alert("Customerinfois"+customer.show());

Page 57: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

</script>

Inthisprecedingexample,wewillgettwoJavaScriptalertmessages.ThefirstalertwilldisplayScottWatson,whichisdefinedglobally,andthesecondpopupshowsthecustomername,e-mailaddress,andmobilenumber.Hence,wecanusethisintwoplaces,butthescopeisdeterminedbasedonthecontextfromwhereitiscallingfrom.

SequenceofcodeexecutioninJavaScript

WhenprogramminginJavaScript,wehavetokeepthesequenceofdefiningthingsbeforetheygetcalled.Consideringtheprecedingexample,ifwedefinethecustomerobjectaftertheShowMessage()method,itwillnotberecognizedandnothingwillbedisplayed.

Usingthethiskeywordonacallingmethod

Let'stakealookatthesampleHTMLpagethathasaJavaScriptfunctionnamedMultiplyandtakestwoparameters:objandval.Thismethodwillbecalledwhentheuserentersanyinputintothetextboxanditwillpassthereferenceofthetextboxcontrolatthefirstparameter.Thiscanbepassedthroughthethiskeyword:

<html>

<head>

<scripttype="text/javascript">

functionMultiply(obj,val){

alert(obj.value*val);

}

</script>

</head>

<body>

<inputtype="text"onchange="Multiply(this,2);"/>

</body>

</html>

Thefunctionstatementandexpression

ThefunctionstatementsareawayofdefiningmethodsinJavaScript.Eachfunctionhasasignature,containingthenameandparameterspassedin.FunctionscanbedeclaredinmanywaysinJavaScript.Forexample,thefollowingisthesampleGetPerson(id)functionthatreturnsthepersonobjectbasedontheIDpassedasaparameter.ThisisthenormalwayofdeclaringfunctioninJavaScript:

<script>

functionGetPerson(id){

returnservice.GetPerson(id);

}

</script>

Thefunctionreturntypeiscomputedatruntimeandnotpartofthefunctionsignature.

Page 58: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Returningvaluesisnotmandatoryandyoucankeepfunctionswithoutreturninganyvalues.

Ontheotherhand,anonymousfunctionsdonothaveanynameandtheycaneitherbepassedasanargumenttootherfunctionsordefinedwithoutafunctionname.Thefollowingaretheexamplesofanonymousfunctions:

varshowMessage=function(message){

console.log(message);

}

showMessage("HelloWorld");

Anotherexampleofdefininganonymousfunctionandpassingitasaparameterisasfollows:

functionmessageLogger(message,logMessage){

logMessage();

}

functionconsoleMessage(){

alert("HelloWorld");

}

messageLogger(consoleMessage());

Thefunctionexpressionisequivalenttofunction,buttheonlydifferenceisthatitshouldnotstartwiththefunctionname.

Classstatementandexpression

WithECMAScript6,wecancreateclassesinJavaScript.Justlikeotherprogramminglanguages,wecancreateaclassusingtheclasskeyword.Withthis,wecanwritecleanercodethandevelopingfunctionsthatwererepresentedasclassesintheearlierversionofECMAScript.

Let'stakealookattheRectangleclassthatcalculatesanarea:

<script>

classRectangle{

constructor(height,width){

this.height=height;

this.width=width;

}

getArea(){

returnthis.calcArea();

}

calcArea(){

alert("Areais"+this.height*this.width);

}

}

</script>

Eachclassshouldhaveoneconstructorandgiveanerrorifmultipleconstructorsarespecified.Classexpressionisanotherwayofdefiningclasses.Justlikeanonymousfunctions,wecandefineclassesinasimilarway.

Page 59: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Let'stakealookattheexampleofthesameclassdefinedearlier:

<script>

varRectangle=class{

constructor(height,width){

this.height=height;

this.width=width;

}

getArea(){

returnthis.calcArea();

}

calcArea(){

alert("Areais"+this.height*this.width);

}

}

</script>

Thenextchapterwillcovermoredetailsaboutclassesandtheattributesandkeywordsavailabletostructurethem.

Groupingoperator

Foranyarithmeticexpression,JavaScriptusestheBODMASrule.Theprecedencewillbegiventobracketsthenmultiplication,division,addition,andsubtraction.Thegroupingoperatorisusedtogivehigherprecedencetotheexpressionifanyofthememberintheexpressionhavehigherprecedencebydefault.

Forexample:

vara=1;

varb=2;

varc=3;

varx=a+b*c;

Theresultantxwillbe7asmultiplicationgetsthehigherprecedence.However,whatifweneedtoperformadditionfirst?

Wecanusegroupingoperatorasfollowsthatgivestheresult9:

varx=(a+b)*c;

new

InthesamewayasC#,thenewkeywordisusedtoinstantiateanyobjectinJavaScript.Inordertocreateaninstanceofanyuser-definedorpredefinedtype,usethenewkeyword:

varobj=newobjectType();

super

Thesuperkeywordisusedtocallmethodsoftheparentobject.InC#,weusethebasekeywordtocallthebaseclassmethodorproperties.InJavaScript,wecanuseitasfollows:

Page 60: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

super.functionOnParent();

Page 61: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

OperatorsOperatorsaretheobjectusedtomanipulatevaluesofanoperand.Forexample,1+2resultsin3,where1and2areoperandsand+isanoperator.InJavaScript,wecanusealmostalltheoperatorstoconcatenatestrings,doarithmeticoperations,andsoon.Inthissection,let'sseewhattypeofoperatorswecanusewhenwritingprogramsinJavaScriptlanguage.

Wewilldiscussthefollowingoperatorsinthissection:

AssignmentoperatorsArithmeticoperatorsUnaryoperatorsComparisonoperatorsLogicaloperatorsBitwiseoperatorsBitwiseshiftoperatorsThetypeofoperatorThevoidoperatorThedeleteoperatorMiscellaneousoperators

Assignmentoperators

Assignmentoperatorisrepresentedas(=)andtheassignmentisdonefromrighttoleft.

Forexample,x=ymeansthatthevalueofyisassignedtox.

Arithmeticoperators

Thefollowingisalistofarithmeticoperatorsyoucanusetoperformaddition,subtraction,division,andmultiplicationandusethemwiththeassignmentstatements:

Name Operator Meaning

Addition x+y Thevalueofxisaddedtoy

Subtraction x–y Thevalueofyissubtractedfromx

Division x/y Thevalueofxisdividedbyy

Multiplication x*y Thevalueofxismultipliedtoy

Page 62: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Remainder x%y Thevalueofxisdividedbyyandtheremainderisreturned

Additionassignment x+=yx=x+y

thatis,thevalueofxandywillbeaddedandassignedtox

Subtractionassignment

x-=y

x=x–y

thatis,thevalueofxandywillbesubtractedandassignedtox

Multiplicationassignment

x*=y

x=x*y

thatis,thevalueofxandywillbemultipliedandassignedtox

Divisionassignment x/=yx=x/y

thatis,thevalueofxwillbedividedbyyandassignedtox

Remainderassignment

x%=y

x=x%y

thatis,thevalueofxwillbedividedbyyandtheremainderwillbeassignedtox

Exponentiationassignment

x**=y

x=x**y

thatis,thevalueofxwillbeexponentiallymultipliedtwicetoyandassignedtox

Unaryoperators

Unaryoperatorworkswithonlyoneoperand.Itcanbeusedforincrement,decrement,inversion,andsoon:

Name Operator Meaning

Incrementoperator x++ Thevalueofxwillbeincrementedby1

Decrementoperator x-- Thevalueofxwillbedecrementedby1

Page 63: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Logicalcomplementoperator !(x) Thisinvertsthevalueofx

Comparisonoperators

ComparisonoperatorisusedtocompareoperandsthatreturnsaBooleantruevalueifthecomparisonistrue.Operandscanbeofanydatatype,haveanassociativityfromlefttoright,andperformdynamicconversioniftheyareofdifferenttypes.

Forexample,ifthevalueofxis2andyis"2".Here,ydenotesthatit'sastring,butincomparison,itwillreturntrue:

x==y//returnstrue

SimilartoC#oranyprogramminglanguage,JavaScriptsupportsalltheseoperators,suchasequal(==),notequal(!=),greaterthan(>),andlessthan(<),butduetothedynamictypebinding,italsoprovidestwooperatorssuchasstrictequal(===)andstrictnotequal(!===)toconfirmifthetypeisalsothesameifthevalueissameandviceversa.

Wewillnowhavealookatstrictoperators.Therearethefollowingtwotypesofstrictoperators:

StrictequaloperatorStrictnotequaloperator

Strictequaloperator

Intheprevioussection,wediscussedthatJavaScriptprovidesdynamicbindingandifthevalueoftwodifferentdatatypes,supposenumberandstring,arethesame,itwillreturntrueoncomparison.Forexample,ifxis1andyis"1",itwillreturntrue.Now,whatifwehavetodothecomparisonworkonlyifthetypeisalsothesame?Herecomesthestrictequaloperatorthatdoesnotonlycheckthevalue,butalsomatchthetypesofboththeoperands.

Thestrictequaloperatorcanberepresentedas===.

Forexample,ifx=1andy="1"andthecomparisonisdonelike(x===y),itwillreturnfalseasxrepresentsnumberandyrepresentsstring.

Strictnotequaloperator

Contrarytothestrictequaloperator,ifwewanttocomparethevaluesoftwooperandsofsametype,wecanusethestrictnotequaloperator.

Thestrictnotequaloperatorcanberepresentedas!===.

Ifx=1andy=2andthecomparisonisdonelike(x!==y),itwillreturntrue.Thisisbecausethetypesarethesameandthevaluesaredifferent.

Logicaloperators

Page 64: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

JustlikeC#,JavaScriptusesthesametypesoflogicaloperatorstohandlelogicalconditions.Logicaloperatorsareusedtohandlemultipleconditionsinalogicalstatement.

LogicalAND

LogicalANDisrepresentedas&&andisusedintwoormoreoperandsorconditionsinstatements.

Forexample,thefollowingisthecodesnippetthatshowsthemethodthattakesthreeparametersandthelogicisdefinedthatcheckswhethernumber1isequaltonumber2andthesummationofnumber1andnumber2isequaltonumber3toreturntrue:

<script>

functionCheckNumbers(number1,number2,number3){

if((number1==number2)&&((number1+number2)==number3)){

returntrue;

}

}

<script>

LogicalOR

LogicalORisrepresentedas||andisusedwithtwoormoreoperandsorlogicalconditions.

Forexample,thefollowingisthecodesnippetthatshowsthemethodthattakesthreeparameters,andifanyofthenumbersisequaltothevalue10,itwillreturntrue:

<script>

functionAnyNumber10(number1,number2,number3){

if((number1==10||number2==10||number3==10){

returntrue;

}

}

</script>

LogicalNOT

LogicalNOTisrepresentedas!andusedwithconditionsthatreturnaBooleanvalue.Forexample,ifanylogicalconditionreturnstrue,thisoperatorwillmakeitfalse.Itcanbeusedasfollows.Inthecodesnippet,ifnumber1,number2,andnumber3areequalto10,themethodwillreturnfalse.Iftheyaredifferent,thereturnvaluewillbetrue:

<script>

functionAnyNumber10(number1,number2,number3){

return!(number1==10&&number2==10&&number3==10){

}

}

</script>

Bitwiseoperators

Bitwiseoperatorsconsidereachnumberoroperandasbinary(acombinationof0and1).

Page 65: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Everynumberhasspecificbinarycorrespondingtoit.Forexample,number1binaryisrepresentedas0001and5representedas0101.

Bitwiseoperatorsworkon32-bitnumbersandanynumericoperandisfirstconvertedintoa32-bitnumberandthenconvertedbacktoJavaScriptnumber.

Bitwiseoperatorsperformtheiroperationsinbinaryandreturntheresultasnumbers.

Forexample,xis1andyis9.

1representedas0001.

9representedas1001.

BitwiseAND

BitwiseANDisrepresentedas&andthefollowingisthecomparisonofeachbitofoperand1and9.Ifbothvalueoneachbitis1,theresultwillbe1,otherwise0:

Number=1 Number=9 Result

0 1 0

0 0 0

0 0 0

1 1 1

IntheJavaScriptcode,wecanuseitasfollows:

<script>

vara="1";

varb="9";

varc=a&b;

</script>

Finally,theresultantvaluewillbe0001,whichisequalto1.

BitwiseOR

BitwiseORisrepresentedas|andthefollowingishowthebitORwillbeoperated:

Number=1 Number=9 Result

Page 66: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

0 1 1

0 0 0

0 0 0

1 1 1

ThefollowingcodesnippetshowstheusageinJavaScript:

<script>

vara="1";

varb="9";

varc=a|b;

</script>

Finally,theresultantvaluewillbe1001,whichisequalto9.

BitwiseNOT

BitwiseNOTisrepresentedas~anditworksonasingleoperandandinverseeachbitofthebinary.

Forexample,ifthenumber9isrepresentedas1001,itwillbeconvertedtoa32-bitnumberandthenbitwiseNOTwillmakeit11111111111111111111111111110110,whichisequalto-10.

Thefollowingisthecodesnippet:

<script>

vara=~9;

</script>

BitwiseXOR

BitwiseXORisrepresentedas^anditworkswithtwoormoreoperands.

ThefollowingtableshowshowthebitwiseXORisoperated:

Number=1 Number=9 Result

0 1 1

Page 67: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

0 0 0

0 0 0

1 1 0

ThefollowingcodesnippetshowstheusageinJavaScript:

<script>

vara="1";

varb="9";

varc=a^b;

</script>

Finally,theresultantvaluewillbe1000,whichisequalto8.

Bitwiseshiftoperators

Therearethreekindsofbitwiseshiftoperators,asfollows:

BitwiseleftshiftoperatorBitwiserightshiftoperator

Bitwiseleftshift

Itisrepresentedas<<andisusedtoshiftabitfromtherightsidetothebinaryvalueofanynumber.

Forexample,number9isrepresentedas01001,andifweusebitwiseleft,theresultantvaluewillbe10010,whichshiftedonebitfromtheright.

ThefollowingcodesnippetshowstheusageinJavaScript:

<script>

vara=9;

varresult=a<<1;

</script>

Finally,theresultantvaluewillbe10010,whichisequalto18.

Bitwiserightshift

Itisrepresentedas>>andisusedtoshiftabitfromtheleftsidetothebinaryvalueofanynumber.

Forexample,number9isrepresentedas1001,usingbitwiserightwillgivetheresultantvalueas0100.

Page 68: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ThefollowingcodesnippetshowstheusageinJavaScript:

<script>

vara="9";

varresult=a>>1;

</script>

Finally,theresultantvaluewillbe0100,whichisequalto4.

Thetypeofoperator

Thisisusedtocheckwhetherthetypeofthevariableisanobject,undefined,number,andsoon.InJavaScript,wecanusethisasfollows:

<script>

if(typeofa=="number"){

alert("thisisanumber");

}

</script>

Hereisthelistofpossiblevaluesreturnedbythetypeofoperator:

Valuereturned Description

"number" Ifoperandisanumber

"string" Ifoperandisastring

"boolean" IfoperandisaBoolean

"object" Ifoperandisanobject

null Ifoperandisnull

"undefined" Ifoperandisnotdefined

Thevoidoperator

Thevoidoperatorpreventsanexpressiontoreturnanyvalue.Itisessentialinconditionswhereyouneedtoevaluatetheexpressionbutdon'tneedthereturnvalueintheprogram.

Youcanwriteanyexpressionorstatementinsidethevoidmethod.

Forexample,thefollowingcodesnippetshowsthesimpleexampleofusingavoidoperator

Page 69: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

todisplayalertmessagewhenthelinkisclicked.Here,thealertexpressionisevaluatedoncetheuserclicksonthelink:

<html>

<head></head>

<body>

<ahref="javascript:void(alert('Youhaveclicked!'));">

</a>

</body>

</html>

Whenthepagerunsandtheuserclicksonthelink,itwilldisplayanalertmessageboxasshowninthefollowing:

Moreover,passing0asanexpressionwithinthevoidmethodwilldonothing:

<html>

<head></head>

<body>

<ahref="javascript:void(0);">

DoNothing

</a>

</body>

</html>

Anotherexamplehereisusingvoidtoaddtwonumbersandreturningundefinedfortheassignedoperand:

<script>

varn1=6;

varn2=7;

Page 70: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

varn3;

varresult=void(n3=n1+n2);

alert("result="+result+"andn3="+n3);

</script>

Thedeleteoperator

Adeleteoperatorisusedtodeleteobjectsanditsproperties,butnotthelocalvariables.ThefollowingexampleshowsthewayyoucanusethedeleteoperatorinJavaScript:

varcountry={id:1,name:"USA"};

deletecountry.id;

alert(country.id);

Callingcountry.idwillreturnundefined,asthiswasalreadydeletedintheprecedingstatement.Ontheotherhand,ifwedeletethecountryobject,itwouldnotdeleteanddisplaythecountryIDas1:

varcountry={id:1,name:"USA"};

deletecountry;

alert(country.id);

Miscellaneousoperators

HerearefewotheroperatorsthatareavailableinJavaScript.

Conditionaloperators

Conditionaloperatorisrepresentedas(?:):

expression1?expression2:expression3

Itworksascross-selectortoevaluateexpressions.Ifthefirstexpressionistrue,thesecondexpressionwillbeexecuted,otherwisethethirdwillbeexecuted.

Thefollowingisthecodesnippetforusingconditionaloperatortoevaluateexpression.ThereisacompareValues()functionthattakestwoparameters,andanalertwillbedisplayedstatingwhetherboththeparametersareequalornotequal:

<script>

functioncompareValues(n1,n2)

(n1==n2)?alert("Bothvaluesareequal"):alert("Passedvaluesarenot

equal");

</script>

Spreadoperator

Thespreadoperatorisrepresentedas(…).Itisusedwhereyouexpectmultipleargumentsto

Page 71: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

bepassedinforafunctioncall.

Forexample,ifyourfunctionistakingfiveparameters,youcaneitherpassthosevaluesonebyoneastheparametervaluewhencallingthatmethodorkeeptheminanarrayandpassthatarraythroughthespreadoperator.

ThefollowingcodesnippetshowstheactualexampleofusingthisinJavaScript:

functionmultipleArgs(a,b,c,d,e){

}

varargs=[1,2,3,4,5]

multipleArgs(…args);

Page 72: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Built-indisplaymethodsinJavaScriptThefollowingarethedisplaymethodsavailableinJavaScripttoprovidenotificationsandmessagestousersindifferentforms.

Displayingmessages

Therearethefollowingthreetypesofpop-updialogboxes:

AlertmessageboxConfirmationmessageboxPromptmessagebox

Alertbox

Usingwindow.alert(),wecanpopupanalertdialogbox:

<!DOCTYPEhtml>

<html>

<body>

<h1>MyFirstWebPage</h1>

<p>Myfirstparagraph.</p>

<script>

window.alert(5+6);

</script>

</body>

</html>

Confirmbox

Usingwindow.confirm(),wecanpopupaconfirmdialogboxthatreturnstheeventresulttheuserhastaken.Whenaconfirmdialogboxpopsup,itprovidestwoactionevents:OKandCancel.IfauserclickonOK,truewillbereturned,otherwisefalse.ThefollowingcodeshowstheusageoftheconfirmdialogboxonyourHTMLpage.

Thefollowingisthecodesnippetforusingaconfirmdialogboxtoconfirmwiththeuserbeforesavingarecord:

<!DOCTYPEhtml>

<html>

<body>

<script>

varr=window.confirm("areyousuretosaverecord");

if(r==true){

alert("Recordsavedsuccessfully");

}

else{

alert("Recordcouldn'tbesaved");

}

Page 73: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

</script>

</body>

</html>

Promptbox

Promptdialogboxisusedincaseswhenyouwanttheusertosupplythevalue.Itcanbeusedinconditionswhereyourequireuserinput.

ThefollowingcodesnippetshowsthewayofusingapromptmessageboxintheJavaScriptprogram:

<!DOCTYPEhtml>

<html>

<body>

<script>

varname=window.prompt("Enteryourname","N/A");

if(name!=null){

alert("hello"+name"+,howareyoutoday!");

}

</script>

</body>

</html>

Writingonapage

Wecanusethedocument.write()methodtowriteanythingonthescreen.

ThefollowingcodesnippetshowsthewayofwritinganytextonawebpageinJavaScript:

<!DOCTYPEhtml>

<html>

<body>

<script>

document.write("HelloWorld");

</script>

</body>

</html>

Writingintothebrowser'sconsolewindow

Usingconsole.log(),wecanwriteanytextintothebrowser'sconsolewindow.

ThefollowingcodesnippetshowsthewayofwritingtextintothebrowserconsolewindowfortracingordebuggingpurposesinJavaScript:

<!DOCTYPEhtml>

<html>

<body>

<h1>MyFirstWebPage</h1>

<p>Myfirstparagraph.</p>

Page 74: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<script>

console.log("Enteredintoscriptexecutioncontext");

</script>

</body>

</html>

Page 75: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

BrowserObjectModelsinJavaScriptJavaScriptprovidessomepredefinedglobalobjectsthatyoucanusetomanipulatetheDOM,closebrowsers,andsoon.Thefollowingarethebrowserobjectswecanusetoperformdifferentoperations:

WindowNavigatorScreenHistoryLocation

Window

Windowobjectreferstotheopenwindowinabrowser.IfintheHTMLmarkup,someiframesaredefined,aseparatewindowobjectwillcreated.Throughthewindowobject,wecanaccessthefollowingobjects:

AllglobalvariablesAllglobalfunctionsTheDOM

ThefollowingshowsanexampleofaccessingtheDOMfromthewindowobjectandaccessingthetextboxcontrol.

Document

window.documentreturnsthedocumentobjectandwecanuseitspropertiesandmethodsforaspecificreason:

<html>

<body>

<inputtype="text"name="txtName"/>

<script>

vartextbox=Window.document.getElementById("txtName");

textbox.value="HelloWorld";

</script>

</body>

</html>

Thewindowobjectitselfcontainsmanymethodsandfewofthemareasfollows:

Event Description Syntax

Close Toclosecurrentwindow window.close();

Open Toopennewwindow window.open();

Page 76: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Move Tomovewindowtothespecifiedposition window.moveTo();

Resize Toresizewindowtospecifiedwidthandheight window.resizeTo();

Navigator

Thisobjectprovidestheinformationaboutthebrowser.Itisbeneficialwhenyouneedtorunspecificscriptsbasedonthebrowserversionordosomethingspecifictothebrowser.Let'slookintothemethodsitexposes.

Properties

Thepropertiesaredescribedasfollows:

appCodeName:ThisreturnsthecodenameofthebrowserappName:ThisreturnsthenameofthebrowserappVersion:ThisreturnstheversionofthebrowsercookieEnabled:ThisdetermineswhethercookiesareenabledinthebrowsergeoLocation:Thisgetsthelocationoftheuseraccessingthepagelanguage:Thisreturnsthelanguageofthebrowseronline:Thisdetermineswhetherthebrowserisonlineplatform:Thisreturnstheplatformthatthebrowserhascompiledproduct:ThisreturnstheenginenameofthebrowseruserAgent:Thisreturnstheuseragentheadersentbythebrowsertotheserver

Theexamplecodeisasfollows:

<!DOCTYPEhtml>

<html>

<head>

<scripttype="text/javascript">

functionshowInformation(){

varspObj=window.document.getElementById("spInfo");

spObj.innerHTML=

"BrowserCodeName:"+navigator.appCodeName+"<br>"+

"ApplicationName:"+navigator.appName+"<br>"+

"ApplicationVersion:"+navigator.appVersion+"<br>"+

"CookieEnabled?"+navigator.cookieEnabled+"<br>"+

"Language:"+navigator.language+"<br>"+

"Online:"+navigator.onLine+"<br>"+

"Platform:"+navigator.platform+"<br>"+

"Product:"+navigator.product+"<br>"+

"UserAgent:"+navigator.userAgent;

navigator.geolocation.getCurrentPosition(showPosition);

}

functionshowPosition(position){

varspObj=window.document.getElementById("spInfo");

spObj.innerHTML=spObj.innerHTML+"<br>Latitude:"+

position.coords.latitude+

Page 77: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

"<br>Longitude:"+position.coords.longitude;

}

</script>

</head>

<bodyonload="showInformation();">

<spanid="spInfo"></span>

</body>

</html>

Theoutputisshownasfollows:

Screen

Throughthescreenobject,youcangetinformationabouttheuser'sscreen.Thisishelpfultoknowfromwhichscreentheuserisviewingthecontent.Ifit'samobilebrowserorstandarddesktopscreen,youcangetthesizeandotherinformationandmodifythecontentasrequired.

Properties

Thepropertiesaredescribedasfollows:

availHeight:ThisreturnstheheightofthescreenavailWidth:ThisreturnsthewidthofthescreencolorDepth:Thisreturnsthebitdepthofthecolorpalettefordisplayingimagesheight:ThisreturnsthetotalheightofthescreenpixelDepth:Thisreturnsthecolorresolution(inbitsperpixel)ofthescreenwidth:Thisreturnsthetotalwidthofthescreen

Page 78: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Theexamplecodeisasfollows:

<!DOCTYPEhtml>

<html>

<head>

<scripttype="text/javascript">

functionshowInformation(){

varspObj=window.document.getElementById("spInfo");

spObj.innerHTML=

"AvailableHeight:"+screen.availHeight+"<br>"+

"AvailableWidth:"+screen.availWidth+"<br>"+

"Height:"+screen.height+"<br>"+

"Width:"+screen.width+"<br>"

}

</script>

</head>

<bodyonload="showInformation();">

<spanid="spInfo"></span>

</body>

</html>

Theoutputisshownasfollows:

History

ThiscontainstheURLsthattheuservisited.Youcanaccessitthroughthewindow.historyobject.

Youcanusethisobjecttonavigatetotherecentlyvisitedlinks.

Methods

Themethodsaredescribedasfollows:

Page 79: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Window.history.back():ThisloadsthepreviousURLWindow.history.forward():ThisloadstherecentURLinthehistorylistWindow.history.go():ThisloadsaspecificURLavailableinthehistorylist

Location

ThelocationobjectgivesyouinformationaboutthecurrentURL.Justlikehistory,itcanalsobeaccessedthroughwindow.location.Thereareafewmethodsandpropertiesyoucanusetoperformspecificoperations.

Properties

Thepropertiesaredescribedasfollows:

window.location.host:ThisreturnsthehostnameandportnumberoftheURLwindow.location.hostname:ThisreturnsonlythehostnameoftheURLwindow.location.href:ThisprovidesthecompleteURLwindow.location.origin:Thisreturnsthehostname,portnumber,andprotocoloftheURLwindow.location.pathname:ThisreturnsthepathnameoftheURLwindow.location.port:ThisreturnsonlytheportnumberoftheURLwindow.location.protocol:ThisreturnstheprotocoloftheURL,forexample,HTTPorHTTPSwindow.location.search:ThisreturnsthequerystringoftheURL

Methods

Themethodsaredescribedasfollows:

window.location.assign():Thisloadsanewdocument.window.location.reload():ThisreloadsthecurrentURL.window.location.replace():ThiscanbeusedtoreplacethecurrentURLwiththenewone.Replacedoesnotrefreshthepage,itcanonlychangetheURL.

Page 80: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryInthischapter,wediscussedthebasicconceptsofJavaScriptandhowtouseitinourwebapplications.Wediscussedthecorefundamentalsofdeclaringvariablesandimplementingarrays,functions,anddatatypestostartwritingprogramsinJavaScript.Inthenextchapter,wewilldiscusssomeadvancedconceptsaboutobject-orientedprogrammingandworkingwithclosures,scopes,andprototypefunctionswithpracticalimplementation.

Page 81: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter2.AdvancedJavaScriptConceptsJavaScript,wheninitiallydesigned,wasnotexpectedtobecomethecoreprogramminglanguageforWebdevelopment.Itwasnormallyusedtoperformsomebasicclient-sideoperationsthatrequiresomemanipulationoftheDocumentObjectModel(DOM)elements.Lateron,withtherecentpaceinWebdevelopment,thingshaveprettymuchchanged.Now,manyapplicationsarepurelyusingJavaScriptandHTMLtohandlecomplexsituations.Fromtimetotime,withdifferentversions,differentfeatureswereaddedand,asperthespecificationofECMAScript6,youcannowhaveclasses,youcandoinheritanceasyoudowithanyotherprogramminglanguage,suchasC#orJava.Closures,prototypefunctions,propertydescriptors,andmanymorethatwewilldiscussinthischaptermakeitmorepowerfulandrobust.

Inthepreviouschapter,welearnedthecoreconceptsandsomebasicfundamentalsofwritingprogramsinJavaScriptandwhatfeaturesasalanguageitprovides.Inthischapter,wewillbefocusingmoreontheadvancedtopics,whichhelpustousetheseconceptsinlargeandcomplexapplications.

Wewillalsofocusonscopingandhoistingvariables,object-orientedprogramming,prototypefunctions,propertydescriptors,closures,exceptionhandling,andsoon.Sometopics,suchaspromises,asynchronouspatternsandAsynchronousJavaScriptandXML(Ajax)techniques,arebroadertopicsandarecoveredinotherchapters.

Page 82: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Variables–scopeandhoistingWealreadyknowhowvariablesaredeclaredinJavaScriptusingthevarkeyword.Anyvariablethatisdeclaredusingthevarkeywordistermedahoistedvariable,andthetermhoistingistheJavaScriptdefaultbehaviorofmovingdeclarationstothetop.WhenJavaScriptiscompiledbytheJavaScriptengine,allthevariablesthataredeclaredusingthevarkeywordareplacedatthetopwithinitsscope.Thismeansthatifthevariableisdeclaredwithinafunctionblock,itwillbeplacedatthetopofthefunction;otherwise,ifit'sdeclaredoutsideanyfunctionandattherootofthescript,itwillbecomegloballyavailable.Let'shavealookatthisexampletoclarifyourunderstanding.

Let'ssupposethefollowingcodeisthesimpleprogramthatreturnstheGMTofthecountrynamepassedinthefunction'sparameter:

functiongetCountryGMT(countryName){

if(countryName=="Pakistan"){

vargmt="+5.00";

}

elseif(country=="Dubai"){

vargmt="+4.00";

}else{

returnnull;

}

}

WhentheJavaScriptenginecompilesthescript,thevargmtvariablewillbeplacedatthetop:

functiongetCountryGMT(countryName){

vargmt;

if(countryName=="Pakistan"){

gmt="+5.00";

}

elseif(country=="Dubai"){

gmt="+4.00";

}else{

returnnull;

}

}

Thisiscalledhoisting,wherethevarvariablesareplacedatthetopwithinitsscope.Moreover,ifyoutrytoaccessthevariablevalueinthelastelsecondition,itwillgiveanundefinedvalueandcouldbeaccessibleineveryconditionblock.

Thiscodeshowsanotherexampleofdeclaringthegmtvariablegloballyanddeclaringitinthebottomofthecode:

functiongetCountryGMT(countryName){

if(countryName=="Pakistan"){

gmt="+5.00";

}

Page 83: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

elseif(country=="Dubai"){

gmt="+4.00";

}else{

returnnull;

}

}

vargmt;

Whenthescriptcompiles,itwillputthedeclarationofgmtatthetopofthecode:

vargmt;

functiongetCountryGMT(countryName){

if(countryName=="Pakistan"){

gmt="+5.00";

}

elseif(country=="Dubai"){

gmt="+4.00";

}else{

returnnull;

}

}

ToovercomethisbehaviorinECMAScript6,thereisanewletkeywordintroducedtodeclarevariablesandthescoperemainswhereitisdefined.Thesevariablesareinaccessibleoutsideitsscope.

Tip

NotethatECMAScript6isnotsupportedbyolderbrowserversionsbutMicrosoftEdge,GoogleChrome11,andMozillaFirefoxsupportit.

Page 84: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DeclaringletAswithvar,youcanuselettodeclarevariablesinthesameway.Youcanusethiskeywordinyourprogramsbutitwillbeaccessiblewithinthescopewhereitisdefined.So,forexample,ifsomevariableisdefinedwithintheconditionblock,itwillnotbeaccessibleoutsideitsscope.

Let'shavealookatthefollowingexample,whereavariableisdeclaredinsideaconditionblockandthefinaloutputaftercompilationsremainsasitis.Thisisbeneficialinconditionswhereyouwanttodeclarevariableswithinascopeforaparticularlogicorscenario.Intheelsecondition,gmtwillnotbeaccessible,asitisdefinedwithintheifcondition:

functiongetCountryGMT(countryName){

if(countryName=="Pakistan"){

letgmt="+5.00";

}

else{

returnnull;

}

}

Oncetheletvariableisdeclaredwithinthescopeofthefunctionorscript,itcannotberedeclared.Also,ifthevariablesaredeclaredusingthevarkeyword,theycannotberedeclaredusinglet.

Thiscodewillnotthrowanexceptionasthescopeisdifferent.However,withinthesameblock,itcannotberedeclared:

functiongetCountryGMT(countryName){

vargmt;

if(countryName=="Pakistan"){

letgmt="+5.00";

}

else{

returnnull;

}

}

Conditionswhereletisefficienttouse

Herearetheconditionswhereletisused.

Functionsinloops

Ifweusethevarvariablesinfunctionsinsideloop,thesevariablesgenerateissues.Considerthefollowingexample,wherethereisanarrayofvaluesand,throughlooping,weareinsertingafunctionateachindexofanyarray.Thiswillmakeanerrorandpasstheivariableasareference.So,ifyoutraverseeachindexandcallfunction,thesamevalue,thatis,10,willbeprinted:

Page 85: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

varvalues=[];

for(vari=0;i<10;i++)

{

values.push(function(){console.log("valueis"+i)});

}

values.forEach(function(valuesfunc){

valuesfunc();

})

Whereaswithlet,eachvaluewillbepassedbyvalueanddoesnotchangewhenthevariablevalueisupdatedinsidetheloop.

Thecodesnippetofusingletisasfollows:

varvalues=[];

for(leti=0;i<10;i++)

{

values.push(function(){console.log("valueis"+i)});

}

values.forEach(function(valuesfunc){

valuesfunc();

})

Page 86: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

EventsinJavaScriptEventsplayanimportantroleinanybusinessapplicationwhereyouwanttosavearecordonabutton-clickevent,orshowsomemessage,orchangesomeelement'sbackgroundcolor.Anyoftheseeventscanbedefinedfromthecontrollevelitselforregisterdirectlythroughthescript.

Let'shavealookatthisexample,whichchangestheinnerhtmlcodeofthedivcontrolwhenthemouseisentered:

<html>

<body>

<divid="contentPane"style="width:200px;height:200px;">

</div>

<script>

vardivPane=document.getElementById("contentPane");

divPane.onmouseenter=function(){

divPane.innerHTML="Youareinsidethediv";

};

divPane.onmouseleave=function(){

divPane.innerHTML="Youareoutsidethediv";

};

</script>

</body>

</html>

TheprecedingexampleregisteredtwoeventsonthescriptsideforanHTMLdivcontrol.Itchangestext,ifthemousehasenteredthefunctionorhaslefttheboundaryofdiv.Alternatively,wecanalsoregistereventsonthecontrolitself,andthisexampleshowsthewayyoucandisplayamessageonabutton-clickevent.Ifyouhavenoticedthescriptingblockisdefinedafterthedivpane,thereasonisthatwhenthepageloads,itwilltrytoexecutethescriptandthrowanerrorbecausethecontentPaneelementwasnotcreatedatthattime:

<html>

<body>

<script>

functiondisplayMessage(){

alert("youhaveclickedbutton");

}

</script>

<inputtype="button"onclick="displayMessage();"/>

</body>

</html>

Inthisexample,thescriptingblockisdefinedatthetopofthepage.Inthisscenario,itcanbedefinedanywhereinthepagebecauseitwillonlybeexecutedwhentheuserclicksonabutton.

Page 87: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

FunctionargumentsWealreadyknowthattheJavaScriptfunctionscanhaveparameters.However,thetypeoftheparameterscannotbespecifiedwhencreatingafunction.JavaScriptneitherperformsanytypecheckingontheparametervaluespassednorvalidatesthenumberofparameterswhenthefunctioniscalled.So,forexample,ifaJavaScriptfunctionistakingtwoparameters,asshowninthiscode,wecanevencallitwithoutpassinganyparametervalueorbypassinganytypeofthevaluesormorevaluesthantheexpectednumberoftheparametersdefined:

functionexecute(a,b){

//dosomething

}

//callingwithoutparametervalues

execute();

//passingnumericvalues

execute(1,2);

//passingstringvalues

execute("hello","world");

//passingmoreparameters

execute(1,2,3,4,5);

Themissingparametersaresetasundefined,whereasifmoreparametersarepassed,theseparameterscanbeaccessedthroughtheargumentsobject.Theargumentsobjectisabuilt-inobjectinJavaScriptthatcontainsanarrayoftheargumentsusedwhenthefunctionisinvoked.Wecanuseitasshowninthiscode:

functionexecute(a,b){

//dosomething

alert(arguments[0]);

alert(arguments[1]);

alert(arguments[2]);

alert(arguments[3]);

alert(arguments[4]);

}

//passingmoreparameters

execute(1,2,3,4,5);

}

Argumentsarepassedbyvalue;thismeansifthevaluesarechangedinsidethefunction,itwillnotchangetheparameter'soriginalvalue.

Page 88: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Object-orientedprogramminginJavaScriptAlltheobjectsinJavaScriptareinheritedfromanobject.JavaScriptprovidesdifferentpatternstoadheretotheobject-orientedprogramming(OOP)principleswhenbuildingapplications.Therearedifferentpatterns,suchasconstructorpatterns,prototypepatterns,andobjectliteralrepresentation,and,withECMAScript6,acompletelynewwayofrepresentingobjectsthroughclassesandinheritingabaseclassusingtheextendskeyword.

Inthissection,wewillseehowwecanimplementtheOOPprincipleswithdifferentmethodologies.

Page 89: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CreatingobjectsAclassrepresentsthestructureofanobjectandeveryclasshascertainmethodsandpropertiesusedbytheobject,whereasanobjectisaninstanceofaclassandisknownasaclassinstance.

JavaScriptisaprototype-basedlanguageandbasedonobjects.Inaclass-basedlanguagesuchasC#andJava,wehavetofirstdefinetheclassthatcontainssomemethodsandpropertiesandthenuseitsconstructortocreateobjects.InJavaScript,anyobjectcanbeusedasatemplatetocreatenewobjectsandusethepropertiesormethodsdefinedwithinit.Newobjectscanalsodefinetheirownpropertiesormethodsandcanbeassociatedasaprototypeforanotherobject.ECMAScript6,however,introducesclassesinJavaScript,whichissyntacticalsugaroverexistingparadigmsandmakesiteasyfordeveloperstowritesimplerandcleanercodetocreateobjects.Inthenextsection,wewillseedifferentwaysofcreatingobjectsinJavaScript.

Definingobjectsusingobjectliteralnotation

Objectliteralsarecomma-separatedlistsofnamevaluepairswrappedincurlybraces.

Objectliteralsaredefinedusingthefollowingsyntaxrules:

AcolonseparatesapropertynamefromavalueAvaluecanbeanydatatype,includingarrayliterals,functions,andnestedobjectliteralsEachnamevaluepairisseparatedbyacommafromthenextnamevaluepairdefinedThelastnamevaluepairshouldnotcontainanycommaafterit

Hereisthebasicrepresentationofapersonobjectinobjectliteralnotation:

varperson={id:"001",name:"Scott",isActive:true,

Age:35};

HereisanotherrepresentationofapersonModelobjectwithasavePerson()methodinobjectliteralnotation:

varpersonModel={id:"001",name:"Scott",isActive:true,

Age:35,function:savePerson(){//codetosavepersonrecord}};

Definingobjectsusingaconstructorpattern

ClassescanbedefinedusingfunctionsinJavaScript.ThiscodeshowsthesimplewayofdefiningacustomerclassinJavaScript:

varperson=newfunction(){};

Theprecedingcodejustdefinedanemptyclasswithadefaultconstructorandnopropertiesandmethods.Objectscanbeinitializedusinganewkeyword,asshowninthiscode:

varp1=newperson();

Page 90: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Thesamefunctioncanbedefinedinaregularfunctiondeclarationstyle:

functionperson(){};

Withtheregularfunctiondeclaration,theJavaScriptengineknowstofetchthefunctionwhenitisneeded.Forexample,ifyoucallitbeforethefunctiondeclarationinyourscript,itwillcallthisfunction,whereasthevariabledefiningapproachneedsthevariabletobedeclaredfirstbeforecallingit.

Usingtheclasskeyword

ECMAScript6providesanewwayofdefiningclassesandintroducedaclasskeyword,whichcanbeusedjustlikeinotherprogramminglanguages.Thiscodeistherepresentationofdefiningacustomerobject.Thedefaultconstructorisconstructor()thattakesnoparametersandcanbeoverriddenwithmoreparameters,dependingontherequirements.Eachclassallowsyoutodefineonlyoneconstructor,andiftheconstructorisoverridden,thedefaultconstructorwillnotbeusedtoinstantiateobjects:

classPerson{

constructor(){}

}

Properties

Propertiesareusedtostoreandreturnvalues.Wecandefinepropertieswheninitializingfunctionsandthesepropertieswillbeavailableeachtimetheobjectiscreated.

Definingpropertiesusingobjectliteralnotation

Propertiescanbedefinedinobjectsasliteralstrings.Forexample,inthiscode,thereisthecustomerobjectcontainingtwopropertiesandamethod.Thedrawbackwiththisapproachisthatthereisnoconstructorandwecannotrestrictuserstosupplypropertyvalueswheninitializinganobject.Eitheritcanbesetashardcoded,asshownhere,orafterinitializinganobject:

varperson={

id:"001",

name:"Person1",

savePerson:function(){

}

}

Definingpropertiesusingaconstructorpattern

Aconstructorfunctionpatternallowsyoutodefineparametersthatrestrictuserstopasspropertyvalueswheninstantiatingobjects.Considerthisexample;itcontainsacustomerobjectwithtwoproperties,namelyidandname:

varperson=function(id,name){

Page 91: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

this._id=id;

this._name=name;

}

Thethiskeywordreferstothecurrentobjectandpropertiescanbeaccessedusingthiswhencallinginsidetheclass,orthroughtheinstancevariable,asshowninthefollowingcode:

varp1=newperson("001","Person1");

console.log("PersonID:"+p1.PersonID);

console.log("PersonName:"+p1.name);

Propertyvaluescanalsobesetafterinitializinganobject,asshowninthefollowingcode:

varperson=function(){

}

varp1=newperson();

p1.id="001";

p1.name="Person1";

Thissnippetalsorepresentsthesameapproachofdefiningapersonobjectthattakestwoparameters.Wewillseethelimitationsofusingthisapproachinthenextsectionwhendealingwithprototypes:

functionperson(id,name){

this.id=id;

this.name=name;

this.logToConsole:function(){

console.log("PersonIDis"+this.id+",Name:"+this.name);

};

}

Definingpropertiesusingsetters/gettersinECMAScript6

InECMAScript6,thereisanewwayofdefiningpropertiesanditfollowsthestandardwaylikeotherprogramminglanguages:

classPerson{

constructor(id,name){

this.id=id;

this.name=name;

}

}

varp1=newperson("001","Person1");

console.log("PersonID:"+p1.id);

Unlikethisapproach,wecanalsodefinesettersandgettersusingthesetandgetkeywords.ConstructorsareoptionalinJavaScriptwhendefiningclasses;ifnoconstructorisdefined,thedefaultconstructor,constructor(),willbeinvokedonobjectinitialization.Let'shavealookatthisexamplecontainingapersonNamepropertyforbothsetterandgetter:

classPerson{

setName(name){

this.personName=name;

Page 92: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

getName(){

returnthis.personName;

}

}

varp1=newPerson();

p1.Name="Person1";

console.log("personName"+p1.Name);

JavaScriptpropertydescriptors

Everypropertyhasthepropertydescriptor,whichisusedtoconfigure,andhasthefollowingmeaning:

Writable:Thisattributeisusedtomakethecoderead-onlyorwritable.Thefalsekeywordmakesitread-onlyandthevaluecannotbemodified.Enumerable:Thisattributeisusedtohide/unhidethepropertytobeaccessibleorserializable.Settingthisattributetofalsewillnotshowupthepropertywhenyouiteratethroughanobject'smembersandalsocouldnotbeserializedwhenusingJSON.stringify.Configurable:Thisattributeisusedfortheonandoffconfigurationchanges.Forexample,settingthisattributetofalsewillpreventapropertytobemodifiedordeleted.

Alltheseattributesaretruebydefaultbutcanbeoverridden,asshowninthefollowingexample.Thisexamplehasacarobjectcontainingtwoproperties,namelynameandcolor:

varcar={

name:"BMW",

color:"black"

};

Displaypropertydescriptors

Youcandisplaytheexistingpropertiesusingthefollowingstatement:

display(Object.getOwnPropertyDescriptor(car,'name'));

Managingpropertydescriptors

Thepropertydescriptorsofanyobject'spropertycanbemanagedasshowninthefollowingcode:

Object.defineProperty(car,'color',{enumerable:false});

Object.defineProperty(car,'color',{configurable:false});

Object.defineProperty(car,'color',{writable:false});

Usinggettersandsetters

ThroughObject.defineProperty,wecanalsoaddsettersandgettersforproperties.Thisexampleaddsthefullnameofthecarbyconcatenatingmakeandname,andthensplittingnametogetthemodelandnamethroughtwodifferentproperties:

varcar={name:{make:"honda",brand:"accord"}};

Page 93: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Object.defineProperty(car,'fullname',

{

get:function(){

returnthis.name.make+''+this.name.brand

},

set:function(value){

varnames=value.split('');

this.name.make=names[0];

this.name.brand=names[1];

}

});

car.fullname="HondaAccord";

display(car.fullname);

Methods

Methodsaretheactionsthatcanbeperformedonobjects.InJavaScript,itcanberepresentedasapropertycontainingafunctiondefinition.Let'shavealookatadifferentapproachtodefiningthemethodsoftheJavaScriptobjects.

Definingmethodsthroughobjectliteralnotationapproach

AnexampleshowingthelogToConsole()methoddefinedintheobjectliteralnotationapproachisshownhere:

varperson={

id:"001",

name:"Person1",

logToConsole:function()

{

console.log("PersonIDis"+this.id+",CustomerName:"+this.name);

}

}

Definingobjectsusingtheconstructorfunctionapproach

Theconstructorfunctionapproachtodefiningmethodsisshowninthefollowingcode:

varperson=function(id,name){

this._id=id;

this._name=name;

this.LogToConsole=function(){

console.log("PersonNameis"+this._name);

}

}

varp1=newperson("001","Person1");

p1.LogToConsole();

Anotherwayistodeclaretheconstructorfunctionapproachisasfollows:

functionperson(id,name){

this._id=id;

this._name=name;

this.LogToConsole=function(){

console.log("Nameis"+this._name);

Page 94: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

}

varp1=newperson("001","Person1");

p1.LogToConsole();

InECMAScript6,thereisabettersyntaxfordefiningmethods.Thecodesnippetwiththesameexampleisasfollows:

classPerson{

constructor(){

}

setName(name){

this._name=name;

}

getName(){

returnthis._name;

}

logToConsole(){

console.log("PersonNameis"+Name);

}

}

varp1=newPerson();

p1.Name="Person1";

p1.logToConsole();

Themethodreturntypeisnotneededwhendefiningamethodanditisrealizedbasedonthemethodbody.

Extendingpropertiesandmethods

EveryJavaScriptobjecthasanobjectknownasaprototype.Aprototypeisapointertoanotherobject.Thisprototypecanbeusedtoextendtheobjectpropertiesandmethods.Forexample,ifyouaretryingtoaccesssomepropertyofanobjectthatisnotdefined,itwilllookintotheprototypeobjectandproceedthroughtheprototypechainuntilitisfoundorreturnsundefined.Therefore,whetheranobjectiscreatedusingaliteralsyntaxapproachoraconstructorfunctionapproach,itinheritsallthemethodsandpropertiesfromaprototypeknownasObject.prototype.

Forexample,anobjectcreatedusingnewDate()inheritsfromDate.prototype,andsoon.However,thebaseobjectitselfdoesnothaveanyprototype.

Wecaneasilyaddpropertiesandfunctionstoobjects,asshownhere:

varPerson=function(name){

this.name=name;

}

Page 95: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

varp1=newPerson("Person1");

p1.phoneNo="0021002010";

alert(p1.name);

Extendingexistingfunctionswithoutinitializinganobjectisdoneusingaprototypeobject.Let'shavealookatthisexample,whereweaddonemethod,logToConsole(),andaphoneNopropertyonaPersonfunction:

varPerson=function(name){

this.name=name;

}

Person.prototype.phoneNo="";

Person.prototype.logToConsole=function(){

alert("PersonNameis"+this.name+"andphoneNois"+this.phoneNo)

};

varp1=newperson("Person1");

p1.phoneNo="XXX"

p1.logToConsole();

Privateandpublicmembers

InJavaScript,therearenoaccessmodifierslikewehaveinC#.Allthemembersthataredefinedasthisorwithprototypesareaccessiblefromtheinstance,whereasothermembers,whicharedefinedinsomeotherway,arenon-accessible.

Let'shavealookatthisexample,whichenablesonlytheyandy1()methodstobeaccessibleoutsidethefunction:

functiona(){

varx=1;

this.y=2;

x1=function(){

console.log("thisisprivatelyaccessible");

}

this.y1=function(){

console.log("thisispubliclyaccessible");

}

}

Inheritance

InheritanceisacoreprincipleofOOP.InJavaScript,ifyouareworkingwithanolderversionthatdoesnotcomplywiththeES6standard,itisdoneusingprototype-basedprogramming.

Prototype-basedprogrammingisanOOPmodelthatdoesnotuseclassesbutextendsobjectsorinheritanceusingtheprototypechain.Thismeansthateveryobjecthasaninternalprototypeproperty,whichpointstoaparticularobjectornullifnotused.ThispropertyisnotaccessiblethroughtheprogramandisprivatetotheJavaScriptengine.So,forexample,ifyouarecallingsomeproperty,suchascustomer.getName,itwillfirstcheckthegetNamepropertylocallyontheobjectitself,otherwisegothroughthechainingprocessandtrytofinditbylinkingobjectsthroughtheprototypepropertyuntilitisfound.Ifnopropertyisdefined,

Page 96: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

itwillreturnundefined.

Considerthefollowingentity–relationshipmodel(ERD)thathasabasepersonobjectwithsomegenericpropertiesandtwochildobjects,namelyVendorandEmployee,withspecificproperties:

InordertoarticulatethesameinheritanceusingtheJavaScriptconstructorfunctionapproach,wecanusetheprototypepropertyofbothVendorandEmployeetothepersonobject,asshowninthiscode:

varPerson=function(id,name){

this.id=id;

this.name=name;

}

varVendor=function(companyName,location){

this.companyName=companyName;

this.location=location;

}

varEmployee=function(employeeType,dateOfJoining){

this.employeeType=employeeType;

this.dateOfJoining=dateOfJoining;

}

Vendor.prototype=newPerson("001","John");

Employee.prototype=newPerson("002","Steve");

varvendorObj=newVendor("ABC","US");

alert(vendorObj.id);

Intheprecedingexample,vendorObjisanobjectthatwascreatedfromtheVendorconstructorfunction.TheVendorconstructorisbothanobjectandafunctionbecausefunctionsareobjectsinJavaScript,andthevendorObjobjectcanhaveitsownpropertiesandmethods.ItcanalsoinheritmethodsandpropertiesfromtheVendorobject.

Page 97: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

BysettingtheprototypepropertyoftheVendorandEmployeeobjectstothePersoninstancethroughtheconstructorfunction,itinheritsallthepropertiesandmethodsofthePersonobjectandbecomesaccessiblebytheVendorandEmployeeobjects.

Object'spropertiesandmethodsdefinedusingtheprototypeobjectareinheritedbyalltheinstancesthatreferencedit.So,inourexample,weextendedtheVendorandEmployeeobjectsthroughtheprototypepropertyandassignedthemtothePersoninstance.Thisway,wheneveranyinstanceoftheVendororEmployeeobjectiscreated,itcanaccessallthepropertiesormethodsofanobjectofPerson.

Propertiesandmethodscanalsobeaddedthroughtheobject;forexample,wecanaddapropertytotheVendorobject,asshowninthefollowingcode,butthiswillbecomethestaticpropertyandnotaccessiblebytheVendorinstance:

Vendor.id="001";

Ontheotherhand,wecanalsoaddpropertiesandmethodstotheVendorinstanceaswellbutthiswillbeaccessiblebythatparticularinstanceonly:

varvendorObj=newVendor("ABC","US");

vendorObj.id="001";

Anothertechniqueofachievinginheritanceisbyassigningtheparent'sprototypetothechild'sprototypeobject,asshownhere:

Vendor.prototype=Person.prototype;

Withthistechnique,anymethodsorpropertiesaddedinthePersonprototypewillbeaccessiblebytheVendorobject:

varPerson=function(id,name){

this.id=id;

this.name=name;

}

//AddingmethodtothePerson'sprototypetoshowmessage

Person.prototype.showMessage=function(message){

alert(message);

}

varVendor=function(companyName,location){

this.companyName=companyName;

this.location=location;

}

//Assigningtheparent'sprototypetochild'sprototype

Vendor.prototype=Person.prototype;

varvendorObj=newVendor("XYZ","Dubai");

vendorObj.showMessage(vendorObjinstanceofPerson);

Afterrunningthisscript,itwillshowtrueinanalertmessage.ThisisbecausetheVendor

Page 98: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

objectbecomesaninstanceofthePersonobjectandanymethodorpropertyaddedinanyoftheobjectswillbeaccessiblebyboth.

IfwemodifytheprecedingexampleandaddanothermethodthroughaVendorprototypepropertyaftertheassignmentofthePersonprototypetotheVendorprototype,itwillbeaccessiblebythePersonobject.Thisisbecause,inJavaScript,whenthechild'sobjectprototypeissettotheparent'sobjectprototype,anymethodsorpropertiesaddedineitherobjectaftertheassignmentwillbeaccessiblebyboth.

Let'saddashowConsoleMessage()methodintheVendorobjectthroughaprototypepropertyandaccessitthroughthePersoninstance,asshowninthiscode:

varPerson=function(id,name){

this.id=id;

this.name=name;

}

//AddingmethodtothePerson'sprototypetoshowmessage

Person.prototype.showMessage=function(message){

alert(message);

}

varVendor=function(companyName,location){

this.companyName=companyName;

this.location=location;

}

//Assigningtheparent'sprototypetochild'sprototype

Vendor.prototype=Person.prototype;

//AddingmethodtotheVendor'sprototypetoshowatconsole

Vendor.prototype.showConsoleMessage=function(message){

console.log(message);

}

varpersonObj=newPerson("001","John");

//Personobjectaccessthechild'sobjectmethod

personObj.showConsoleMessage("Console");

ChainingconstructorsinJavaScript

Intheexampleintheprevioussection,wehaveseenhowtoinheritobjects.However,ifsomebaseobjecthassomeoverloadedconstructor,acceptingpropertieswillrequiresomeextraeffort.EveryfunctioninJavaScripthasacallmethod,whichisusedtochainconstructorsforanobject.Wecanusethecallmethodtochainconstructorsandcallbaseconstructors.AsthePersonobjecttakestwoparameters,wewillmodifytheVendorfunctionandtwoproperties,idandnumber,whichcanbepassedwhilecreatingaVendorobject.So,whenevertheVendorobjectiscreated,thePersonobjectwillbecreatedandthevalueswillbepopulated:

varPerson=function(id,name){

this.id=id;

this.name=name;

Page 99: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

varVendor=function(companyName,location,id,name){

this.companyName=companyName;

this.location=location;

Person.call(this,id,name);

}

varemployee=function(employeeType,dateOfJoining,id,name){

this.employeeType=employeeType;

this.dateOfJoining=dateOfJoining;

Person.call(this,id,name);

}

Vendor.prototype=Person.prototype;

Employee.prototype=Person.prototype;

varvendorObj=newVendor("ABC","US","V-01","Vendor1");

alert(vendorObj.name);

InheritanceusingObject.create()

WithECMAScript5,youcaneasilyinherityourbaseobjectthroughtheObject.create()method.Thismethodtakestwoparameters,theobjecttouseasaprototypeandanobjectcontainingpropertiesandmethodsforthenewobjecttocreate.TheObject.create()methodimprovesconstructor-basedinheritance.It'sagoodchoiceforcreatinganobjectwithoutgoingthroughitsconstructor.Let'sseetheexampleofVendorandEmployeeinheritingthePersonobjectusingtheObject.create()approach:

varPerson=function(id,name){

this.id=id;

this.name=name;

}

varVendor=function(companyName,location,id,name){

this.companyName=companyName;

this.location=location;

Person.call(this,id,name);

}

varEmployee=function(employeeType,dateOfJoining,id,name){

this.employeeType=employeeType;

this.dateOfJoining=dateOfJoining;

Person.call(this,id,name);

}

Vendor.prototype=Object.create(Person.prototype);

Employee.prototype=Object.create(Person.prototype);

varvendorObj=newVendor("ABC","US","V-01","Vendor1");

alert(vendorObj.name);

Intheprecedingexample,weusedObject.create()toinheritthePersonobjecttotheVendorandEmployeeobjects.WhenevertheVendororEmployeeinstancesarecreated,theycanaccess

Page 100: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

thepropertiesofthePersonobject.TheObject.create()methodautomaticallyinstantiatesaninstanceofanobjectdefinedastheparameterinitscallmethod.

PredefinedpropertiesofObject.create()

AnObject.create()methoddoesnotexecutethePersonfunction;instead,itwilljustsetthePersonfunctionasaprototypeofthecustomerfunction.Anotherrepresentationofthecustomerobject,containingpropertyasCustomerCode,isshowninthefollowingcode:

varcustomerObj=Object.create(Object.prototype,{

customerCode:{

value:"001",

enumerable:true,

writable:true,

configurable:true

}

});

alert(""+customerObj.customerCode);

Here,valueistheactualvaluerepresentingthecustomercode,whereasenumerable,writable,andconfigurablearepredefinedattributes.

Defininginheritanceusingclass

Intheexampleintheprevioussection,wehavealreadyseenhowtodefineclassesusingECMAScript6.JustlikeJava,wecaninheritaparentclassusingtheextendskeyword.

Anexampleofusingextendsisshownhere:

classPerson{

constructor(id,name){

this._id=id;

this._name=name;

}

getGetID(){returnthis._id;}

getGetName(){returnthis._name;}

}

classVendorextendsPerson{

constructor(phoneNo,location,id,name){

super(id,name);

this._phoneNo=phoneNo;

this._location=location;

}

logToConsole(){

alert("PersonIDis"+this.GetID);

}

}

varvendorObj=newVendor("XXX","US","V-01","Vendor1");

vendorObj.logToConsole();

Page 101: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WithECMAScript6,youcangetthetrueessenceofdeclaringstaticvariablesandmethodsintheclass.Let'shavealookatthefollowingexample,whichcontainsonestaticmethod,logToConsole(),andcallsitfromthecustomerclasswithoutinitializingitsobjectafterinheritingitfromthePersonclass:

classPerson{

staticlogToConsole(){

console.log("Hellodevelopers!");

}

}

classVendorextendsPerson{

}

Vendor.logToConsole();

Encapsulation

Intheexampleintheprevioussection,theVendorobjectdoesn'tneedtoknowtheimplementationofthelogToConsole()methodinthePersonclassandcanusethatmethod.TheVendorclassdoesn'tneedtodefinethismethodunlessoverridingforaspecificreason.Thisiscalledencapsulation,inwhichtheVendorobjectdoesn'tneedtoknowtheactualimplementationofthelogToConsole()methodandeachVendorobjectcanusethismethodtologtoconsole.Thisishowtheencapsulationisdone,throughwhicheveryclassisencapsulatedintoasingleunit.

Abstraction

Abstractionisusedtohidealltheinformationexceptthedata,whichisrelevantaboutanobject,toreducecomplexityandincreaseefficiency.ThisisoneofthecoreprinciplesofOOP.

InJavaScript,thereisnobuilt-insupportforabstractionanditdoesnotprovideanytypesuchasaninterfaceorabstracttocreateinterfacesorabstractclassestoachieveabstraction.However,therearecertainpatternsthroughwhichyoucanimplementabstractionbutstillitdoesnotrestrictandensuresthatalltheabstractmethodsarecompletelyimplementedbytheconcreteclassorfunction.

Let'shavealookatthefollowingexample,wherewehaveapersoncontrollerthattakesaconcreteobjectasaparameter,andthencallsitsspecificimplementation:

varperson=function(id,name){

this._id=id;

this._name=name;

this.showMessage=function(){};

}

varvendor=function(companyName,location,id,name){

this._companyName=companyName;

this._location=location;

person.call(this,id,name);

Page 102: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

this.showMessage=function(){

alert("thisisVendor");

}

}

varemployee=function(employeeType,dateOfJoining,id,name){

this._employeeType=employeeType;

this._dateOfJoining=dateOfJoining;

person.call(this,id,name);

this.showMessage=function(){

alert("thisisEmployee");

}

}

vendor.prototype=Object.create(person.prototype);

employee.prototype=Object.create(person.prototype);

varpersonController=function(person){

this.personObj=person;

this.showMessage=function(){

this.personObj.showMessage();

}

}

varv1=newvendor("ABC","USA","V-01","Vendor1");

varp1=newpersonController(v1);

p1.showMessage();

Alternatively,withECMAScript6,wecanimplementthesamescenario,asshowninthefollowingcode:

classperson{

constructor(id,name){

this._id=id;

this._name=name;

}

showMessage(){};

}

classvendorextendsperson{

constructor(companyName,location,id,name){

super(id,name);

this._companyName=companyName;

this._location=location;

}

showMessage(){

alert("thisisVendor");

}

}

classemployeeextendsperson{

constructor(employeeType,dateOfJoining,id,name){

super(id,name);

this._employeeType=employeeType;

this._dateOfJoining=dateOfJoining;

}

showMessage(){

alert("thisisEmployee");

}

}

Page 103: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

classpersonController{

constructor(person){

this.personObj=person;

}

showMessage(){

this.personObj.showMessage();

}

}

varv1=newvendor("ABC","USA","V-01","Vendor1");

varp1=newpersonController(v1);

p1.showMessage();

new.target

Thenew.targetpropertyisusedtodetectwhetherthefunctionoraclassiscalledusingthenewkeyword.Itreturnsareferencetothefunctionoraclassifitiscalled,otherwisenull.Consideringtheexampleintheprevioussection,wecanrestrictcreatingthecallobjectsofpersonbyusingnew.target:

classperson{

constructor(id,name){

if(new.target===person){

thrownewTypeError("CannotcreateaninstanceofPersonclassasits

abstractinnature");

}

this._id=id;

this._name=name;

}

showMessage(){};

}

Namespace

ECMAScript6introducedmodulesthroughwhichyoucandefinenamespacesandusetheexportandimportkeywordsbuttheyarestillindraftandnoimplementationsarepresentsofar.

However,withearlierversions,namespacescanbesimulatedusinglocalobjects.Forexample,hereisthesyntaxtodefinealocalobjectrepresentedasanamespaceandwecanaddfunctionsandobjectsinsideit:

varBusinessLayer=BusinessLayer||{};

Wecanthenaddfunctions,asshowninthiscode:

BusinessLayer.PersonManager=function(){

};

Moreover,morenestednamespacehierarchycanalsobedefined,asshowninthefollowingcode:

Page 104: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

varBusinessLayer=BusinessLayer||{};

varBusinessLayer.Managers=BusinessLayer.Managers||{};

Page 105: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ExceptionhandlingJavaScriptisbecomingapowerfulplatformfordevelopinglargeapplications,andexceptionhandlingplaysanimportantroleinhandlingexceptionsinprogramsandpropagatethemwhereneeded.JustlikeC#oranyotherprogramminglanguage,JavaScriptprovidesthetry,catch,andfinallykeywordstoannotatecodeforhandlingerrors.JavaScriptprovidesthesamewayofusingthenestedtrycatchstatementsandconditionsforhandlingdifferentconditionsinthecatchblock.

Whenanexceptionoccurs,anobjectiscreatedthatrepresentstheerrorthrown.JustlikeC#,wehavedifferenttypesofexception,suchasInvalidOperationException,ArgumentException,NullException,andException.JavaScriptprovidessixerrortypes,whichareasfollows:

Error

RangeError

ReferenceError

SyntaxError

TypeError

URIError

Error

TheErrorobjectrepresentsgenericexceptionsandismostlyusedinreturninguser-definedexceptions.AnErrorobjectcontainstwoproperties,namelynameandmessage.Namereturnsthetypeoferrorandmessagereturnstheactualerrormessage.Wecanthrowerrorexceptions,asshownhere:

try{}catch{thrownewError("Someerroroccurred");}

RangeError

TheRangeErrorexceptionisthrowniftherangeofanynumberisexceeded.Forexample,creatinganarraywithanegativelengthwillthrowRangeError:

vararr=newArray(-1);

ReferenceError

TheReferenceErrorexceptionoccurswhenaccessinganobjectorvariablethatdoesnotexist;forexample,thefollowingcodewillthrowaReferenceErrorexception:

functiondoWork(){

arr[0]=1;

}

SyntaxError

Asthenamestates,SyntaxErroristhrownifthereisanysyntaxproblemintheJavaScript

Page 106: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

code.So,ifsomeclosingbracketismissing,loopsarenotstructuredproperly,andsoon,thiswillcomeundertheSyntaxErrorcategory.

TypeError

TheTypeErrorexceptionoccurswhenavalueisnotoftheexceptedtype.ThefollowingcodethrowsaTypeErrorexceptionastheobjectistryingtocallamethodthatdoesnotexist:

varperson={};

person.saveRecord();

URIError

TheURIErrorexceptionoccurswithencodeURI()anddecodeURI()whenaninvalidURIisspecified.Thefollowingcodethrowsthiserror:

encodeURIComponent("-");

Page 107: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ClosuresClosuresareoneofthemostpowerfulfeaturesofJavaScript.Closuresprovideawaytoexposeinnerfunctionsthatareinsidethebodyofotherfunctions.Afunctioncanbetermedaclosurewhenoneoftheinnerfunctionsismadeaccessibleoutsidethefunctioninwhichitwascontainedandcanbeexecutedaftertheouterfunctionisexecutedandusethesamelocalvariables,parameters,andfunctiondeclarationswhentheouterfunctionwascalled.

Let'shavealookatthefollowingexample:

functionIncrementor(){

varx=0;

returnfunction(){

x++;

console.log(x);

}

}

varinc=Incrementor();

inc();

inc();

inc();

Thisisasimpleclosureexample,inwhichinc()becomestheclosurethatreferencestheinnerfunction,whichincrementsthexvariabledefinedintheouterfunction.Thexvariablewillbeincrementedoneachcallandthevaluewillbecome3onthelastcall.

Aclosureisaspecialkindofobjectthatcombinesthefunctionandtheenvironmentinwhichthatfunctionwascreated.So,callingitmultipletimeswillusethesameenvironmentandthevaluesbeingupdatedinthepreviouscall.

Let'shavealookatanotherexample,wherewehaveatablegeneratorfunctionthattakesatablenumberandreturnsthefunction,whichcanbeusedtogettheresultofanynumbermultiplicationwiththetablenumbersuppliedonthefirstcall:

functiontableGen(number){

varx=number;

returnfunction(multiplier){

varres=x*multiplier;

console.log(x+"*"+multiplier+"="+res);

}

}

vartwotable=tableGen(2);

varthreetable=tableGen(3);

twotable(5);

threetable(6);

Theresultantvaluesaftercallingthetwotable()andthreetable()methodswillbe10and

Page 108: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

18.ThisisbecausethetwoTable()functionobjectwasinitializedbypassing2astheparametertothetableGen()function.ThistableGen()functionthenstoresthevaluepassedasaparameterinthexvariableandmultipliesitwiththevariablepassedinthesecondcallwhenitisexecutedthroughthetwoTable()andthreeTable()methodcalls.

Hence,theoutputofthetwoTable(5)functioncallwillbe10,asshowninthefollowingscreenshot:

Theoutputofthesecondstatement,threeTable(6),willbe18,asshowninthefollowingscreenshot:

Practicaluse

Wehaveseenwhatclosuresareandhowwecanimplementthem.However,let'sconsidertheirpracticalimplications.Closuresletyouassociatesomeenvironmentwithafunctionthatoperateswithinthatenvironmentordata.

InJavaScript,functionsmostlyexecuteonanyeventortriggeronanyactiontakenbytheuser.Let'shavealookatthefollowingexampleofthepracticaluseofclosurestologmessagesonaconsoleanddialogwindow:

<body>

<inputtype="text"id="txtMessage"/>

<buttonid="consoleLogger">LogtoConsole</button>

<buttonid="dialogLogger">LogtoDialog</button>

<script>

functiongetLogger(loggerType){

returnfunction(){

varmessage=document.getElementById("txtMessage").value;

if(loggerType=="console")

console.log(message);

elseif(loggerType=="dialog")

alert(message);

}

}

varconsoleLogger=getLogger("console");

vardialogLogger=getLogger("dialog");

document.getElementById("consoleLogger").onclick=consoleLogger;

document.getElementById("dialogLogger").onclick=dialogLogger;

Page 109: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

</script>

</body>

Intheprecedingexample,wehavetwologgerclosures:onethatlogstotheconsoleandtheotheronetoapop-updialogwindow.Wecaninitializetheseclosuresandusethemthroughoutourprogramtologmessages.

Page 110: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

JavaScripttypedarraysClient-sidedevelopmentinJavaScripthasbecomeapowerfulplatformandtherearecertainAPIsandlibrariesavailablethatallowyoutoworkwithmediafiles,Websockets,andsoon,andhandledatainbinary.Whenworkingwithbinarydata,itisrequiredtosaveitinitsownspecificformat.Herecomestheroleoftypedarrays,whichallowdeveloperstomanipulatedatainarawbinaryformat.

Typedarrayarchitecture

Typedarrayskeepthedataintwoportions,namelybufferandview.Buffercontainstheactualdatainbinarybutitcannotbeaccessiblewithoutview.Viewtellstheactualmetadatainformationandcontextaboutthebuffer,suchasdatatype,startingoffset,andnumberofelements.

Thearraybuffer

Thearraybufferisadatatypethatisusedtorepresentbinarydata.Itscontentcannotbemanipulateduntilitisassignedtoaview,whichrepresentsthebufferinaspecificformatandperformsmanipulationonthedata.

Therearedifferenttypesoftypearrayviews,whichareasfollows:

Type Sizeinbytes Description

Int8Array 1 Thisarrayis8-bitsignedinteger.

UInt8Array 1 Thisarrayis8-bitunsignedinteger.

Int16Array 2 Thisarrayis16-bitsignedinteger.

UInt16Array 2 Thisarrayis16-bitunsignedinteger.

Int32Array 4 Thisarrayis32-bitsignedinteger.

UInt32Array 4 Thisarrayis32-bitunsignedinteger.

Float32Array 4 Thisarrayis32-bitIEEEfloatingpointnumber.

Float64Array 8 Thisarrayis64-bitIEEEfloatingpointnumber.

Page 111: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UInt8ClampedArray 1 Thisarrayis8-bitunsignedinteger(clamped).

Now,let'sgothroughanexampletoseehowwecanstoredatainabufferandmanipulateitthroughaview.

Creatingabuffer

Firstofall,weneedtocreateabuffer,asshowninthiscode:

varbuffer=newArrayBuffer(32);

Theprecedingstatementallocatesthememoryfor32bytes.Nowwecanuseanyofthetypearrayviewstomanipulateit:

varint32View=newInt32Array(buffer);

Andfinally,wecanaccessthefields,asshownhere:

for(vari=0;i<int32View.length;i++){

int32View[i]=i;

}

Thiscodewillmakeeightentriesintotheview,from0to7.Theoutputwilllookasfollows:

01234567

Thesamebuffercanalsobemanipulatedwiththeotherviewtypes.Forexample,ifwewantedtoreadthepopulatedbufferwitha16-bitarrayview,theresultwillbelikethis:

varInt16View=newInt16Array(buffer);

for(vari=0;i<int16View.length;i++){

console.log(int16View[0]);

}

Theoutputwilllookasfollows:

0010203040506070

Thisishoweasilywecanmanipulatesinglebufferdatawithmultipleviewsofdifferenttypesandinteractwiththedataobjectscontainingmultipledatatypes.

Page 112: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Maps,sets,weakmaps,andweaksetsMaps,weakmaps,sets,andweaksetsareobjectsthatrepresentcollections.Mapsarekeyedcollectionsthatholdvaluesinnamevaluepairs,whereassetsstoreuniquevaluesofanytype.Wewilldiscusseachoftheminthenextsections.

Mapsandweakmaps

AMapobjectprovidesasimplekey/valuemapanditeratesitbasedontheinsertion.Thefirstinsertedvaluewillberetrievedfirst.Weakmapsarenon-enumerableandholdobjecttypesonly.Noprimitivetypesareallowedinweakmapsandeachkeyrepresentsanobject.Let'shavealookatthefollowingexampleofusingamapforcurrencies:

varcurrencies=newMap();

currencies.set("US","USDollar");

currencies.set("UK","BritishPound");

currencies.set("CA","CanadianDollar");

currencies.set("PK","Rupee");

currencies.set("UAE","Dirham");

for(varcurrencyofcurrencies){

console.log(currency[0]+"currencyis"+currency[1]);

}

SomeotherpropertiesandmethodsavailableontheMapobjectareshowninthefollowingcode:

currencies.get("UAE");//returnsdirham

currencies.size;//returns5

currencies.has("PK")//returnstrueiffound

currencies.delete("CA")//deleteCanadafromthelist

Insteadofsimpleprimitivevalues,weakmapsholdobjectsandtheirkeysarerepresentedasweakkeys.Thisisbecauseifthereisnoreferencetotheobjectstoredinaweakmapvalueandgotcollectedingarbage,thekeywillbecomeweak.Itisnormallyusedtostoreprivatedataforanobjectortohideimplementationdetails.

Welearnedintheprevioussectionthateverythingthatisexposedontheinstancelevelandprototypelevelispublic.ThepracticalexamplecontainingafunctiontoauthenticateauserfromaTwitteraccountisshowninthefollowingcode.Foropenauthentication(OAuth),Twitterneedstwokeys:theconsumerAPIkeyandasecretkey.Wedon'twantedtoexposeandlettheusertochangethisinformation.Therefore,wehavekeptthisinformationusingweakmaps,andthenretrieveditintheprototypefunctiontoauthenticatetheuser:

varauthenticatorsecrets=newWeakMap();

functionTwitterAuthenticator(){

constloginSecret={

apikey:'testtwitterapikey',

secretkey:'testtwittersecretkey'

};

Page 113: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

authenticatorsecrets.set(this,loginSecret);

}

TwitterAuthenticator.prototype.Authenticate=function(){

constloginSecretVal=authenticatorsecrets(this);

//todoauthenticatewithtwitter

};

Setsandweaksets

Setsarethecollectionsofvalueswhereeachvalueshouldbeunique.So,forexample,ifatanyindexyouhaveavalue,1,alreadydefined,youcannotinsertitintothesamesetinstance.

Setsarenottypedandyoucanputanydata,irrespectiveofanydatatype:

varset=newSet();

set.add(1);

set.add("HelloWorld");

set.add(3.4);

set.add(newDate());

Ontheotherhand,weaksetsarecollectionsofuniqueobjectsandnotthearbitraryvaluesofanytype.Justlikeweakmaps,ifthereisnootherreferencetotheobjectstored,itwillbedisposedandgarbagecollected.Similartoweakmaps,theyarenotenumerable:

varno={id:1};

varabc={alphabets:['a','b','c']};

varx=newWeakSet();

x.add(no);

x.add(abc);

Thestrictmode

ThestrictmodeisaliteralexpressionintroducedinECMAScript5.ItisusedtowriteasecureJavaScriptandthrowserrorsifthereareanyminorerrorsonyourscriptanddoesn'toverlookthem.Secondly,itrunsfasterthanthenormalJavaScriptcodebecauseitsometimesfixesmistakes,whichhelpsJavaScriptenginestoperformoptimizationsandmakeyourcoderunfaster.

Wecaninvokethestrictmodeonaglobalscriptlevelorafunctionlevel:

"usestrict;"

Forexample,inthefollowingcode,itwillthrowanerrorasthexvariableisnotdefined:

"usestrict";

x=100;

functionexecute(){

"usestrict;"

x=100;

}

Page 114: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Forlargerapplications,it'sabetterchoicetousethestrictmode,whichwillthrowanerrorifsomethingismissingornotdefined.Thelistofscenarioswhereusingthestrictmodewillresultinanerrorisshowninthefollowingtable:

Code Reasonforerror

x=100; Inthiscode,variableisnotdeclared.

x={id:1,name:'ABC'}; Inthiscode,objectvariableisnotdeclared.

function(x,x){}Duplicatingtheparameternamecausedtheerrorinthiscode.

varx=0001 Inthiscode,octalnumericliteralsareused.

varx=\0001 Escapeisnotallowed,sotheerroroccurred.

varx={getval(){return

'A'}};

x.val='B'

Writingtoagetvaluecausedtheerrorinthiscode.

deleteobj.prototype;Deletingobjectprototypeisnotallowed,sotheerroroccurred.

varx=2;

deletex;

Deletingavariableisnotallowed,sotheerroroccurred.

Moreover,therearecertainreservedkeywords,suchasarguments,eval,implements,interface,let,package,private,protected,public,static,andyield,whicharenotallowedaswell.

Page 115: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryInthischapter,welearntaboutsomeadvancedconceptsofJavaScript,suchashoistedvariablesandtheirscope,propertydescriptors,OOP,closures,typedarraystostoretypesofdata,andexceptionhandling.Inthenextchapter,wewilllearnaboutthemostextensivelyusedlibrary,jQuery,toperformDOMtraversalandmanipulation,eventhandling,andmoreinaverysimpleandeasyway.

Page 116: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter3.UsingjQueryinASP.NETWewillstartoffthischapterwithashortintroductiontojQuery.jQueryisaJavaScriptlibrarydevelopedtoprovideabetterdevelopmentexperienceandafastercodingexperiencebywritinglesscodetodocomplexoperationsmuchfastercomparedtoplainvanillaJavaScript.However,JavaScriptisstilltherewhenwritingcustomscriptsforspecificreasons.So,jQueryhelpsyouperformDOMmanipulation,selectingelementsbasedonclass,elementname,andsoon,andprovidesabettereventhandlingmodeltomakeitsimplerfordeveloperstouseintheirroutineprojects.

ComparedtoJavaScript,anotheradvantageisthecrossbrowserissues.Itoffersconsistentbehavioracrossbrowsers.JavaScript,ontheotherhand,isimplementeddifferentlybyeachbrowser.Also,inordertohandlecross-browserissuesinJavaScript,adevelopertendstowritesomeconditionallogictocheckwhatbrowserversionJavaScriptisrunningonandhandleitaccordingly;whereasjQueryhandlesalltheheavyliftingofwhatthebrowserisandprovidesconsistentbehavior.

SomepowerfulfeaturesofjQuerythatwewilldiscussinthecurrentchapterareasfollows:

WorkingwithselectorsManipulatingtheDOMelementsHandlingevents

Page 117: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

GettingstartedwithjQueryThejQuerylibrarycanbedownloadedfromhttp://jquery.com.ThelatestversionofjQueryis3.0.0andyoucanusethislibraryifyouaretargetingmodernbrowsers;forexample,IE9andMicrosoftEdgesupportthisversion.Forolderversions—forexample,IE6-8—youcandownloadjQuery1.x.

OncejQueryisdownloaded,youcanaddittoyourprojectandreferenceit,asshownhere:

<head>

<scriptsrc="~/scripts/jquery.js"></script>

</head>

<body>

</body>

Page 118: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UsingacontentdeliverynetworkInsteadofloadingjQueryfromyourserver,wecanalsoloaditfromsomeotherserver,suchastheMicrosoftserverorGoogleserver.Theseserversarecalledthecontentdeliverynetwork(CDN)andtheycanbereferencedasshownhere:

ReferencingtheMicrosoftCDN:

<scriptsrc="http://ajax.microsoft.com/ajax/jquery/jquery-2.0.js">

</script>

ReferencingtheGoogleCDN:

<scriptsrc="http://ajax.googleapis.com/ajax/libs/jquery/2.0/jquery.min.js">

</script>

TheuseofCDN

Actually,theseCDNsareverycommonandmostofthesitesalreadyusethem.WhenrunninganyapplicationthatreferencesaCDN,therearechancesthatsomeotherwebsitemighthavealsousedthesameCDNofMicrosoftorGoogle,andthesamefilemightbecachedontheclientside.Thisincreasesthepagerenderingperformance.Also,downloadingthejQuerylibraryagainfromyourlocalserverusesthecachedversionofCDN.Moreover,MicrosoftandGooglehavedifferentserversavailable,basedondifferentregions,andtheuserwillgetsomespeedbenefitstoowhenusingitfromaCDN.

However,therearecertaincaseswhentheCDNmightbedown,andinthiscase,youmighthavetorefertoanddownloadscriptsfromyourownserver.Tohandlethisscenario,wecanspecifythefallbackURL,whichdetectswhetherithasbeendownloadedfromCDN;otherwise,itdownloadsfromthelocalserver.Wecanusethefollowingscripttospecifythefallback:

<scriptsrc="//ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js">

</script>

<script>if(!window.jQuery){document.write('<script

src="/path/to/your/jquery"><\/script>');}

</script>

Thewindow.jQueryinstancetellsuswhetherjQueryisloaded;otherwise,itwritesthescriptontheDOM,whichreferstothelocalserver.

Alternatively,inASP.NETCore,wecanusetheasp-fallback-srcattributetospecifythefallbackURL.ASP.NETCore1.0providesawiderangeoftaghelpers.ComparedtotheHTMLhelpers,thesehelperscanbeusedjustbyaddingtheHTMLattributestothepageelementsandtheyofferdevelopersthesameexperienceaswritingthefrontendcode.

ThesamecodecanbewritteninasimplewaytohandlethefallbackscenariosinASP.NET:

<scriptsrc="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"

Page 119: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

asp-fallback-src="~/lib/jquery/dist/jquery.min.js"

asp-fallback-test="window.jQuery">

</script>

InASP.NETCore,thereisonemoretaghelper,<environment>,whichcanbeusedtoloadscriptsbasedonthecurrentenvironmentsetinthelaunchSettings.jsonfile:

Basedonthecurrentenvironmentsetintheproject'sprofile,wecanloadscriptstocatertodebuggingandproductionscenarios.Forexample,inaproductionenvironment,preferably,weusedtospecifytheminifiedversionoftheJavaScriptlibrariesasitremovesallthewhitespacesandrenamesthevariablestomakeitmorecompressedinsizetoloadfast.However,fordebuggingpurposes,thestandardnon-minifiedversionismuchbetterasfarasthedevelopmentexperienceisconcerned.Therefore,wecanusetheenvironmenttaghelper,asshowninthefollowingcode,toloadtheminifiedversionforproductionandstandardwhendevelopinganapplication:

<environmentnames="Development">

<scriptsrc="~/lib/jquery/dist/jquery.js"></script>

<scriptsrc="~/lib/bootstrap/dist/js/bootstrap.js"></script>

<scriptsrc="~/js/site.js"asp-append-version="true"></script>

</environment>

<environmentnames="Staging,Production">

<scriptsrc="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"

asp-fallback-src="~/lib/jquery/dist/jquery.min.js"

asp-fallback-test="window.jQuery">

</script>

<scriptsrc="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/bootstrap.min.js"

asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"

asp-fallback-test="window.jQuery&&window.jQuery.fn&&

window.jQuery.fn.modal">

</script>

Page 120: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<scriptsrc="~/js/site.min.js"asp-append-version="true"></script>

</environment>

Page 121: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ThedocumentreadyeventThejQuerylibrarycanbeaccessedthrougha$signorsimplybywritingjQuery.However,preferably,developersaccessitusingadollarsign.ItalsoprovidesawaytocatchaneventwhentheDOMhierarchyiscompletelyloaded.ThismeansthatoncetheDOMstructureisloaded,youcancatchthiseventtoperformdifferentoperations,suchasassociatingtheCSSclasswithcontrolsandmanipulatingcontrolvalues.TheDOMhierarchyisnotdependentonthetheimagesorCSSfileswhenthepageisloadingandthedocumentreadyeventisraisedinparallelirrespectiveofwhethertheimagesorCSSfilesaredownloadedornot.

Wecanusethedocumentreadyevent,asshowninthiscode:

<html>

<head>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

console.log("Documentislo aded");

});

</script>

</head>

</html>

Asexplainedintheprecedingcode,$isthewayofaccessingajQueryobject.Ittakesadocumentobject,whichispassedasaparameter,whereasreadycheckswhetherthedocumentobjectmodelhierarchyisloadedcompletelyonce.Finally,ittakesananonymousfunctioninwhichwecanwritetheoperationthatweneedtoperform.Intheprecedingexample,wearejustdisplayingasimpletextmessagewhentheDOMhierarchygetsloaded.

Page 122: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ThejQueryselectorsForDOMmanipulation,thejQueryselectorsplayanimportantroleandprovideabetterandeasyone-lineapproachtoselectanyelementfromDOMandmanipulateitsvaluesandattributes,forexample,searchingalistofelementswithaspecificCSSclassiseasierwiththejQueryselectors.

ThejQueryselectorscanbewrittenwithadollarsignandparentheses.WecanusethejQueryselectorstoselectelementsbasedontheelement'sID,tagname,class,attributevalue,andinputnodes.Wewilllookintotheseelementsonebyonewithapracticalexampleinthenextsection.

SelectingtheDOMelementsusingtheID

ThefollowingexampleshowsyouthewayofselectingadivelementwithitsID:

<!DOCTYPEhtml>

<html>

<head>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('#mainDiv').html("<h1>HelloWorld</h1>");

});

</script>

</head>

<body>

<divid="mainDiv">

</div>

</body>

</html>

Afterselectinganelement,wecancallvariousmethodstosetvalues.Inthegivenexample,wecalledthehtml()methodthattakesthehtmlstringandsetsHelloWorldasthefirstheading.Ontheotherhand,thehtmlcontentcanberetrievedbycallingthiscode:

<script>

$(document).ready(function(){

varhtmlString=$('#mainDiv').html();

});

</script>

SelectingtheDOMelementsusingTagName

InJavaScript,wecanretrievetheDOMelementsbycallingdocument.getElementsByTagName().Thiselementreturnsanarrayofelementsmatchedwiththetagname.InjQuery,thiscanbeachievedinaneasierwayandthesyntaxisquitesimple.

Page 123: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Considerthefollowingexample:

$('div')//returnsallthedivelements

Let'shavealookatthefollowingexampletoclarifyourunderstanding:

<!DOCTYPEhtml>

<html>

<head>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('div').css('text-align,'left');

});

</script>

</head>

<body>

<divid="headerDiv">

<h1>Header</h1>

</div>

<divid="mainDiv">

<p>Main</p>

</div>

<divid="footerDiv">

<footer>Footer</footer>

</div>

</body>

</html>

Theprecedingexamplesetsallthedivchildcontrolsalignmenttotheleft.Ifyounotehere,wedidn'thavetoloopthroughallthedivcontrolstosetthebackgroundcolorandthestylehasbeensetonall.However,therearecertaincasesinwhichyoumightneedtosetdifferentvaluesbasedontheindexofeachelementresiding,andthiscanbedoneusingtheeach()functionondiv.Forexample,thefollowingscriptshowsyouthewayofassigninganindexvalueasanhtmlstringoneachdivcontrolusingtheeachfunction:

<script>

$(document).ready(function(){

$('div').each(function(index,element){

$(element).html(index);

});

});

</script>

Eachfunctiontakesafunctionwiththeindexandelementsasaparameter.Wecanaccesseachelementusingadollarsign,asshownintheprecedingcode,andsettheindexasthecontentbycallingthehtmlmethod.Theoutputwillbesimilartothefollowingscreenshot:

Page 124: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Let'shavealookatanotherexamplethatdisplaysthecontentofeachdivcontrolinaconsolewindow.Here,theeach()functiontakesnoparametersandeachitemintheloopcanbeaccessedthroughthethiskeyword:

<!DOCTYPEhtml>

<html>

<head>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('div').each(function(){

alert($(this).html());

});

});

</script>

</head>

<body>

<divid="headerDiv">

<h1>Demo</h1>

</div>

<divid="mainDiv">

<p>ThisisademoofusingjQueryforselectingelements</p>

</div>

<divid="footerDiv">

<footer>Copyright-JavaScriptfor.NetDevelopers</footer>

</div>

</body>

</html>

Theoutputwillbeasfollows:

Page 125: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Therearevariousothermethodsavailable,whichyoucanrefertointhejQuerydocumentation.Therefore,withselectors,wecansearchanyelementinafasterandmoreefficientway.

Anotherexampleisselectingmultipleelementsusingthetagname,asfollows.

<html>

<head>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('div,h1,p,footer').each(function(){

console.log($(this).html());

});

});

</script>

</head>

<body>

<divid="headerDiv">

<h1>Demo</h1>

</div>

<divid="mainDiv">

<p>ThisisademoofusingjQueryforselectingelements</p>

</div>

<divid="footerDiv">

<footer>Copyright-JavaScriptfor.NetDevelopers</footer>

</div>

</body>

</html>

Theresultwillbeasfollows.Eachitem'sinnerhtmlcodewillbeloggedintheconsole:

Page 126: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Selectingnodesbytheclassname

TheclassnameselectorisquitesimilartotheIDselector;theonlydifferenceisthatitusesaperiodcharacter,.,beforetheclassname.ItfacilitatestraversingalltheDOMelementsandfindingtheelementsthathavethesameclassnamespecifiedintheselector.Itcanbeusedasfollows:

$(.classname);

Let'shavealookatthefollowingexamplethatshowsyouthewayofselectingelementsbasedontheclassnameselector.Inthefollowingcodesnippet,weusethebootstrapthemeandapplydifferentclassestothebuttons.Withthehelpoftheclassnameselector,wecanselectcontrolsandupdatetheclassname.Thefollowingexamplewillreturntwoelementsbasedontheselectioncriteriaspecified:

<!DOCTYPEhtml>

<html>

<head>

<linkrel="stylesheet"type="text/css"href="Content/bootstrap.css"/>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

varlst=$('.btn-primary');

Page 127: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

alert(lst.length);

});

</script>

</head>

<body>

<divclass="container">

<p></p>

<buttontype="button"class="btnbtn-primaryactive">Edit</button>

<buttontype="button"class="btnbtn-primarydisabled">Save</button>

<buttontype="button"class="btnbtn-danger"

value="Cancel">Cancel</button>

</div>

</body>

</html>

Unlikeaccessingclassnames,wecanrestrictthesearchbyspecifyingthetagnamebeforetheperiodandclassname.Youcanuse$('button.active')tosearchforallthebuttonsthatareactive.

Selectingbytheattributevalue

Incertaincases,youmayhavetoselecttheelementsbasedontheattributeoritsvalue.ThejQuerylibraryprovidesaveryconcisewayofsearchingelementsbasednotonlyontheattribute,butitsvalueaswell.

Thesyntaxofusingthisselectorisspecifyingtheelementnamefollowedbyasquarebracketcontainingtheattributenameandvalue,whichisoptional:

$(elementName[attributeName=value])

Forexample,thefollowingcodeselectsalltheelementsthathavetypeasanattribute:

<!DOCTYPEhtml>

<html>

<head>

<linkrel="stylesheet"type="text/css"href="Content/bootstrap.css"/>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

varlst=$('input[type]');

console.log(lst.length);

});

</script>

</head>

<body>

<divclass="container">

<p></p>

<inputtype="text"value="helloworld"/>

<inputtype="text"value="thisisademo"/>

<inputtype="button"value="Save"/>

</div>

</body>

Page 128: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

</html>

Inthisexample,wehavethreeinputcontrolsthathaveatypeattribute.So,theresultwillbe3.Inthesameway,ifyouwanttosearchfortheelementsthathaveavalueequaltohelloworld,wecanusethefollowingcode:

<script>

$(document).ready(function(){

varlst=$('input[value="helloworld"]');

alert(lst.length);

});

</script>

Onethingtonoteisthattheattributevalueiscasesensitive,andso,withthisexpression,youshouldconsidertheexactcaseastheattributevalue.However,thereareotherwaysaswell,thatis,using^tosearchavaluethatcontains,starts,orendswithparticulartext.

Let'shavealookatthefollowingexample,alert,whichisbasedonsearchingavaluethatstartswithanexpression:

<!DOCTYPEhtml>

<html>

<head>

<linkrel="stylesheet"type="text/css"href="Content/bootstrap.css"/>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

varlst=$('input[value^="Pr"]');

alert(lst.length);

});

</script>

</head>

<body>

<divclass="container">

<p></p>

<inputtype="text"value="Product1"/>

<inputtype="text"value="Thisisadescription"/>

<inputtype="button"value="Process"/>

</div>

</body>

</html>

Ontheotherhand,wecanalsosearchavaluethatendswithatextusingthe$symbol.Hereisthecodetosearchthetextthatendswith1:

<script>

$(document).ready(function(){

varlst=$('input[value$="1"]');

alert(lst.length);

});

</script>

Page 129: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Finally,searchingforatextthatcontainssometextcanbeachievedusing*andhereisthecodetorunthisexample:

<script>

$(document).ready(function(){

varlst=$('input[value*="ro"]');

alert(lst.length);

});

</script>

Selectinginputelements

InputcontrolsinHTMLhaveawiderangeofdifferentcontrols.Controlssuchastextarea,button,input,select,image,andradioareinputcontrols.Thesecontrolsarenormallyusedinform-basedapplications.Therefore,jQueryspecificallyprovidestheselectingoptiontoselectinputcontrolsbasedondifferentcriteria.

Thisselectorstartswithadollarandtheinputkeywordfollowedbytheattributeandvalue:

$(':input[attributeName=value]);

However,intheprevioussection,wehavealreadyseenhowtosearchanyelementwiththeattributenameandvalue.So,ifwewanttosearchalltheinputcontrolswiththetypethatequalstotext,itisachievable.

Thisselectorislessperformance-efficientinparticularscenariosandsearchesoutallthecontrolsthatareapartoftheinputgroupandfindstheattributewithitsvalue;whereas,thisselectorwillonlysearchintheinputcontrols.Whenwritingprograms,usingthismethodisabetterchoiceifsomethingisspecificallytargetingtheinputcontrolproperties.

Let'shavealookatthefollowingexampleinASP.NETCoreMVC6thatappliestheCSSpropertiesoncethedocumentisloadedcompletely:

@modelWebApplication.ViewModels.Book.BookViewModel

@{

ViewData["Title"]="View";

}

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$(':input').each(function(){

$(this).css({'color':'darkred','background-color':'ivory','font-

weight':'bold'});});

});

</script>

<formasp-action="View"class="container">

<br/>

<divclass="form-horizontal">

<divclass="form-group">

<labelasp-for="Name"class="col-md-2control-label"></label>

<divclass="col-md-10">

Page 130: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<inputasp-for="Name"class="form-control"/>

<spanasp-validation-for="Name"class="text-danger"/>

</div>

</div>

<divasp-validation-summary="ValidationSummary.ModelOnly"class="text-

danger"></div>

<divclass="form-group">

<labelasp-for="Description"class="col-md-2control-label"></label>

<divclass="col-md-10">

<textareaasp-for="Description"class="form-control"></textarea>

<spanasp-validation-for="Description"class="text-danger"/>

</div>

</div>

<divclass="form-group">

<divclass="col-md-offset-2col-md-10">

<inputtype="submit"value="Save"class="btnbtn-primary"/>

</div>

</div>

</div>

</form>

<div>

<aasp-action="Index">BacktoList</a>

</div>

Theoutputoftheprecedingcodesnippetisasfollows:

Selectingalltheelements

ThejQuerylibraryprovidesyouwithaspecialselectorthatbringsthecollectionofalltheelementsdefinedinaDOM.Insteadofthestandardcontrols,italsoreturnstheelements,suchas<html>,<head>,<body>,<link>,and<script>.

Thesyntaxofgettingalltheelementsis$("*")andthefollowingexamplelistsdownalltheelementsoftheDOMonthebrowser'sconsole:

<!DOCTYPEhtml>

<html>

<head>

<linkrel="stylesheet"type="text/css"href="Content/bootstrap.css"/>

Page 131: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$("*").each(function(){

console.log($(this).prop('nodeName'));

});

});

</script>

</head>

<body>

<formclass="container">

<divclass="form-group">

<label>Name</label>

<inputtype="text"class="form-control"/>

</div>

</form>

</body>

</html>

Intheprecedingcode,weusedthepropmethodthattakesthepropertynametodisplayelementnames.Here,inthepropmethod,wecanuseeithertagNameornodeNametodisplaynametypes.Finally,onthebrowser'sconsole,aloginpagewillbedisplayed,asfollows:

Page 132: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Selectingthefirstandlastchildelements

ThejQuerylibraryprovidesspecialselectorstoselectallthefirstelementsorlastelementsoftheirparentelement.

Thesyntaxofselectingthefirstchildofalltheparentelementsisasfollows:

$(elementName:first-child);

Thesyntaxofselectingthelastchildofalltheparentelementsisasfollows:

$(elementName:last-child);

Thefollowingexampleshowsyouthewayofchangingthefontstyleofthefirstandlastchildoftheselectoptions:

<!DOCTYPEhtml>

<html>

<head>

<linkrel="stylesheet"type="text/css"href="Content/bootstrap.css"/>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('option:first-child').css('font-style','italic');

$('option:last-child').css('font-style','italic');

alert(lst.length);

});

</script>

</head>

<body>

<select>

<option>--select--</option>

<option>USA</option>

<option>UK</option>

<option>Canada</option>

<option>N/A</option>

</select>

</body>

</html>

Theoutputwillbeasfollows:

Page 133: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ThecontainsselectorinjQuery

ThecontainsselectorisusedtofindthetextintheHTMLcontainerelements,suchas<div>and<p>.Thisselectorsearchesalltheelementsofaspecifictypeandfindsthetextpassedasaparametertothecontains()function.Anexamplethatdisplaysthetextofthedivelementsthatcontainsthetextisshowninthefollowingcode.Thisiscase-sensitive,somakesuretosupplythecorrectcasewhensearching.

Thefollowingcodewilldisplayanalertwiththevalue,2,asitfindstwodivelementscontainingthetext,demo:

<!DOCTYPEhtml>

<html>

<head>

<linkrel="stylesheet"type="text/css"href="Content/bootstrap.css"/>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

varlst=$('div:contains("demo")');

alert(lst.length);

});

</script>

</head>

<body>

<div>

Thisisasampledemoforcontainsselector

</div>

<div>

Demooftheselector

</div>

<div>

Sampledemo

</div>

</body>

</html>

Selectingtheevenandoddrowsselectors

Thesetypesofselectorsworkontherowsinatableandareusuallyusedtoprovidespecialformattingtotheoddorevenrowsbychangingthecolorofeachoddrowtomakeitlookmorelikeagrid.Wecanusethistypeofselectorwiththefollowingsyntax:

$('tr:even');

$('tr:odd');

Let'shavealookatthefollowingexampletochangealltherowcolorsinatabletogray:

<!DOCTYPEhtml>

<html>

<head>

<linkrel="stylesheet"type="text/css"href="Content/bootstrap.css"/>

Page 134: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('tr:odd').css('background-color','grey');

});

</script>

</head>

<body>

<table>

<thead>

<tr><th>ProductName</th><th>Description</th><th>Price</th></tr>

</thead>

<tbody>

<tr><td>Product1</td><td>ThisisProduct1</td><td>$100</td></tr>

<tr><td>Product2</td><td>ThisisProduct2</td><td>$500</td></tr>

<tr><td>Product3</td><td>ThisisProduct3</td><td>$330</td></tr>

<tr><td>Product4</td><td>ThisisProduct4</td><td>$50</td></tr>

<tr><td>Product5</td><td>ThisisProduct5</td><td>$1000</td></tr>

<tr><td>Product6</td><td>ThisisProduct6</td><td>$110</td></tr>

<tr><td>Product7</td><td>ThisisProduct7</td><td>$130</td></tr>

<tr><td>Product8</td><td>ThisisProduct8</td><td>$160</td></tr>

<tr><td>Product9</td><td>ThisisProduct9</td><td>$20</td></tr>

<tr><td>Product10</td><td>ThisisProduct10</td><td>$200</td></tr>

</tbody>

</table>

</body>

</html>

Page 135: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ManipulatingDOMInthissection,wewillseesomeexamplesofmanipulatingDOMthroughthejQuerymethods.ThejQuerylibraryprovidesanextensivelibraryofperformingdifferentoperationsontheDOMelements.Wecaneasilymodifytheelementattributes,applystyles,anditeratethroughdifferentnodesandproperties.Wehavealreadyseensomeexamplesintheprevioussection,andthissectionwillfocusontheDOMmanipulationspecifically.

Modifyinganelement'sproperties

Whenworkingwithaclient-sidescriptinglanguage,modifyinganelement'sattributesandreadingthemisavitaltask.InplainJavaScript,thiscanbeachievablebywritingafewlinesofcode;however,withjQuery,itcanbeachievedinaquickerandnicerway.

Modifyinganypropertiesofanelement,whichistobeselected,canbedonewiththevariousoptionslistedintheprevioussection.Eachpropertylistedinthefollowingtableprovidesboththegetandsetoptionsandtakesparameter(s)whensettingsomethingandnoparameterswhenreadingit.

Therearesomecommonmethodsavailabletomodifyanelement,namelyhtml,value,andsoon,injQuery.Formoremethods,youcanrefertohttp://api.jquery.com/category/manipulation/.

Thegetmethod Thesetmethod Description

.val() .val('anyvalue')ThismethodisusedtoreadorwriteanyvalueoftheDOMelement.

.html().html('anyhtml

string')

ThismethodisusedtoreadorwriteanyHTMLcontentoftheDOMelement.

.text() .text('anytext')Thismethodisusedtoreadorwritethetextcontent.HTMLwillnotbereturnedinthismethod.

.width() .width('anyvalue')Thismethodisusedtoupdatethewidthofanyelement.

.height() .height('anyvalue')Thismethodisusedtoreadormodifytheheightofanyelement.

Page 136: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

.attr() .attr('attributename',

'value')Thismethodisusedtoreadormodifythevalueofaspecificelement'sattribute.

.prop() .prop()

Thismethodisthesameasattr()butmoreefficientwhendealingwiththevaluepropertythatreturnsthecurrentstate.Forexample,theattr()checkboxprovidesthedefaultvaluewhereasprop()givesthecurrentstate,thatis,trueorfalse.

.css('style-

property')

.css({'style-

property1':value1,

'style-property2':

value2,'style-

propertyn':valueN}

Thismethodisusedtosetanypropertyofstyle,suchasthefontsize,fontfamily,andwidthforaparticularelement.

Let'shavealookatthefollowingexample,whichusesthehtml(),text(),andcss()modifiersandupdatesthepelementwithhtml,text,andincreaseFontSize:

<!DOCTYPEhtml>

<html>

<head>

<linkrel="stylesheet"type="text/css"href="Content/bootstrap.css"/>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

functionupdateHtml(){

$('p').html($('#txtHtml').val());

}

functionupdateText(){

$('p').text($('#txtText').val());

}

functionincreaseFontSize(){

varfontSize=parseInt($('p').css('font-size'));

varfontSize=fontSize+1+"px";

$('p').css({'font-size':fontSize});

}

</script>

</head>

<body>

<formclass="form-control">

<divclass="form-group">

<p>thisisabookforJavaScriptfor.NetDevelopers</p>

</div>

<divclass="form-group">

EnterHTML:<inputtype="text"id="txtHtml"/>

<buttononclick="updateHtml()">UpdateHtml</button>

</div>

<divclass="form-group">

Page 137: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UpdateText:<inputtype="text"id="txtText"/>

<buttononclick="updateText()">UpdateText</button>

</div>

<divclass="form-group">

<buttononclick="increaseFontSize()">IncreaseFontSize</button>

</div>

</form>

</body>

</html>

TheoutcomeoftheprecedingHTMLcodeisasfollows:

YoucanupdateHTMLbyclickingontheUpdateHtmlbuttonandplaintextbyclickingontheUpdateTextbutton:

Finally,thefontsizecanbeincreasedbyclickingontheIncreaseFontSizebutton:

Page 138: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Creatingnewelements

ThejQuerylibraryprovidesasmartwayofcreatingnewelements.Elementscanbecreatedusingthesame$()methodandpassinghtmlasaparameter.Oncetheelementiscreated,itcannotbeshownuntilitisaddedtotheDOM.Therearevariousmethodsavailablethathelpappend,insertafter,orinsertbeforeanyelement,andsoon.ThefollowingtableshowsthelistofallthemethodsusedtoaddnewelementstotheDOM:

Thegetmethod Description

.append()ThismethodisusedtoinserttheHTMLcontentintotheelementfromwhichithasbeencalled

.appendTo()Thismethodisusedtoinserteveryelementattheendfromwhichithasbeencalled

.before()ThismethodisusedtoinserttheHTMLcontentbeforetheelementfromwhichithasbeencalled

.after()ThismethodisusedtoinserttheHTMLcontentaftertheelementfromwhichithasbeencalled

.insertAfter()ThismethodisusedtoinserttheHTMLcontentaftereveryelementfromwhichithasbeencalled

.insertBefore()ThismethodisusedtoinserttheHTMLcontentbeforeeveryelementfromwhichithascalled

Page 139: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

.prepend()ThismethodisusedtoinserttheHTMLcontentintotheelementatthestartingpositionfromwhichithasbeencalled

.prepend()ThismethodisusedtoinserttheHTMLcontentfromthestartingpositionforeachelementfromwhichithasbeencalled

Thefollowingexamplecreatesaformwithtwofields,NameandDescription,andabuttontosavethesevalues:

<!DOCTYPEhtml>

<html>

<head>

<linkrel="stylesheet"type="text/css"href="Content/bootstrap.css"/>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

varformControl=$("<formid='frm'class='container'></form>");

$('body').append(formControl);

varnameDiv=$("<divclass='form-group'><labelid='lblName'>EnterName:

</label><inputtype='text'id='txtName'class='form-control'/></div>");

vardescDiv=$("<divclass='form-group'><labelid='lblDesc'>Enter

Description:</label><textareaclass='form-control'type='text'

id='txtDescription'/></div>");

varbtnSave=$("<buttonclass='btnbtn-primary'>Save</button>")

formControl.append(nameDiv);

formControl.append(descDiv);

formControl.append(btnSave);

});

</script>

</head>

<body>

</body>

</html>

Thiscodewillgivethefollowingoutput:

Page 140: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Removingelementsandattributes

WiththeoptionofusingdifferentmethodstocreateandrenderelementsintheDOM,jQueryalsoprovidesafewmethodstoremoveelementsfromtheDOM.Thefollowingtableisalistofmethodsthatwecanusetoremoveaparticularelement,setofelements,orallchildnodes:

Methods Description

.empty() ThismethodremovestheinnerHTMLcodefromtheelement

.detach() ThismethodremovesthesetofmatchedelementsfromtheDOM

.remove() ThismethodremovesthesetofmatchedelementsfromtheDOM

.removeAttr() Thismethodremovesaparticularattributefromtheelement

.removeClass() Thismethodremovesaclassfromanelement

.removeProp() Thismethodremovesapropertyfromanelement

Thedifferencebetweenremove()anddetach()isthatremoveremovesthecontentfromtheDOMpermanently;thismeansthatiftheelementhasspecificeventsordataassociated,theseeventsordatawillalsoberemoved.However,detachjustseparatesandisolatestheelementfromtheDOMandreturnsthecontentthatyoucansaveinsomevariableforlaterattachment:

Page 141: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

@modelWebApplication.ViewModels.Book.BookViewModel

@{

ViewData["Title"]="View";

}

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

varmainDivContent=undefined

$(document).ready(function(){

$('button').click(function(){

if(mainDivContent){

mainDivContent.appendTo('#pageDiv');

mainDivContent=null;

}else{

mainDivContent=$('#mainDiv').detach();

}

});

});

</script>

<divid="pageDiv"class="container">

<br/>

<divid="mainDiv"class="form-horizontal">

<divclass="form-group">

<labelasp-for="Name"class="col-md-2control-label"></label>

<divclass="col-md-10">

<inputasp-for="Name"class="form-control"/>

</div>

</div>

</div>

<divclass="form-group">

<divclass="col-md-offset-2col-md-10">

<buttonclass="btnbtn-primary">Detach/Attach</button>

</div>

</div>

</div>

Ondetaching,theoutputwillbeasfollows:

Onattaching,theoutputwillbesimilartothefollowingscreenshot:

Page 142: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer
Page 143: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

EventhandlinginjQueryThejQueryeventmodelprovidesabetterwayofhandlingeventsontheDOMelements.Programmatically,ifdeveloperswanttoregisteranyeventoftheuser'saction;forexample,abuttonclickeventcanbeacumbersomeprocesswhenworkingwithplainJavaScript.Thisisbecausedifferentbrowsershavedifferentimplementationsandthesyntaxissomehowdifferentfromoneanother.ThejQuerylibrary,ontheotherhand,providesacleanersyntaxanddevelopersdon'thavetoworkonthecrossbrowserissues.

RegisteringeventsinjQuery

TherearemanyshortcutsavailableinjQuerytoregistereventstodifferentelements.Thefollowingtableshowsyoualistofalltheseeventswithspecificdescriptions:

Events Description

click() Thiseventisusedwhenthemouseclickoccurs

.dblclick() Thiseventisusedwhenthedouble-clickoccurs

.mousedown() Thiseventisusedwhenanyofthemousebuttonsarepressed

.mouseup() Thiseventisusedwhenanyofthemousebuttonsarereleased

.mouseenter() Thiseventisusedwhenthemouseentersthesection

.mouseleave() Thiseventisusedwhenthemouseleavesthesection

.keydown() Thiseventisusedwhenakeyboardkeyispressed

.keyup() Thiseventisusedwhenthekeyboardkeyisreleased

.focus() Thiseventisusedwhentheelementisfocused

.blur() Thiseventisusedwhentheelementlosesfocus

.change() Thiseventisusedwhentheitemischanged

Page 144: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Therearevariousotherevents,whichyoucancheckoutathttp://api.jquery.com/category/events.

RegisteringaneventisquitesimpleusingjQuery.Firstofall,theelementhastobeselectedbychoosinganyoftheselectorsandthenregisteringtheeventsbycallingaspecificeventhandler;forexample,thefollowingcodesnippetwillregistertheclickeventforthebutton:

$(document).ready(function({

$('#button1').click(function(){

console.log("buttonhasbeenclicked");

});

)};

Aftertheprecedingexamplecode,registertheasp.netbuttonclickeventandcalltheContactactionofthecontrollerofHomeinASP.NET:

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

varmainDivContent=undefined

$(document).ready(function(){

$('#btnSubmit').click(function(){

window.location.href='@Url.Action("Contact","Home")';

});

});

</script>

<divid="pageDiv"class="container">

<br/>

<divclass="form-group">

<divclass="col-md-offset-2col-md-10">

<buttonid="btnSubmit"class="btnbtn-primary">Submit</button>

</div>

</div>

</div>

Intheprecedingexample,weusedtheHTMLhelper,Url.Action,throughtheRazorsyntax,whichgeneratedtheURLandsetittothehrefpropertyofthewindow'scurrentlocation.Now,clickonthebuttonshowninthefollowingscreenshot:

Thefollowingcontactpagewillbedisplayed:

Page 145: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Anotherexampleshownherewillchangethebackgroundcolorofallinputcontrolstoalicebluewhenthecontrolisfocusedandchangebacktowhitewhenitblurs:

@modelWebApplication.ViewModels.Book.BookViewModel

@{

ViewData["Title"]="View";

}

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

varmainDivContent=undefined

$(document).ready(function(){

$('#btnSubmit').click(function(){

window.location.href='@Url.Action("Contact","Home")';

});

$('input').each(function(){

$(this).focus(function(){

$(this).css('background-color','aliceblue');

})

$(this).blur(function(){

$(this).css('background-color','white');

});

});

});

</script>

<divid="pageDiv"class="container">

<br/>

<divid="mainDiv"class="form-horizontal">

<divclass="form-group">

<labelasp-for="Name"class="col-md-2control-label"></label>

<divclass="col-md-10">

<inputasp-for="Name"class="form-control"/>

</div>

</div>

<divclass="form-group">

<labelasp-for="Description"class="col-md-2control-label"></label>

<divclass="col-md-10">

<inputasp-for="Description"class="form-control"/>

Page 146: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

</div>

</div>

</div>

<divclass="form-group">

<divclass="col-md-offset-2col-md-10">

<buttonid="btnSubmit"class="btnbtn-primary">Submit</button>

</div>

</div>

</div>

Bindingeventsusingonandoff

Apartfromregisteringeventsdirectlybycallingtheeventhandler,wecanalsoregisterthemusingonandoff.Theseeventsregisterandderegistertheeventforspecificelements.

Hereisasimpleexampleofbindingaclickeventtoabuttonusingon:

$(document).ready(function(){

$('#btnSubmit').on('click',function(){

window.location.href='@Url.Action("Contact","Home")';

});

});

Thisisaveryusefultechniqueandcanbeusedincertainconditionswhereyouwanttoderegisteranyevent.Forexample,businessapplicationsaremostlyrelatedtoformhandling,andformscanbesubmittedusingsomebuttonthatpoststherequesttosomeserver.Incertainconditions,wehavetorestricttheusertosubmitmultipletimesuntilthefirstrequesthasbeenprocessed.Tohandlethisproblem,wecanusetheon()andoff()eventstoregisterandderegisterthemwhentheuserclicksthefirsttime.Hereisanexamplethatderegistersthebutton-clickeventwhenitisclickedforthefirsttime:

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('#btnSubmit').on('click',function(){

$('#btnSubmit').off('click');

});

});

</script>

ThepreventDefault()eventisjustthecanceleventthatweusedtohavein.NET.Thiseventisusedtocanceltheeventfromexecution.Itcanbeusedasfollows:

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('#btnSubmit').on('click',function(event){

event.preventDefault();

});

});

</script>

Page 147: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Theon()methodisequivalenttothedelegate()methodusedwiththepreviousversionofjQuery.SincejQuery1.7,delegate()hasbeenreplacedwithon().

Thereisonemoreoverloadedmethod,on,whichtakesfourparameters:

$(element).on(events,selector,data,handler);

Here,elementisthecontrolname,eventsistheeventthatyouwanttoregister,andselectorisanewthing,whichcanbethechildelementoftheparentcontrol.Forexample,foratableelementselector,itcouldbetd;andoneachclickeventoftd,wecandosomethingasfollows:

@modelIEnumerable<WebApplication.ViewModels.Book.BookViewModel>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('table').on('click','tr',null,function(){

$(this).css('background-color','aliceblue');

});

});

</script>

<p>

<aasp-action="Create">CreateNew</a>

</p>

<tableclass="table">

<tr>

<th>

@Html.DisplayNameFor(model=>model.Description)

</th>

<th>

@Html.DisplayNameFor(model=>model.Name)

</th>

<th></th>

</tr>

@foreach(variteminModel){

<tr>

<td>

@Html.DisplayFor(modelItem=>item.Description)

</td>

<td>

@Html.DisplayFor(modelItem=>item.Name)

</td>

<td>

<aasp-action="Edit"asp-route-id="@item.Id">Edit</a>|

<aasp-action="Details"asp-route-id="@item.Id">Details</a>|

<aasp-action="Delete"asp-route-id="@item.Id">Delete</a>

</td>

</tr>

}

</table>

Page 148: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Theprecedingcodesnippetoutputwouldbesimilartothefollowingscreenshot.Whentheuserclicksonanyrow,thebackgroundcolorwillbechangedtoAliceblue:

Usingthehoverevents

Wecanusethehovereventswhenthemouseentersorexitsaparticularelement.Itcanbeusedbycallingthehover()methodonanyelementoftheDOM.Thesyntaxofcallingthismethodisasfollows:

$(selector).hover(mouseEnterHandler,mouseExitHandler);

Thefollowingexamplechangestheinputtextcontrol'sbordercolorwhenthemouseentersorexits:

@{

ViewData["Title"]="View";

}

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<02>

$(document).ready(function(){

$("input[type='text']").hover(function(){

$(this).css('border-color','red');

},

function(){

$(this).css('border-color','black');

}

});

</script>

<divid="pageDiv"class="container">

<br/>

<divid="mainDiv"class="form-horizontal">

<divclass="form-group">

<labelasp-for="Name"class="col-md-2control-label"></label>

<divclass="col-md-10">

<inputasp-for="Name"class="form-control"/>

</div>

</div>

<divclass="form-group">

Page 149: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<labelasp-for="Description"class="col-md-2control-label"></label>

<divclass="col-md-10">

<inputasp-for="Description"class="form-control"/>

</div>

</div>

</div>

<divclass="form-group">

<divclass="col-md-offset-2col-md-10">

<buttonid="btnSubmit"class="btnbtn-primary">Submit</button>

</div>

</div>

</div>

Thefollowingscreenshotwillbetheoutputoftheprecedingcodesnippet.Thiswillchangethebordercoloroftheinputtextcontroltoredwhenthemouseentersandblackwhenitexits:

Page 150: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryInthischapter,youlearnedaboutjQuerybasicsandhowtousetheminwebapplications,especiallyinASP.NETcore1.0.Thisisaverypowerfullibrary.Iteliminatescross-browserissuesandprovidesconsistentbehavioracrossallbrowsers.Thislibraryprovidessimpleandeasymethodstoselectelements,modifyattributes,attachevents,andperformcomplexoperationsbywritingcodeinacleanerandmoreprecisemanner.Inthenextchapter,wewilllookintothevarioustechniquesofdoingAjaxrequestsusingjQueryandplainJavaScripttoperformserver-sideoperations.

Page 151: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter4.AjaxTechniquesOneofthecorecharacteristicsofmakingresponsivewebapplicationsisAjax.Traditionally,inserver-sidepostbacks,wheneverauserperformsanyaction,theinformationsuppliedintheformissentbacktotheserverandthesamepageloadsagain,containingalltheimages,CSS,andJavaScriptfilesloadedagainontheclientside.Thisapproachisquiteheavyintermsofthesizeoftherequestandresponsebeingsentfromtheclientandserver.Thus,theapplicationbecomeslessresponsiveandtheuserhastowaitforthepagetorefresheverytimeanyactionistaken.Inthischapter,wewilldiscusshowtosimplifythewholeprocessandavoidheavyserver-sidepostbacksthroughAjax.

Page 152: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

IntroducingAjaxAjaxstandsforAsynchronousJavaScriptandXML;itcreatesasynchronousrequestsonserverwithoutsendingandrenderingthewholepageagainonclientside,whereasitonlysendsabitofinformationthatneedstobesentouttotheserverandreceivesresponseinaspecificformattoupdateaspecificsectionortheelementsofDOMthroughJavaScript.Thisallowsdeveloperstodevelopresponsivewebapplicationsanddynamicallyupdatethecontentofthepagewithoutreloadingiteverytimeforaparticularaction.Forexample,inamaster-childpagerelationship,thechildcontentisdependentontheparentitemselection;andwithaclassicapproach,everytimetheparentitemisselected,thepageisbeingpostedbacktotheserverside,wheretheserverdoessomebackendjobtofillthechildsectionandreturnstheHTMLcode,whichisthenrenderedontheclientside.ThroughAjax,thiscanbeachievedbymakinganasynchronousrequesttosendtheselectedinformationandupdatetheselectedpartsofthepagecontent.

Page 153: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

HowAjaxworksAjaxusestheXMLHttpRequest(XHR)objecttoinvoketheserver-sidemethodsasynchronously.XHRisdevelopedbyMicrosoft,anditwasinitiallyprovidedwithInternetExplorer5.ItwasusedinitiallybycallinganActionXObjectinstancetocreateaninstance;however,withmodernversions,everybrowsersupportsinitializingtheXHRobjectthroughtheXMLHttpRequestobject.

ThefollowingdiagramshowsthearchitecturalviewofhowAjaxworks:

Traditionally,whenanyactionistakenfromtheclientside,theentiredataissentbacktotheserverandisloadedagainontheclientsideoncetheresponseisreceived.Insteadofupdatingthedata,whichneedstobeupdated,includingallthestaticfilessuchasCSS,JavaScript,andimages,itisloadedfromtheserveragainandrenderedontheclientside,unlesssomecachingmechanismisimplemented.WithAjax,wesendthedatainaJSONstringorXMLandgettheresponseinaJSON,XML,HTML,oranyotherformat,dependingontheserver.Wecanalsouserequestheader,suchasAccept,whensendingtherequest,sotheserverknowswhattheclientisaccepting;andbasedontheformatter,itcanserializethedataintoaparticularformat.InASP.NETMVC6,therearetwoformattersimplementedbydefaultfor

Page 154: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

JSONandXML,whichsendthedata,basedontherequestAcceptheaderandserializetheobjectaccordingly.Customformatterscanalsobeimplementedonaserverleveltohandlespecificscenarios.

AjaxrequestsusingtheclassicXHRobject

Allbrowsers,includingInternetExplorer,Chrome,Firefox,andSafari,providethisobjectthatcanbeusedfromJavaScripttoexecutetheAjaxrequests.

InJavaScript,wecaninitializetheXMLHttpRequestobjectasfollows:

varxhr=newXMLHttpRequest();

EveryrequestcouldbeaGETorPOSTrequest.Oncetheresponseisreceivedfromserver,afewpropertiesgetpopulatedandeventhandlersareinvoked,whichcanbeconfiguredfortheXHRobjectwhenmakingtheAjaxrequest.

Let'slookintothedetailsofwhatmethods,properties,andeventstheXHRobjectprovides.

XHRmethods

TheXHRobjectprovidesvariousmethodsasfollows,butthetwomostimportantmethodstoinitiateanAjaxifiedrequestareopen()andsend():

Sendingrequest:

RequestcaneitherbeGETorPOST.Whenmakinganyrequest,willwefirsthavetoinvoketheopenmethodandspecifytheHTTPmethod,suchasGETorPOST,andtheURLoftheserver.Restoftheparameters,suchasasyncbit,user,andpassword,areoptional.

Thesignatureoftheopenmethodisasfollows:

voidOpen(

DOMStringmethod,

DOMStringURL,

optionalbooleanasync,

optionalDOMStringuser?,

optionalDOMStringpassword

);

Thesendmethodisusedtosendtherequesttotheserver.Thisistheactualmethod,whichsendstherequesttotheserveranditacceptsthedatainvariousformats.

Thefollowingtableshowstheoverloadedmethodsavailableforthesendmethod:

Methods Description

Page 155: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

voidsend() ThismethodisusedwhenmakingtheGETrequests

voidsend(DOMString?

Data)Thismethodisusedwhenpassingthedatainstring

voidsend(Documentdata) Thismethodisusedwhenpassingthedocumentdata

voidsend(Blobdata)Thismethodisusedtopasstheblobdataordatainbinary

voidsend(FormDatadata) Thismethodisusedtopassthewholeform

Abortingrequest:

Therearecertaincasesinwhichdevelopersmightneedtoabortthecurrentrequest.Thiscanbedonebycallingtheabort()functionoftheXHRobject:

varxhr=newXMLHttpRequest();

xhr.abort();

Settingrequestheaders:

XHRprovidesseveraltechniquesofmakinganAjaxrequest.ThismeansthattherearecaseswhenweneedtosenddataintheJSON,XML,orsomecustomformat,basedontheserverimplementation.Forexample,whenworkingwithASP.NETMVC6,therearetwodefaultformattersimplemented,JSONandXML,andifyouwanttoimplementyourowncustomformatter,thisisalsopossible.Whensendingdatainaspecificformat,weneedtotelltheformattotheserverthroughrequestheaders.Thishelpstheserverinidentifyingtheformatterthathastobeloadedtoserializetheresponseandprocesstherequest.

ThefollowingtableshowsthedefaultheadersthatcanbesuppliedwiththeAjaxrequest:

Headers Description

Cookie Thisheaderspecifiesanycookiesetintheclientside

Host Thisheaderspecifiesthedomainnameofthepage

Connection Thisheaderspecifiesthetypeofconnection

Page 156: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Accept Thisheaderspecifiesthecontenttypethattheclientcanhandle

Accept-charset Thisheaderspecifiesthecharactersetthattheclientcandisplay

Accept-

encodingThisheaderspecifiestheencodingsthatclientcanhandle

Accept-

language

Thisheaderspecifiesthepreferrednaturallanguagesacceptedasaresponse

User-Agent Thisheaderspecifiesauseragentstring

Referer ThisheaderspecifiestheURLofthepage

ThroughtheXHRobject,wecansettherequestheadersthroughthesetRequestHeader()function,asshowninthefollowingcode:

varxhr=newXMLHttpRequest();

xhr.setRequestHeader('Content-Type','application/json');

Gettingresponseheaders:

Whentheresponseisreturnedbytheserver,wecanreadtheresponseheadersbyusingthefollowingtwomethods:

varxhr=newXMLHttpRequest();

functioncallback(){

vararrHeaders=xhr.getAllResponseHeaders();

//or

varcontentType=xhr.getResponseHeader('Content-Type');

}

ThegetAllResponseHeaders()functionreturnsthelistofalltheresponseheaders,whereasthegetResponseHeader()functionacceptstheheadernameandreturnsthevalueoftheheadernamesupplied.

XHRevents

ThemostusefuleventhandlerintheXHRobject,whichisinvokedwhenthevalueofthereadystatepropertyischanged,istheonreadystatechangeevent.Oninitiatingrequest,wecanassociatethefunctionwiththiseventhandlerandreadtheresponse:

varxhr=newXMLHttpRequest();

xhr.onreadystatechange=callback;

functioncallback(){

Page 157: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

//dosomething

}

Anothercoreeventhandlerisontimeout,whichcanbeusedinconditionstohandletherequesttimed-outscenario.WheninitiatinganXHRrequest,thereisatimeoutpropertythroughwhichthetimeoutcanbesetinmilliseconds,andiftherequestexceedsthetimed-outvalue,theontimeouteventhandlerwillbeinvoked.Theexample,wheretimeoutissetto5,000milliseconds,ifitexceedsthetimeoutproperty,thetimeouthandlerfunctionwillbeinvoked,asshownhere:

varxhr=newXMLHttpRequest();

xhr.timeout=5000;

xhr.ontimeout=timeouthandler;

functiontimeouthandler(){

//dosomething

}

XHRproperties

ThelistofpropertiesavailablefortheXMLHttpRequestobjectisasfollows:

GETrequeststate:

Thispropertyreturnsthestatusinformationabouttheresponse.Itisnormallyusedtotakeactionbasedontherequeststatus:

varxhr=newXMLHttpRequest();

xhr.readystate;

Thelistofstatuseswiththeirmeaningavailableforthereadystatepropertyisgiveninthefollowingtable:

Statusvalue State Description

0 UNSENTInthisstate,theXMLHttpRequestobjectiscreated,buttheopen()methodisnotcalled

1 OPENED Inthisstate,theopenmethodiscalled

2 HEADERS_RECEIVEDThisstateoccursoncesend()iscalledandheadersarereceived

3 LOADING Thisstateoccurswhentheresponseisdownloading

4 DONE

Page 158: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Thisstateoccurswhentheresponseiscomplete

Getresponsedata:

ResponsecanberetrievedbycallingtheresponseorresponseTextproperty.ThedifferencebetweenthesepropertiesisthattheresponseTextpropertyreturnstheresponseasastring,whereastheresponsepropertyreturnstheresponseasaresponseobject.Theresponseobjectcanbeadocument,blob,orJavaScriptobject:

varxhr=newXMLHttpRequest();

xhr.response;

//or

xhr.responseText;

Getresponsestatus:

ResponsestatuscanberetrievedbycallingthestatusorstatusTextproperty.Thedifferencebetweenthesepropertiesisthatthestatuspropertyreturnsthenumericalvalue,forexample,200,iftherequestissuccessfullyprocessedbyserver,whereasthestatusTextpropertyincludesthecompletetext,suchas200OKandsoon:

varxhr=newXMLHttpRequest();

xhr.status;

or

xhr.statusText;

Let'stakealookatthefollowingexamplethatmakestheformPOSTrequestusingtheXHRobjectinASP.NETMVC6.Thefollowingformhastwofields,NameandDescription:

HereisthecodesnippetthatsendstherequesttoserversideusingtheXHRobject.ThisexamplesendsthedatainJSON:

@modelWebApplication.ViewModels.Book.BookViewModel

@{

ViewData["Title"]="View";

}

<script>

Page 159: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

varxhr=null;

functionsubmit(){

xhr=newXMLHttpRequest();

xhr.open("POST",'/Book/SaveData');

varname=document.getElementById("Name").value;

vardescription=document.getElementById("Description").value;

vardata=

{

"Name":name,

"Description":description

};

xhr.setRequestHeader('Content-Type','application/json;charset=utf-8');

xhr.onreadystatechange=callback;

xhr.send(JSON.stringify(data));

}

functioncallback(){

if(xhr.readyState==4){

varmsg=xhr.responseText;r

document.getElementById("msg").innerHTML=msg;

document.getElementById("msgDiv").style.display='block';

}

}

</script>

<formasp-action="SaveData"id="myForm">

<p></p>

<divid="msgDiv"style="display:none"class="alertalert-success">

<ahref="#"class="close"data-dismiss="alert"aria-label="close">&times;</a>

<strong>Success!</strong><labelid="msg"></label>

</div>

<divid="pageDiv"class="container">

<br/>

<divid="mainDiv"class="form-horizontal">

<divclass="form-group">

<labelasp-for="Name"class="col-md-2control-label"></label>

<divclass="col-md-10">

<inputasp-for="Name"class="form-control"/>

</div>

</div>

<divclass="form-group">

<labelasp-for="Description"class="col-md-2control-label"></label>

<divclass="col-md-10">

<textareaasp-for="Description"class="form-control"></textarea>

</div>

</div>

</div>

<divclass="form-group">

<divclass="col-md-offset-2col-md-10">

<buttonid="btnSubmit"onclick="submit()"type="submit"class="btnbtn-

primary">Submit</button>

</div>

</div>

</div>

</form>

Page 160: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

InASP.NETCore,forJSONandXML,wehavetoexplicitlyannotatethecomplextypewiththe[FromBody]attribute.ThisisbecauseMVC6firstsearchesforthevaluesinthequerystringirrespectiveofitstype,whetheracomplextypeoraprimitivetype.FortheJSONandXMLdata,weneedtoexplicitlyannotatethemethod'sparameterwiththe[FromBody]attributesothatthedatacanbeeasilyboundwithoutanyissue:

publicIActionResultSaveData([FromBody]BookViewModelbookViewModel)

{

returnContent("Datasavedsuccessfully");

}

Intheprecedingcodesnippet,wereadtheformvaluesthroughdocument.getElementByIdandthenmadeaJSONstringtopasstheformdatainaJSONformat.

Theoutputwillbeasfollows:

However,thereisalibraryprovidedbyGoogle,whichserializestheformdatabycallingtheserialize()function.Theonlydifferenceissettingtherequestheader'Content-Type'to'application/x-www-form-urlencoded',andaddingthefollowingscriptfile:

<scriptsrc=http://form-serialize.googlecode.com/svn/trunk/serialize-0.2.min.js

/>

Thefollowingcodeistherevisedversionofthesubmitfunction,whichserializestheformdatathroughtheserialize()functionandsendsthedataasform-encodedvalues:

functionsubmit(){

xhr=newXMLHttpRequest();

xhr.open('POST','/Book/SaveData');

xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

varhtml=serialize(document.forms[0]);

Page 161: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

xhr.onreadystatechange=callback;

xhr.send(html);

}

Fortheform-encodedvalues,wewillremovethe[FromBody]attribute.Thisisbecausetheform-encodedvaluesaresentasthenamevaluepairsinthequerystring:

publicIActionResultSaveData(BookViewModelbookViewModel)

{

returnContent("Datasavedsuccessfully");

}

InthepreviousversionsofASP.NETWebAPI,iftheactionmethodofWebAPIcontrollercontainsacomplextype,WebAPIframeworkautomaticallyboundthevaluesfromtherequestbody.WhereaswithASP.NETCore,theWebAPIandMVChavebecomeoneunifiedframework,andthemodelbindingisnotequivalenttowhatwehasinthepreviousversionsofWebAPI.

Intheprecedingexamples,wesawhoweasilywecanmakeaPOSTrequestandsenddatainJSONandform-encodedvalues.Now,let'sseeanotherexampleinwhichwewillloadthepartialviewbasedontheJSONresponsesentfromserver.

ThefollowingscreenshotisoftheASP.NETpagethatcontainsabuttontoloadthelistofbooksinatable:

Hereisthecodesnippetforthemainpage:

@modelWebApplication.ViewModels.Book.BookViewModel

@{

ViewData["Title"]="Books";

}

<script>

varxhr=null;

functionloadData(){

xhr=newXMLHttpRequest();

xhr.open('GET','/Book/Books',true);

xhr.onreadystatechange=callback;

xhr.send();

Page 162: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

functioncallback(){

if(xhr.readyState==4){

varmsg=xhr.responseText;

document.getElementById("booksDiv").innerHTML=msg;

}

}

</script>

<divclass="container">

<buttonid="btnLoad"onclick="loadData()"type="submit"class="btnbtn-

primary">Load</button>

<hr/>

<divid="booksDiv">

</div>

</div>

Thefollowingisthepartialviewthatdisplaysthelistofbooksinatable:

@{

Layout=null;

}

@modelIEnumerable<WebApplication.ViewModels.Book.BookViewModel>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$('table').on('click','tr',null,function(){

$(this).css('background-color','aliceblue');

});

});

</script>

<p>

<aasp-action="Create">CreateNew</a>

</p>

<tableclass="table">

<tr>

<th>

@Html.DisplayNameFor(model=>model.Description)

</th>

<th>

@Html.DisplayNameFor(model=>model.Name)

</th>

<th></th>

</tr>

@foreach(variteminModel){

<tr>

<td>

@Html.DisplayFor(modelItem=>item.Description)

</td>

<td>

@Html.DisplayFor(modelItem=>item.Name)

</td>

<td>

<aasp-action="Edit"asp-route-id="@item.Id">Edit</a>|

Page 163: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<aasp-action="Details"asp-route-id="@item.Id">Details</a>|

<aasp-action="Delete"asp-route-id="@item.Id">Delete</a>

</td>

</tr>

}

</table>

HereisthecodesnippetoftheASP.NETMVCBookscontrollerthatcontainstheBooksactionmethodthatreturnsalistofbooks:

publicclassBookController:Controller

{

//GET:/<controller>/

publicIActionResultIndex()

{

returnView();

}

publicIActionResultBooks()

{

List<BookViewModel>books=newList<BookViewModel>();

books.Add(newBookViewModel{Id=1,Name="JavaScriptfor.Net

Developers",Description="Bookfor.NETDevelopers"});

books.Add(newBookViewModel{Id=1,Name="BeginningASP.NETCore1.0",

Description="BookforbeginnerstolearnASP.NETCore1.0"});

books.Add(newBookViewModel{Id=1,Name="MasteringDesignPatterns",

Description="AllaboutDesignPatterns"});

returnView(books);

}

publicIActionResultCreate()

{

returnView();

}

}

So,withthisinplace,whentheuserclicksontheLoadbutton,therequestwillbemadetotheserverandtheASP.NETMVCcontrollerBooksactionmethodwillbeinvoked,whichreturnsViewthatrendersthepartialviewthatwillberenderedinsidethebooksDivelementonthemainpage:

Page 164: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

MakinganAjaxrequestusingjQuery

Intheprevioussections,wediscussedhowtosendanAjaxrequestusingaplainXMLHttpRequestobject,whichisavailableinallbrowsers.Inthissection,wewillseewhatjQueryoffersinmakingtheAjaxrequestandhowtousetheHTTPGETandPOSTrequeststhroughthejQueryobject.

jQuery.ajax()

ThismethodisusedtomakebothGETandPOSTasynchronousrequests.Thefollowingcodeisthesignatureofthismethod,whichtakestwoparameters:URLandoptions.TheURLparameteristheactualserverURL,whereasoptionstakestheconfigurerequestheadersandotherpropertiesinaJSONrepresentation:

$.([URL],[options]);

$.([options]);

ThefollowingexampleshowshowtomakeanasynchronousrequestontheMVCcontrolleranddisplaysanalertonsuccessfulresponsebeingreturnedfromserver:

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$.ajax('/Book/Books',{

success:function(data){

$('#booksDiv').html(data);

},

Page 165: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

error:function(data){

$('#booksDiv').html(data);

}

});

});

</script>

TheBooksactionmethodreturnstheASP.NETMVCview,whichpassesthelistofbooksthatwillbepopulatedinsidethebooksDivDOMelement:

Ajaxproperties

ThefollowingtableshowssomecorepropertiesthatyoucanspecifytoconfiguretheAjaxrequest:

Name Type Description

accepts PlainObjectThispropertytellstheserveraboutthetypeofresponsethattheclientwillaccept.

async BooleanBydefault,thispropertyistrue(forasynchronousrequest),butitcanbesettofalse(synchronous).

cache BooleanIfthispropertyissettofalse,forcerequestedpageswillnotbecachedbythebrowser.

contents PlainObjectThispropertyisusedtospecifyregularexpressionsforparsingresponse.

Thispropertytellstheserveraboutthetypeofdatapassedinthe

Page 166: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

contentType StringorBoolean

request.Thedefaultvalueisapplication/x-www-form-urlencoded;charset=UTF-8.

crossDomain BooleanThispropertyissettotrueifyouwanttoforcethecross-domainrequest.

data

PlainObject,String,orArray

ThispropertycanbeusedtopassthedatainJSON,XML,oranyotherformat.

dataType StringThispropertyspecifiesthetypeofdataexpectingfromserver.SomecoredatatypesareXML,JSON,script,andHTML.

Pre-filteringAjaxrequests

Thisisagreatfeaturetofiltertheexistingrequestoptionsandconfigurationattributesbeforetheyaresentout.Itprovidestwooverloadedmethods:onethattakesafunctionthatinjectstheoptions,originalOptions,andjqXHRobjects,andtheotherthattakesastringwhereyoucanfilterouttheconfigurationattributesforspecificrequestsfollowedwiththefunctionacceptingparametersasoptions,originalOptions,andjqXHR.Thefollowingcodeisthesignatureofbothoverloadedmethods:

$.ajaxPrefilter(function(options,originalOptions,jqXHR){

//Modifyoptions,originalOptionsandstorejqXHR

}

$.ajaxPrefilter('dataType',function(options,originalOptions,jqXHR){

//Modifyoptions,originalOptionsandstorejqXHR

}

Theobjectsintheprecedingcodeareexplainedasfollows:

options:TheseobjectsarethesameastherequestoptionssuppliedintheAjaxrequest,buttheycanbeoverriddenandfilteredaccordingly.originalOptions:TheseobjectsprovidetheactualoptionsbeingsuppliedintheAjaxrequest.Theycanbeusedtoreferandcannotbemodified.Anychangeintheconfigurationcanbedoneusingtheoptionsobject.jqXHR:ThisobjectisequivalenttotheXMLHttpRequestobjectinjQuery.

Let'stakealookatthefollowingexample,whichappendsthefromAjaxparametertotelltheMVCcontrollerthattherequestisexecutedfromJavaScript:

<script>

$(document).ready(function(){

$.ajaxPrefilter(function(options,originalOptions,jqXHR){

options.url+=((options.url.indexOf('?')<0)?'?':'&')+

Page 167: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

'fromAjax=true';

});

$.ajax('/Book/Books',{

success:function(data){

$('#booksDiv').html(data);

},

error:function(data){

$('#booksDiv').html(data);

}

});

});

</script>

ThefollowingcodeisthecontrolleractionmethodthatreturnsthelistofbooksiftherequestisanAjaxrequest:

publicIActionResultBooks(boolfromAjax)

{

if(fromAjax)

{

List<BookViewModel>books=newList<BookViewModel>();

books.Add(newBookViewModel{Id=1,Name="JavaScriptfor.Net

Developers",Description="Bookfor.NETDevelopers"});

books.Add(newBookViewModel{Id=1,Name="BeginningASP.NETCore1.0",

Description="BookforbeginnerstolearnASP.NETCore1.0"});

books.Add(newBookViewModel{Id=1,Name="MasteringDesignPatterns",

Description="AllaboutDesignPatterns"});

returnView(books);

}

returnContent("RequesttothismethodisonlyallowedfromAjax");

}

Therearevariouspropertiesforoptionsavailable,whichyoucanreferathttp://api.jquery.com.

SettingdefaultvaluesforallfutureAjaxrequests

Withthe$.ajax.setupfunction,wecansettheconfigurationvaluesforallthefuturerequeststobemadethroughthe$.ajax()or$.get()function.Thiscanbeusedtosetthedefaultsettingsbeforecallingthe$.ajax()function,andtheajaxfunctionwillpickthesettingsdefinedinthe$.ajaxSetup()function.

Thefollowingisthesignaturetocall$.ajax.setup:

$.ajaxSetup({name:value,name:value,name:value,…});

ThefollowingexamplesetsthedefaultURLfortheajaxrequestbeingmadethroughthe$.ajaxfunction:

<script>

$(document).ready(function(){

Page 168: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

$.ajaxSetup({url:"/Book/Books"});

$.ajax({

success:function(data){

$('#booksDiv').html(data);

},

error:function(data){

$('#booksDiv').html(data);

}

});

});

</script>

LoadingdatathroughthegetfunctionsinjQuery

ThejQuerylibraryprovidesdifferentfunctionsforretrievingdatafromserver.Thefunction,suchas$.get(),canbeusedtoloadthedatabyusingtheHTTPGETrequest,whereas$.getJSON()isspecificallyusedtoloadtheJSON-encodeddata,and$.getScript()isusedtoloadandexecuteaJavaScriptfromtheserver.

UsingjQuery.get()

The$.get()functionisashorthandfunctionof$.ajax()andonlyallowstheGETrequest.Itabstractsmostoftheconfigurationvaluestodefaultvalues.Similartothe$.ajax()function,itreturnsthedatatothecallbackfunction,butdoesnotprovideanerrorcallback.So,ifanyerroroccurredduringtherequestprocessing,itcannotbetracked.

Ittakesfourparameters,URL,data,callback,andtype.WhereURListheaddresstowhichtherequestissent,datathattakesastringthatissenttotheserverwhentherequestismade,callbackreferstothefunctionwhichisexecutedwhentherequestissucceededandtypedenotesthetypeofdataexpectedfromtheserverlikeXML,JSONandsoon.

Thefollowingisthesignatureofthe$.get()function:

$.get('URL',data,callback,type);

Hereistheexamplethatloadsthebooks,whichcontainanetstringinitstitle:

<script>

$(document).ready(function(){

$.get('/Book/Books',{filter:"net"},function(data){

$('#booksDiv').html(data);

}

);

});

</script>

UsingjQuery.getJSON()

ThejQuery.getJSON()functionisusedtoloadJSONfromtheserver.Itcanbeusedby

Page 169: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

callingthe$.getJSON()function:

$.getJSON('URL',{name:value,name:value,name:value,…});

ThefollowingistheexamplethatloadstheJSONbycallinganactionmethod,whichreturnstheJSONresponseanddisplaysthebooktitleinthebooksDivelement:

<script>

$(document).ready(function(){

$.getJSON('/Book/Books',function(data){

$.each(data,function(index,field){

$('#booksDiv').append(field.Name+"<br/>");

});

}

);

</script>

TheActionmethodreturnstheJSONresponseasfollows:

publicIActionResultBooks()

{

List<BookViewModel>books=newList<BookViewModel>();

books.Add(newBookViewModel{Id=1,Name="JavaScriptfor.NetDevelopers",

Description="Bookfor.NETDevelopers"}

books.Add(newBookViewModel{Id=1,Name="BeginningASP.NETCore1.0",

Description="BookforbeginnerstolearnASP.NETCore1.0"});

books.Add(newBookViewModel{Id=1,Name="MasteringDesignPatterns",

Description="AllaboutDesignPatterns"});

returnJson(books);

}

Onthepage,thebooktitleswillberenderedasshowninthefollowingscreenshot:

UsingjQuery.getScript()

ThejQuery.getScript()functionisashorthandof$.ajax(),anditisspecificallydesignedtoloadthescriptfromtheserver.Thefollowingisthesignatureofthe$.getScript()function:

$.getScript(url,callback);

Thefollowingexampleloadsthecustom.jsfileoncethedocumentisloaded:

<script>

Page 170: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

$(document).ready(function(){

$.getScript("/wwwroot/js/custom.js");

</script>

Postingdatatoserverusingthepostfunction

Similartothe$.get()function,jQueryalsoprovidesa$.post()function,whichisashorthandof$.ajax(),andisspecificallydesignedtoonlymaketheHTTPPOSTrequests.

Hereisthesignatureofthe$.post()function:

$.post(url,data,callback,type);

Thefollowingexamplesubmitstheformdatausingthe$.post()function:

<script>

functionsubmit(){

$.post('/Book/SaveData',$("form").serialize(),function(data){

alert("formsubmitted");

});

}

</script>

ThefollowingisthecodesnippetoftheBookcontroller'sSaveDataactionmethodthattakestheobjectandreturnstheresponseasastring:

publicIActionResultSaveData(BookViewModelbookViewModel)

{

//callsomeservicetosavedata

returnContent("Datasavedsuccessfully")

}

Similarly,wecanpassdatainJSONbyspecifyingthetypeasjson:

<script>

functionsubmit(){

$.post('/Book/SaveData',{Name:"DesignPatterns",Description:"Allabout

designpatterns"},function(data){

},'json');

}

</script>

Ajaxevents

Ajaxeventsarecategorizedintolocalandglobalevents.LocaleventscanbedeclaredwhenmakinganAjaxrequestusingthe$.ajaxfunction.Eventssuchassuccessanderroraretermedaslocalevents,whereasglobaleventsworkwitheveryAjaxrequestexecutedwithinthepage.

Localevents

Page 171: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Thefollowingisthelistoflocalevents,anditisspecificallyrelatedtothe$.ajax()function.Othershorthandfunctions,suchas$.get()and$.post(),donothavethesemethodsavailable,aseachofthemhavespecificvaluestopasstheparametersandconfigurationattributes:

beforeSend:Thiseventistriggeredbeforetheajaxrequestisbeingmade.success:Thiseventoccurswhenthesuccessfulresponseisbeingmadefromtheserver.error:Thiseventoccurswhenanerrorisoccurredduringtheajaxrequest.complete:Thiseventoccurswhentherequestiscompleted.Itdoesnotcheckwhetheranerrorhasoccurredortheresponsewassuccessfulandexecutedwhentherequestiscompleted.

Globalevents

Thefollowingisthelistofglobalevents,anditworkswithallothershorthandfunctionsaswell,suchas$.post(),$.get(),and$.getJSON:

ajaxStart:ThiseventisusedwhenthereisnoajaxrequestinthepipelineandthefirstajaxrequestisstartingupajaxSend:ThiseventisusedwhenanajaxrequestissenttotheserverajaxSuccess:ThiseventisusedwhenanyofthesuccessfulresponsereturnsfromtheserverajaxError:Whenanerroroccursforanyajaxrequest,thiseventisfiredajaxComplete:Thiseventisusedwhenanyoftheajaxrequestiscompleted

ThefollowingcodeisasimpleexampleofASP.NETthatcallstheactionmethod,Books,ofBookController,whichreturnsthelistofbooksandtriggersglobalandlocalevents:

@modelWebApplication.ViewModels.Book.BookViewModel

@{

ViewData["Title"]="Books";

}

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.0.min.js">

</script>

<script>

$(document).ready(function(){

$(document).ajaxComplete(function(e){

alert("Ajaxrequestcompleted");

}).ajaxSend(function(){

alert("Ajaxrequestsending");

}).ajaxSend(function(){

alert("Ajaxrequestsenttoserver");

}).ajaxStop(function(){

alert("Ajaxrequeststopped");

}).ajaxError(function(){

alert("SomeerroroccurredinAjaxrequest");

}).ajaxSuccess(function(){

alert("Ajaxrequestwassuccessful");

})

$('#btnLoad').click(function(){

Page 172: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

$.ajax('/Book/Books',{

success:function(data){

$('#booksDiv').html(data);

},

error:function(data){

$('#booksDiv').html(data);

}

});

});

});

</script>

<divclass="container">

<br/>

<h4>BooksView</h4>

<h5>Clickonthebuttontoloadallthebooks</h5>

<buttonid="btnLoad"type="submit"class="btnbtn-primary">Load</button>

<hr/>

<divid="booksDiv">

</div>

</div>

Page 173: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Cross-originrequestsDuetosecurityreasons,everybrowserrestrictswebapplicationstomakecross-originrequestthroughJavaScript.Cross-originrequestsaretherequeststhatmakeanHTTPrequesttoanotherserver,whichistheoutsidedomain.Forexample,iftheapplication-basedURLislocalhost,andyouaregoingtomakearequestonanotherdomain.com,itwillnotwork.However,therearefewdifferencesbetweenbrowsers'implementation,asinChromeiftheportnumberdiffers,itwon'tallowyoutomakearequest;whereasInternetExplorerignoresthis.

Cross-originrequestisonlyrestrictedtotherequestbeingmadefromtheXMLHttpRequestobject;however,wecanstillhaveresourcessuchasCSS,images,andscriptfilesloadedfromothersourcesordomains.

Thereasonfornotenablingthisistoprotectthedatafrommalicioussiteattacks.However,tohandlethesescenarios,wecaneitheruseJSON-P(anoldertechnique)orCORS,whichwillbediscussedinthefollowingsection.

JSON-P

TheJavaScriptObjectNotationPadding(JSON-P)techniqueisusedwitholderbrowsers.Thistechniqueisobsoletenow,andalternatively,CORSissaferandneater.

UsingJSON-P

JSON-Pisatechniquethatfakesabrowserformakingcross-originrequest.Itworksbyspecifyinga<script>tagthatmakesacross-originrequesttosomeotherserver,andtheresponsereturnedisactuallythefunctionname,whichisalreadydefinedinthewebpage.Itthenpassesthedataasaparametertothefunctionwhenthescriptisexecuted.

Itcanbeimplementedbyaddinga<script>tag,specifyingtherequestURLinthesrcattributeandJavaScriptcallbackfunctioninaquerystringforthesameURL.Forexample,considerthefollowingrequestURL:

http://otherdomain.com?Id=1

AppendthefunctionintherequestURL,whichwillbeinvokedwhenthescriptisloaded:

http://otherdomain.com?Id=1&callback=jsonPCallback

Thefollowingcodesnippetcallsthegeoserviceandspecifiesacallbackparameter,whichpointstothejsonCallbackfunctiondefinedinthescript.ThisscriptwillbeloadedwhenthepageloadsandexecutesthesrcURL,whichfinallycallsthejsonCallbackmethodandpassestheresponse.

ThiscodesnippetisasampleHTTPGETrequestthatusestheBingAPItogetthelocationinformationbasedonthelatitudeandlongitudevaluesprovided:

Page 174: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<script>

varscrpt=document.createElement('script');

scrpt.setAttribute('src','

http://dev.virtualearth.net/REST/v1/Locations/latitudeNo,longitudeNo?

o=json&key=BingMapsKey);

document.body.appendChild(scrpt);

functionjsonCallback(data){

alert("CrossOriginrequestgotmade");

}

</script>

Ontheotherhand,withjQuery,cross-originrequestscanbemadebyspecifyingthedataTypeattributeasjsonpandcrossDomainastrueinthe$.ajaxcall:

$.ajax({

url:serviceURL,

type:"GET",

dataType:"jsonp",

method:"GetResult",

crossDomain:true,

error:function(){

alert("listfailed!");

},

success:function(data){

alert(data);

}

});

CORS

Alternatively,CORSisamorepreferredwaywhenmakingcross-originrequests.ItisaW3Cstandardandallowsaservertosendcross-originrequestsfromanydomain.Thisneedstobeenabledontheserverside.

ASP.NETCoreprovidesaneasywayofenablingCORSontheserverside,andthiscanbedonebyaddingMicrosoft.AspNet.WebApi.CorsthroughNuGet,orbymodifyingproject.jsonandaddingadependencyasfollows:

"Microsoft.AspNet.Cors":"6.0.0-rc1-final"

EnabletheCORSserviceusingtheConfigureServicesmethodintheStartupclass:

publicvoidConfigureServices(IServiceCollectionservices

{

services.AddCors();

}

AddtheCORSmiddlewarebyusingtheUseCors()methodintheConfiguremethod.TheUseCorsmethodprovidestwooverloadedmethods:onethattakestheCORSpolicyandotherthattakesthedelegate,whichcanbeusedasabuildertobuildpolicy.

Note

Page 175: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

NotethatUseCors()shouldbeaddedbeforeUseMVC.

ThroughtheCORSpolicy,wecandefinetheallowedorigins,headers,andmethods.TheCORSpolicycaneitherbedefinedattheConfigureServicesorConfiguremethodwhendefiningmiddleware.

SpecifyingtheCORSpolicyatserviceslevel

ThissectionwillcoverthewayofdefiningthepolicyattheConfigureServicesmethodandreferringwhenaddingmiddleware.TheAddPolicymethodtakestwoparameters:thenameofthepolicyandaCorsPolicyobject.TheCorsPolicyobjectallowschainingmethodsandallowsyoutodefineorigins,methods,andheadersusingtheWithOrigins,WithMethods,andWithHeadersmethods.

Hereisthesamplecodesnippetthatallowsallorigins,methods,andheaders.So,whatevertherequestorigin(domain)andHTTPmethodsorrequestheadersarepassed,therequestwillbeprocessed:

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddCors(options=>{

options.AddPolicy("AllowAllOrigins",builder=>

builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

});

}

Intheprecedingcode,Originsrepresentsthedomainnames,MethodrepresentstheHTTPmethods,andHeaderrepresentstheHTTPrequestheaders.ItcanbesimplyusedintheConfiguremethodasfollows:

publicvoidConfigure(IApplicationBuilderapp,IHostingEnvironmentenv,

ILoggerFactoryloggerFactory

{

app.UseCors("AllowAllOrigin");

}

Wecanalsodefinemultiplepolicies,asfollows:

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddCors(options=>{

options.AddPolicy("AllowAllOrigins",builder=>

builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

options.AddPolicy("AllowOnlyGet",builder=>

builder.WithMethods("GET").AllowAnyHeader().AllowAnyOrigin());

});

EnableCORSattheConfiguremethod

Alternatively,wecandefinetheCORSpolicyontheConfiguremethoditself.TheUseCors

Page 176: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

methodhastwooverloadedmethods:onethattakesthepolicynamethatisalreadydefinedintheConfigureServicesmethod,andtheotherisCorsPolicyBuilderthroughwhichthepolicycandefinedirectlyontheUseCorsmethoditself:

publicvoidConfigure(IApplicationBuilderapp,IHostingEnvironmentenv,

ILoggerFactoryloggerFactory)

{

app.UseCors(policyBuilder=>policyBuilder.WithHeaders("accept,content-

type").AllowAnyOrigin().WithMethods("GET,POST"));

}

DefiningontheConfigureMethodclassenablestheCORSpolicythroughouttheapplication.InsteadofusingtheEnableCorsattribute,wecanspecificallydefinethepolicynamepercontroller,andactionlevelaswell,andusethepolicydefinedintheConfigureServicesmethod.

Definingthroughattributeisanalternative,whichreferstothepolicynamefromtheConfigureServicesmethodandignoresthepolicydefinedatthemiddlewarelevel.HerearethewaysofenablingCORSatcontroller,action,andgloballevel:

EnablingCORSatthecontrollerlevel:

ThefollowingcodeenablestheCORSpolicyattheMVC-controllerlevel:

[EnableCors("AllowAllOrigins")]

publicclassBookController:Controller

{

//todo

}

EnablingCORSattheactionlevel:

ThefollowingcodeenablestheCORSpolicyattheMVCactionmethodlevel:

[EnableCors("AllowAllOrigins")]

publicIActionResultGetAllRecords(

{

//Callsomeservicetogetrecords

returnView();

}

EnablingCORSglobally:

Globally,CORScanbeenabledbydefiningatthemiddlewarelevel,aswehaveseenthroughtheConfiguremethod.Otherwise,ifitisdefinedattheConfigureServiceslevel,enablingitgloballycanbeachievedbyusingtheCorsAuthorizationFilterFactoryobject,asshownhere:

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddCors(options=>{

options.AddPolicy("AllowAllOrigins",builder=>

Page 177: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

options.AddPolicy("AllowOnlyGet",builder=>

builder.WithMethods("GET").AllowAnyHeader().AllowAnyOrigin());

});

services.Configure<MvcOptions>(options=>

{

options.Filters.Add(newCorsAuthorizationFilterFactory("AllowOnlyGet"));

});

}

Theprecedingcodesnippetcontainstwopolicies:AllowAllOriginsandAllowOnlyGet,andthroughCorsAuthorizationFilterFactory,wecanpasstheAllowOnlyGetpolicyasthepolicynameandmakeitglobal.

Page 178: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CallingWCFservicesfromJavaScriptToconsumetheWCFservicemethodsfromJavaScript,weneedtoexposethemastheRESTfulservicemethodsthatacceptandreturnthedataineitherJSONorXMLformats.ThishelpsdeveloperstoconsumetheWCFservicesaseasilyastheRESTservices,andusethemwiththejQuery$.ajaxor$.getJSON(shorthandmethodof$.ajax)methods.ToexposeaWCFserviceasaRESTservice,weneedtoannotatetheWCFservicemethodswiththeWebGetorWebInvokeattributes.TheWebGetattributeismostlyusedwhenmakinganyHTTPGETrequest,whereasWebInvokeisusedforallHTTPrequestmethods.

ThefollowingcodeshowstherepresentationofusingtheWebGetattributeonaWCFoperationcontractthatreturnstheproductbasedonproductCodepassedduringthemethodcall:

[OperationContract]

[WebGet(ResponseFormat=WebMessageFormat.Json,BodyStyle=

WebMessageBodyStyle.Wrapped,UriTemplate="json/{productCode}")]

ProductGetProduct(stringproductCode);

WecanalsorepresentthesamemethodusingWebInvoke,asshowninthefollowingcode:

[OperationContract]

[WebInvoke(Method="GET",ResponseFormat=WebMessageFormat.Json,BodyStyle=

WebMessageBodyStyle.Wrapped,UriTemplate="products/{productCode}")]

ProductGetProduct(stringproductCode);

ThefollowingcodeshowstherepresentationofusingWebInvokefortheHTTPPOSTrequest:

[OperationContract]

[WebInvoke(Method="POST",ResponseFormat=WebMessageFormat.Json,RequestFormat

=WebMessageFormat.Json,BodyStyle=WebMessageBodyStyle.Wrapped,UriTemplate=

"products/SaveProduct")]

boolSaveProduct(Productproduct);

Ifyounotice,thePOSTmethodcontainsbothRequestFormatandResponseFormatattributesthattelltheserverthetypeofdataprovidedwhenmakinganyHTTPPOSTrequestandtheresponsewillbereturnedbasedontheResponseFormattypedefined.

WhenworkingwiththeRESTfulservices,makesurethatthebindingissettowebHttpBinding,asshowninthefollowingscreenshot.Alsowiththe.NETframework4andhigher,MicrosoftintroducedanotherattributeknownascrossDomainScriptAccessEnabled,whichcanbesettotruetodealwithcross-originrequests:

Page 179: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Moreover,inordertoenableCORS,youcanspecifystandardEndpoints,asshowninthefollowingscreenshot,undersystem.serviceModel:

Addcustomheadersasfollows.Specifyingasterisk(*)allowseverything,whereasforsecuritypurpose,origin,headers,andmethodscanbedefinedexplicitlytospecificvaluesthatareseparatedbycommas:

Thefollowingtableshowsthedescriptionofeachaccesscontrolkeys:

Page 180: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Accesscontrolkey Description

Access-

Control-

Allow-Origin

Thiskeyisusedtoallowtheclient'sdomainfromwheretheservicewillbeinvoked

Access-

Control-

Allow-Headers

Thiskeyisusedtospecifytheheaderspermittedwhentheclientismakingarequest

Access-

Control-

Allow-Method

Usingthiskey,theHTTPmethodsallowedwhentheclientismakingarequest

Access-

Control-Max-

Age

Thiskeytakesthevalueinsecondstoseehowlongtheresponsetothepreflightrequestcanbecachedforwithoutsendingtheanotherpreflightrequest

ToinvoketheSaveProductmethod,wecanusethejQuery$.ajax()methodandsupplythefollowingparameters,asshowninthefollowingcode.Ifyounotice,wedefinedcontentTypeaswellasdataType.ThedifferenceisthatcontentTypeisusedtotelltheserveraboutthetypeofdataclientissending,whereasdataTypeisusedtolettheserverknowthetypeofdatatheclientisexpectingtoreceiveinresponse.ThedataTypevaluescanbejson,jsonp,xml,html,orscript:

functionSaveProduct(){

varproduct={

"ProductName":"Product1",

"ProductDescription":"ThisisProductA"

};

$.ajax({

type:"POST",

url:"http://localhost/products/SaveProduct",

data:JSON.stringify(product),

contentType:"application/json",

dataType:"json",

processData:true,

success:function(data,status,xhr){

alert(data);

},

error:function(error){

alert(error);

Page 181: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

});

}

Inordertomakeacalltoanotherdomain,wecanusejsonp,sotheserverwrapstheJSONdatainaJavaScriptfunction,whichisknownasacallbackfunction,andwhentheresponsecomesbacktotheclient,itwillautomaticallycallthesuccessmethod.Themodifiedversionoftheprecedingmethodtohandlecross-originrequestisshowninthefollowingcode.

Inthiscode,wemodifiedtheURLandpassedthecallback=?querystringasaparameter.Moreover,thecrossDomainattributeisusedtoensurethattherequestwillbecrossDomain.Whentheserverresponds,?specifiedinthecallbackqueryandthestringwillbereplacedbythefunctionname,suchasjson43229182_22822992,andwillcallthesuccessmethod:

functionSaveProduct(){

varproduct={

"ProductName":"Product1",

"ProductDescription":"ThisisProductA"

};

$.ajax({

type:"POST",

url:"http://localhost:4958/ProductService.svc/products/SaveProduct?

callback=?",

data:JSON.stringify(product),

contentType:"application/json",

dataType:"jsonp",

crossDomain:true,

processData:true,

success:function(data,status,xhr){

alert(data);

},

error:function(error){

alert(error);

}

});

}

Similarly,wecaninvoketheGetProductmethodasshowninthefollowingcode:

(function(){

varproductCode="Prod-001";

varwebServiceURL=

"http://localhost:4958/ProductService.svc/products/GetProduct/"+productCode;

$.ajax({

type:"GET",

url:webServiceURL,

dataType:"json",

processData:false,

Page 182: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

success:function(data){

alert(data);

},

error:function(error){

alert(error);

}

});

});

Forcrossdomain,itcanbemodifiedasfollows:

(function(){

varproductCode="Prod-001";

varwebServiceURL=

"http://localhost:4958/ProductService.svc/products/GetProduct/"+productCode;

$.ajax({

type:"GET",

url:webServiceURL+"?callback=?",

dataType:"jsonp",

crossDomain:true,

processData:false,

success:function(data){

alert(data);

},

error:function(error){

alert(error);

}

});

});

Alternatively,fortheprecedingsolution,wecanalsooverridethecallbackfunctionnameinajsonprequest,andthevaluespecifiedinjsonpCallbackwillbeusedinsteadofcallback=?passedinaURL.ThefollowingcodesnippetcallsyourlocalfunctionwhosenameisspecifiedinthejsonpCallbackvalue:

functioncallbackFn(data){

}

(function(){

varproductCode="Prod-001";

varwebServiceURL=

"http://localhost:4958/ProductService.svc/products/GetProduct/"+productCode;

$.ajax({

type:"GET",

url:webServiceURL,

dataType:"jsonp",

crossDomain:true,

processData:false,

jsonpCallback:callbackFn,

success:function(data){

alert(data);

},

error:function(error){

alert(error);

Page 183: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

});

});

Page 184: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryInthischapter,wediscussedAjaxtechniquesandconceptsofusingtheXMLHttpRequestobject.WehaveseenthebasicarchitectureofhowtheAjaxrequestisprocessedandwhateventsandmethodsitprovides.Similarly,wealsodiscussedwhatjQueryoffersandtheextensivelibraryithasforperformingdifferenttypesoftheHTTPGETandPOSTrequests.Inthenextchapter,wewilldiscussthebasicsofTypeScript,andoneofthemostpopularclient-sideframework,Angular2.WewillalsogothroughdevelopingasimpleapplicationusingASP.NETCoreMVC6withAngular2asafrontendframeworkandEntityFramework7forbackendoperations.

Page 185: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter5.DevelopinganASP.NETApplicationUsingAngular2andWebAPIInthischapter,wewilldevelopacompleteapplicationonASP.NETCoreusingMVC6forMVCviewsandWebAPIforwebservices.Fortheclientside,wewilluseAngular2,whichisoneofthemostpopularframeworksforclient-sidedevelopment.Angular2iswritteninTypeScript,butitprovidestheoptiontowritecodeinJavaScriptandDart.Inthischapter,wewilluseTypeScriptbecauseitadherestotheECMAScript6standard,withaprovisiontogenerateJavaScriptwhenyoubuildyourprojectinECMAScript3,ECMAScript4,andECMAScript5standards.TypeScriptisasupersetofJavaScriptandmostofthethingsarecommontoboth;infact,TypeScriptprovidessomefeaturesthatinJavaScriptarenotimplementedbymanybrowsers,exceptMozillaFirefox.

ThischapterfocusesonthebasicconceptsandtakesyouthroughasampleapplicationtolearnhowAngular2canbeusedwithASP.NETCoreandMVC6.

Page 186: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

TypeScriptTypeScriptisalanguagedevelopedbyMicrosoftandisasupersetofJavaScript.TypeScripttranspilesintoJavaScriptatcompiletime.VisualStudio2015automaticallybuildstheTypeScriptintoJavaScriptfilesandplacestheminsideafolderconfiguredwiththeTypeScript.tsconfigconfigurationfile.ItprovidesalotmorethanJavaScriptprovides,butdeveloperscanstillusesomeofthetypesandobjectsinTypeScriptthattheyuseinJavaScript.However,TypeScriptgeneratescleanerandmoreoptimizedcode,whichisthenrunbytheAngular2framework.So,whentheTypeScriptcompiles,itgeneratesJavaScriptandstoresamapfiletohandledebuggingscenarios.SupposeyouwanttodebugyourTypeScriptcodefromVisualStudio2015;thismappingfilecontainsthemappinginformationofthesourceTypeScriptfileandgeneratedJavaScriptfilebeingruninsideyourAngularpageandthebreakpointscanbesetonyourTypeScriptfile.

Page 187: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CompilationarchitectureofTypeScriptTheTypeScriptcompilergoesthroughseveralstagestocompileTypeScriptfilesandgenerateJavaScriptfiles.

Thecompilationprocessstartswithapre-processor,whichdetermineswhatfilesneedtobeincludedbyfollowingreference///<referencepath=…/>tagsandimportstatements.Oncethefilesareidentified,theparserparsesandtokenizesthesourcecodeintoanAbstractSyntaxTree(AST).

AnASTrepresentsthesyntacticalstructureofthesourcecodeinatreeformatthatconsistsofnodes.ThebinderthenpassesovertheASTnodesandgeneratesandbindssymbols.Onesymboliscreatedforeachnamedentityandiftherearemultipleentitieswiththesamename,theywillhavethesamesymbol.

Symbolsrepresentnamedentitiesandmergemultiplefilesifseveraldeclarationsarefound.Torepresentaglobalviewofallthefiles,aprogramisbuild.Aprogramisthemainentrypointtothetypesystemandcodegeneration.Oncetheprogramiscreated,atypecheckerandanemittercanbecreated.

AtypecheckeristhecorepartoftheTypeScriptsystem,consolidatesallthesymbolsfrommultiplefilesintoasingleview,andbuildsasymboltable.Thissymboltablecontainsthetypesofeachsymbolidentifiedandmergedintoacommonsymbol.Atypecheckercontainscompleteinformationaboutwhichsymbolbelongstowhichnode,thetypeofaparticularsymbol,andsoon.

Finally,anemitterisusedbytheTypeScriptcompiler,throughaprogram,togeneratetheoutputfile:.js,.js.map,.jxs,ord.ts.

Page 188: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AdvantagesofTypeScriptThefollowingaresomecorebenefitsofusingTypeScriptwithAngular2.

SupersetofJavaScript

TypeScriptisatypedsupersetofJavaScriptthatcompilestoJavaScript.ThebasicadvantageofbeingasupersetisthatitprovidesthelatestfeaturesofJavaScriptthatmanybrowsersdonotsupportyet.Developersusefeaturessuchasasyncfunctions,decorators,andothersduringapplicationdevelopment,whichthencompileintoaJavaScriptfilethattargetstheECMAScript4orECMAScript3versions,whichbrowserscaneasilyunderstandandinterpret.

Supportforclassesandmodules

Typescriptsupportsclass,interface,extends,andimplementskeywords.

HereishowyoucandefineclassinTypeScript:

classPerson{

privatepersonId:string='';

privatepersonName:string='';

privatedateOfBirth:Date;

constructor(){}

getPersonName():string{

returnthis.personName;

}

setPersonName(value):void{

this.personName=value;

}}

HereisthetranspiledversionofTypeScriptinJavaScript:

varPerson=(function(){

functionPerson(){

this.personId='';

this.personName='';

}

Person.prototype.getPersonName=function(){

returnthis.personName;

};

Person.prototype.setPersonName=function(value){

this.personName=value;

};

returnPerson;

})();

Statictypechecking

ThemainbenefitofusingTypeScriptisstatictypechecking.Whenyoubuildyourproject,theTypeScriptcompilerchecksthesemanticsandgiveserrorsatcompiletimetoavoidruntime

Page 189: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

errors.Forexample,thefollowingcodewillgiveanerroratcompiletime:

varname:string

name=2;//giveerror

HereisanotherexamplethatextendsthePersonclassandgivesatypemismatchederroratcompiletype:

classPerson{

constructor(name:string){

}

}

classEmployeeextendsPerson{

constructor(){

super(2);//error

}

}

ECMAScript6featuresupport

Atthetimeofwriting,mostbrowsersstilldonotsupportECMAScript6completely,butwithTypeScript,wecanwritecodeanduseECMAScript6features.AsECMAScript6supportsbackwardcompatibility,wecansetthetargetversionthroughtheTypeScriptconfigurationfile,whichgeneratestheJavaScriptbasedontheversionspecified.ThishelpsdeveloperstowritecodeusingECMAScript6featuresandtheoutputJSfileswillbegeneratedinECMAScript3,ECMAScript4,orECMAScript5standards.

Optionaltyping

TypeScriptsupportsstricttypingandvalidatestypesatcompiletype,butusingstricttypingisnotmandatory.Youcanevendeclareavariablewithoutspecifyingitstypeanditwillberesolvedwhenthevalueisassigned.

DeclaringtypesinTypeScript

Hereisanexampleofdeclaringavariablewithoutitstype:

privatesNo=1;

privatetext='Helloworld';

Hereisanexampleofdeclaringavariablewithtypes:

privatesNo:number=1;

privatetext:string='Helloworld';

Page 190: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CoreelementsofTypeScriptThissectiondiscussesthecoreelementsofTypeScript:

DeclaringvariablesTypesClassesandinterfacesFunctionsIteratorsModulesandnamespaces

Declaringvariables

VariabledeclarationisequivalenttowhatwedoinJavaScript.However,asTypeScriptfollowstheECMAScript6standard,itprovidesstrongtypesaswell.Strongtypescanbedeclaredbynamingavariablefollowedbyacolon(:)anditstype.

HereisasimplevariabledeclarationinJavaScript:

varname;

ItcanbedeclaredinTypeScriptasfollows:

varname:string;

VariablescanbeinitializedinTypeScriptasfollows:

varname:string="HelloWorld";

Types

MostofthetypesavailableinTypeScriptareequivalenttoJavaScripttypes.Thefollowingtablecontainsalistofallavailabletypes,withacodesnippetforusingthem:

Type Description Codesnippet

NumberTypeScriptprovidesanumbertypethatholdsalltypesofdecimal,hexadecimal,binary,andoctalvalues.

letdecimal:number=2;

lethex:number=0x001;

letbinary:number=

0b1010;

letoctal:number=0o744;

StringIt'sthesameasweuseinanyotherlanguage.Stringvaluescanbesurroundedwithsingleordoublequotes.

letx:string='Hello';

lety:string="Hello";

Page 191: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ArrayTypeScriptsupportssimplearrays,andgenericarraysaswell.

letcountries=['US',

'UK','UAE'];

letcountries<string>=

['US','UK','UAE'];

Tuple Throughtuples,wecandefineanarraywhoseelementtypesareknown.

letval:[string,number,

Date];

val=['HelloWorld',10,

newDate()];

val[0];//printHelloWorld

EnumUsedtogivenamestothenumericalvalues.Bydefault,thefirstvaluespecifiedis0butcanbesetexplicitlytoanynumber.

enumStatus{InProcess,

Active,Ready,Success,

Error}

lets:Status=

Status.Active;

//specifyvalues

explicitly

enumStatus{InProcess=1,

Active=2,Ready=3,

Success=4,Error=5}

Any Thistypecanbeusedincaseswherethetypeisnotknownandisdependentonanassignment.

letx:any;

x=['Hello',1,2];

//tuple;

x=1;//number

x='HelloWorld';//string

Classesandinterfaces

Thefollowingarethewaysofdefininginterfaces,derivingclassesandinterfaces,andwritinggenericclassesinTypeScript.

Defininginterfaces

JustlikeC#,TypeScriptallowsyoutodefineinterfacesthatcanbeimplementedinTypeScriptclassesandforcetheimplementerclasstoimplementallthemembersdefinedintheinterface.

HereisthecodetodefineaninterfaceinTypeScript:

interfaceIShape{

shapeName:string;

draw();

}

classTodoServiceimplementsIShape{

constructor(privatehttp:Http){

this.shapeName="Square";

}

Page 192: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

shapeName:string;

draw(){

alert("thisis"+this.shapeName);

}

}

Derivingclassesandinterfaces

LikeC#,classesandinterfacescanbeextendedbyderivingfrombaseclassesorinterfaces.Toextendanyclass,wecanusetheextendskeyword,andforaninterfacewecanuseimplements,asshownhere:

interfaceIPerson{

id:number;

firstName:string;

lastName:string;

dateOfBirth:Date;

}

interfaceIEmployeeextendsIPerson{

empCode:string;

designation:string;

}

classPersonimplementsIPerson{

id:number;

firstName:string;

lastName:string;

dateOfBirth:Date;

}

classEmployeeextendsPersonimplementsIEmployee{

empCode:string;

designation:string;

}

Inthepreviouscodesnippet,wehavedeclaredtwointerfaces,IPersonandIEmployee.IPersoncontainscommonpropertiessuchasid,firstName,lastName,anddateOfBirth,whichcanbeusedinallderivedinterfaces,suchasIEmployeeoranyother.

Then,wehaveimplementedtheIPersoninterfaceinthePersonclass,andfinallyderivedtheEmployeeclassfromPersonandimplementedtheIEmployeeinterface.Ifyouhavenoticed,asthePersonclassalreadyimplementstheIPersoninterface,wedonothavetoimplementitagainandonlyimplementtheproperties,suchasempCodeanddesignationintheEmployeeclass.

Genericclasses

Genericclassesareusefultodefineaparticularclasswhosetypeisgenericanddeterminedwhenitiscalled.Genericclassescanbedefinedbyusing<T>followedbytheclassname.

Page 193: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Hereisasimpleexamplethatshowsthegenericclassprocess,whichcanworkasperthetypespecifiedduringinitialization.ThegetTypeInfo()methodwillprintaspecificmessagebasedonthetypeofobjectinitialized:

classProcess<T>{

value:T;

getTypeInfo(){

if(typeofthis.value=="string")

console.log("Typeisastring");

elseif(typeofthis.value=="number")

console.log("Typeisanumber");

elsealert("typeisunknown");

}

}

letpString=newProcess<string>();

pString.getTypeInfo();//printTypeisastring

letpNumber=newProcess<number>();

pNumber.getTypeInfo();//printTypeisanumber

Functions

FunctionscanbedefinedinthesamewayasJavaScript.TypeScriptsupportsbothnamedandanonymousfunctions.InTypeScript,functionparameterscanbetypedparameters,asshownhere:

functionconcat(x:string,y:string):string{

returnx+""+y;

}

Functionscanalsohaveoptionalparametersandcanbedeclaredbyusing(?)asshownhere:

functionconcat(x:string,y:string,z?:string):string{

returnx+""+y+""+z;

}

Withthisoption,wecancallthefunctionbypassingtwoparametersorthreeparametersbecausethethirdparameterisoptional.

Genericfunctions

TypeScriptallowsyoutodefinegenericfunctions,whichacceptanytypeofargumentorreturntype.Genericfunctionscanbedefinedbyspecifyingthe<T>afterthefunctionname,asshowninthefollowingcode,andtheargumentsorreturnedtypecanalsobegenericandrefertothesameTtype.Thisisusefultodefineaparticularfunctionthatacceptsalltypesofargumentsandworksasexpected.Thefollowingexampleshowstheprocessfunctionbasedonthetypeofargumentconcatenatedoradded:

functionprocess<T>(x:T,y:T):string{

if(typeofx=="string")

returnx+""+y;

Page 194: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

elseif(typeofx=="number")

return"Sumis:"+x+y;

else

return"Typeinunknown";

}

Iterators

Apartfromstandardloopssuchasfor,while,TypeScriptalsoprovidestwotypesofforstatements,for..ofandfor..in.Bothstatementsiterateoncollections.Thedifferencebetweentheseisthatthefor..ofstatementreturnsthekeysoftheobjectwhereasfor..inreturnsthevalues:

countries=['USA','UK','UAE'];

//thisloopwilldisplaykeys0,1,2

for(letindexinthis.countries){

console.log(index);

}

//thisloopwilldisplayvaluesUSA,UK,UAE

for(letindexofthis.countries){

console.log(index);

}

Modulesandnamespaces

ECMAScript6introducestheconceptofmodules.Modulescanbethoughtofaslogicalcontainersthathavetheirownscope.Anyclass,variable,ormethoddeclaredinsideamoduleisscopedwithinitsowncontainerandaccessibletoothermodulesonlyifitisallowedexplicitly.InTypeScript,anyfilecontainingimportsorexportsatatoplevelareconsideredmodules.Modulesimportoneanotherusingamoduleloader,andatruntimethemoduleloaderisresponsibleforloadingallthedependenciesofthemoduledefinedwithinit.Modulescanbeexportedusingtheexportkeywordandothermodulescanimportitusingtheimportkeyword.

HereisanexampleofdefiningandexportingamoduleinTypeScript:

//BaseManager.ts

exportclassBaseManager{

}

Tousethemoduleinsomeotherarearequiresyoutousetheimportkeyword,asshownhere:

//ServiceManager.ts

exportclassServiceManagerextendsBaseManager{

}

Modulescanbeimportedbyusingtheimportkeyword.Whenimportinganymodule,youhavetousetheimportkeyword,followedbytheclassnameinbrackets{},followedbytheactualfilenamethatcontainstheclass.Forexample,thefollowingcodeshowsthewayofimportingServiceManagerintoMain.ts:

Page 195: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

//Main.ts

import{ServiceManager}from"./ServiceManager"

Wecanalsogiveafriendlynametotheclass,asfollows:

//Main.ts

import{ServiceManagerasserviceMgr}from"./ServiceManager"

Namespaces,ontheotherhand,arethelogicalmodulestocategorizeclasses,methods,andsoon.JustlikeC#,theycanbedefinedbyusinganamespacekeyword.OnenamespacecanbesplitacrossdifferentTypeScriptfilesandthisgivesdevelopersahandywayofcategorizingspecificfilestoasinglenamespace.ThefollowingexampleshowsthewaytocategorizeTypeScriptfilesintoasinglenamespaceandusingthem:

//PersonManager.ts

namespaceBusinessManagers{

exportclassPersonManager{}

}

//SecurityManager.ts

namespaceBusinessManagers{

exportclassSecurityManager(){

}

}

//main.ts

///<referencepath="personmanager.ts"/>

///<referencepath="SecurityManager.ts"/>

personObj=newBusinessManagers.PersonManager();

securityObj=newBusinessManagers.SecurityManager();

Ifyounotice,wehaveusedatriple-slashdirective,whichisusedtorefertothedependentfilesbeforeexecutingthecodeintheTypeScriptfile.Therefore,asthesefilespersistsomewhereelse,wehavetoexplicitlyreferencethemintheprecedingcode.

Tosummarize,namespacesareabettermethodtousethanmodulesastheycategorizefileslogicallybyprovidingafriendlyname,andallowdeveloperstostructurecodeproperlywhenworkingwithmedium-to-large-sizedprojects.

Wecanalsogiveashortenednametoanamespaceifit'sunfriendlybyusinganimportkeywordasshownhere:

namespaceBusinessManagers{

exportclassPersonManager{

}

}

importmgr=BusinessManagers;

letpersonObj=newmgr.PersonManager();

ToLC:Applycodeto:

"namespaceBusinessManagers{

exportclassPersonManager{

Page 196: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

}

importmgr=BusinessManagers;

letpersonObj=newmgr.PersonManager();

SothiswindsupthecoretopicsofTypeScript.TolearnmoreaboutTypeScript,youcanrefertohttp://www.typescriptlang.org/.

Page 197: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

IntroductiontoAngular2Angular2isaclient-sideframeworktobuildwebapplications.Itisveryflexibleintermsofbeingusedwithbothmobileandwebplatforms.ThebasicadvantageofusingAngularisthatitfollowstheECMAScript6standardanddeveloperscandoobject-orientedprogramming,defineclassesandinterfaces,implementclasses,anddefinedatastructuresusingPlainOldJavaScriptObjects(POJO)forbindingdata.Anotherbigadvantageintermsofperformanceistheunidirectionaldataflow.UnlikeAngular1.x,Angular2providesboththeoptionofdoingtwo-waydatabindingorunidirectionaldatabinding.Incertaincases,unidirectionalbindingisgoodforperformance.Forexample,whensubmittingaform,twowaybindingswithcontrolsmaybeoverkill.

Page 198: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Angular2architectureAngular2consistofanumberofcomponents.Eachcomponentcanbeboundtothepagebyeitheraselector,forexample<my-app></my-app>,oraroutingmodule.Eachcomponenthasaselector,templateHTMLortemplatereferencelink,directives,providers,andacontrollerclasswhosepropertiesandmethodscanbeaccessedintheassociatedview.Whenthewebapplicationfirststarts,System.importloadsthemaincomponentoftheapplication,whichbootstrapstherootcomponent.HereisasamplemaincomponentbootstrappinganAngularapp:

//LoadingmodulethroughImportstatement

Import{AppComponent}from'pathofmycomponent'

bootstrap(AppComponent,[Providers]);

Providerscanbedefinedinsidesquarebrackets.Therearevariousprovidersavailable,whichwewilldiscussinalaterchapter.

Thisbootstrapobjectisinangular2/platform/browser,whichcanbeimportedintotheTypeScriptfilewiththeimportcommand:

import{bootstrap}from'angular2/platform/browser';

ThisbootstrapobjectdirectsAngulartoloadthecomponentdefinedinit.Whenthecomponentisloaded,alltheattributesormetadatadefinedforthecomponentareevaluated.Eachcomponentshouldhavethe@Componentannotation,somepropertiestodefinemetadataaboutthecomponent,andoneormoreclassestermedascomponentcontrollersthatcontainpropertiesandmethodsaccessiblebythetemplatedefinedinthe@ComponenttemplateortemplateUriproperties.

Hereisasampleapp.component.tsthatcontainsaselector,atemplate,andaclass,AppComponent:

//app.component.ts

import{Component,View}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

@Component({

selector:"my-app",

template:`<p>Thisisafirstcomponent</p>`,

})

classAppComponent{

}

bootstrap(AppComponent);

Eventsofcomponentlifecycle

Whenthecomponentinitializes,itgoesthroughseveraleventsandhasaverystructuredlifecycleprocess.Wecanimplementtheseeventstodospecificoperations.Thefollowingtableshowsthelistofeventswecanuseinourcomponentcontrollerclass:

Page 199: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Event Description

ngOnInit()Itiscalledafterthecomponentisinitializedandthecontrollerconstructorisexecuted.

ngOnDestroy()Itisusedtocleanupresourceswhenthecomponentisdisposedof.

ngDoCheck()Itisusedtooverridethedefaultchangedetectionalgorithmforadirective.

ngOnChanges(changes)

Itisinvokedwhenanyofthecomponentselectorpropertyvaluesgetmodified.(Custompropertiesoftheselectorscanbedefinedthroughinputs.)

ngAfterContentInit()Itisinvokedwhenthedirective'scontentisinitialized.(Directivesaredefinedlater.)

ngAfterContentChecked() Itisinvokedeverytimethedirective'scontentischecked.

ngAfterViewInit() Itisinvokedwhentheviewiscompletelyinitialized.

ngAfterViewChecked() Itisinvokedoneverycheckofyourcomponent'sview.

Modules

Amodulerepresentsacontainerthatcontainsclasses,interfaces,andmore,toexportfunctionality,soothermodulescanbeimportedusingtheimportstatement.Forexample,hereismath.ts,usedtoperformdifferentarithmeticoperations:

//math.ts

import{Component}from'angular2/core';

@Component({

})

exportclassMathService{

constructor(){

}

publicsum(a:number,b:number):number{

returna+b;

}

publicsubtract(a:number,b:number):number{

Page 200: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

returna-b;

}

publicdivide(a:number,b:number):number{

returna/b;

}

publicmultiply(a:number,b:number):number{

returna*b;

}

}

Components

Acomponentisacombinationofthe@Componentannotationtodefinemetadatapropertiesandtheassociatedcontrollerclassthatcontainstheactualcode,suchastheclassconstructor,methods,andproperties.The@Componentannotationcontainsthefollowingmetadataproperties:

@Component({

providers:string[],

selector:string,

inputs:string[],

outputs:string[],

properties:string[],

events:string[],

host:{[key:string]:string},

exportAs:string,

moduleId:string,

viewProviders:any[],

queries:{[key:string]:any},

changeDetection:ChangeDetectionStrategy,

templateUrl:string,

template:string,

styleUrls:string[],

styles:string[],

directives:Array<Type|any[]>,

pipes:Array<Type|any[]>,

encapsulation:ViewEncapsulation

})

Page 201: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CorepropertiesofAngular2componentsWhendefiningacomponent,wecanspecifyvariousproperties,aslistedpreviously.HerewewillseesomeofthecorepropertiesthatareoftenrequiredwhencreatingAngular2components:

TemplatesandselectorsInputsandoutputsDirectivesProviders

Templatesandselectors

Thefollowingrealexamplecontainsthetemplateandtheselectordefinedinthecomponentclass.Whenthebuttonisclicked,itwillcallthelogMessage()method,whichprintsthemessageinthe<p>element.Ifyounotice,wehavenotusedtheexportkeywordwiththeclassbecausewehavealreadybootstrappedthecomponentonthesamefileandthiscomponentdoesnotneedtobereferencedanywhereelse:

import{Component,View}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

@Component({

selector:"my-app",

template:"<p>{{message}}</p><button(click)='logMessage()'>Log

Message</button>"

})

classAppComponent{

logMessage(){

this.message="HelloWorld";

}

message:string="";

}

bootstrap(AppComponent);

TheappselectorcanbeusedanywhereintheHTMLorindex.cshtmlpageifworkingonanASP.NETproject,andthetemplatewillberenderedinsideit.Hereisanexampleofusingthecustomtagmy-app:

<html>

<body>

<my-app></my-app>

</body>

</html>

Oncethepageruns,itwillrendertheoutputwiththisgeneratedsource:

<html>

<body>

<p>HelloWorld</p>

<button(click)='logMessage()'>LogMessage</button>

</body>

</html>

Page 202: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Inputsandoutputs

Inputsallowdeveloperstospecifythecustomattributesmappedtosomepropertyofthecomponentclassdownwardinthehierarchyofcomponents,whereasoutputsareusedtodefinecustomeventhandlersonthecomponentthatcanberaisedupwardinthehierarchyofcomponents.Inshort,inputsareusedtosenddatafromparenttochildcomponents,whereasoutputsareusedtoinvokeeventsfromchildtoparentcomponents.Inthepreviousexample,wesawhowselectorscanbeused,andtheassociatedtemplateisrenderedinplaceofaselector,withtheprovisionofhavingallthemembersofthecomponentclassavailable.Incertaincases,wehavetospecifysomeattributesinourcustomselectortopassthevaluetohandleparticularactions.Forexample,wemayneedsomeattributeintheprevious<my-app>tagtospecifytheloggingtype,suchastologontoadeveloper'sconsoleorshowanalertmessage.

Usinginputs

Inthisexample,wewillcreatetwoinputattributes,logToConsoleandshowAlert.Wecandefineinputattributesinthe@Componentannotation.Thefollowingcodesnippetistheseparatecomponentdefinedinchild.component.tsandcontainstheselectoraschild;thetemplatedisplaystheBooleanvaluesofthelogToConsoleandshowAlertattributesspecifiedinthechildtag.Theinputscontainthelistofstringvariablesthatwillbedefinedasthechildtagattributes:

//child.component.ts

import{Component}from'angular2/core';

@Component({

selector:'child',

template:`<div>LogtoConsole:{{logToConsole}},ShowAlert:{{showAlert}}

<button(click)="logMessage()">Log</button></div>`,

inputs:['logToConsole','showAlert'],

})

HereistheChildComponentclassthatcontainsthelogToConsoleandshowAlertBooleanvariables.Thesevariablesactuallyholdthevaluessuppliedfromthenotificationtag.Finally,wehavethelogMessage()methodthatwillbeinvokedonabuttonclickeventandeitherlogthemessageonthedeveloper'sconsoleorshowanalertmessagebasedonthevaluethathasbeensetbytheparentcomponentinthehierarchy:

exportclassChildComponent{

publiclogToConsole:boolean;

publicshowAlert:boolean;

logMessage(message:string){

if(this.logToConsole){

console.log("Consoleloggingisenabled");

}

if(this.showAlert){

alert("Showingalertmessageisenabled");

}

Page 203: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

}

Intheapp.component.tsfile,wherewehavethemainAppComponentdefined,wecanusethechildselectorasshowninthefollowingcode.Whendefiningthechildselector,wecansetthevaluesforcustominputsdefinedintheChildComponent,logToConsoleandshowAlert.Thiswaytheparentcomponentcanspecifythevaluestothechildcomponentthroughinputs.HereisthecompletecodeofAppComponent:

//app.component.ts

import{Component,View}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

import{ChildComponent}from'./child.component';

@Component({

selector:"my-app",

template:`<child[logToConsole]=true[showAlert]=true></child>`,

directives:[ChildComponent]

})

exportclassAppComponent{

}

bootstrap(AppComponent);

Tip

WhenusingtemplatetodefineHTML,wecanuseabacktick(`)ratherthanthedoublequotes('')orsinglequotes('),asshowntheprecedingexample.ThisallowstheHTMLcontenttospanmultiplelines.

Usingoutputs

Outputsareusedtoinvokeeventsontheparentcomponentfromchildcomponentsinthehierarchyofcomponents.WewillmodifytheprecedingexampleandaddtheoutputseventintheChildComponent,thenregisteritintheAppComponentusingtheChildComponentselector.

HereisthemodifiedcodesnippetforChildComponent:

//child.component.ts

import{Component,EventEmitter,Output}from'angular2/core';

@Component({

selector:'child',

template:`<div>LogtoConsole:{{logToConsole}},ShowAlert:{{showAlert}}

<button(click)="logMessage()">Log</button></div>`,

inputs:['logToConsole','showAlert']

})

exportclassChildComponent{

publiclogToConsole:boolean;

publicshowAlert:boolean;

@Output()clickLogButton=newEventEmitter();

logMessage(message:string){

this.clickLogButton.next("Fromchild");

}

Page 204: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

The@OutputpropertylistsclickLogButtonasacustomeventthatChildComponentcanemit,whichitsparentAppComponentwillreceive.

WehaveaddedEventEmitterintheimportstatement.EventEmitterisabuilt-inclassthatshipswithAngularandprovidesmethodsfordefiningandfiringcustomevents.OncethelogMessage()methodisexecuted,itwillexecutetheclickLogButton.next()methodfromtheChildComponent,whichfinallycallstheeventregisteredintheAppComponent.

WehaveaddedtheclickLogButtonintheAppComponent,asshowninthefollowingcode.InAngular2,wecanspecifytheeventbyspecifyingtheeventnameinbrackets()followedbythemethodthatwillbecalledwhentheeventisraised.Thisishowtheeventisregistered.Here,logMessageisthelocalmethoddefinedintheAppComponent:

(clickLogButton)="logMessage($event)"

HereisthecodesnippetforAppComponent:

//app.component.ts

import{Component,View}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

import{ChildComponent}from'./child.component';

@Component({

selector:"my-app",

template:`<child[logToConsole]=true[showAlert]=true

(clickLogButton)="logMessage($event)"></child>`,

directives:[ChildComponent]

})

exportclassAppComponent{

logMessage(value){

alert(value);

}

}

bootstrap(AppComponent);

ThelogMessagemethodisthemethodthatwillbeinvokedwhentheeventisraisedfromtheChildComponent.

Directives

DirectivesarecustomtagsthatrendertheHTMLatruntimebutencapsulatetherenderingcontentinthedirectiveitself.WecanrelateittothetaghelpersinASP.NET.Therearethreekindsofdirectives,components,structuraldirectives,andattributedirectives:

Components:Itisadirectivewithatemplate.Structuraldirective:ItisadirectivetoaddorremoveDOMelements.Therearesomebuilt-instructuraldirectivesthatAngularprovides.DirectivessuchasngIf,ngSwitch,andngForarestructuraldirectives.

Page 205: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Attributedirective:ItchangestheappearanceofanyDOMelement.CreatingasimpleHelloWorlddirective

Directivescanbecreatedinasimpleway,asacomponentiscreated,andcanbereferencedinthecallingcomponentthroughitsselectortag.

HereisanexampleofHelloWorldComponentthatdefinesasimpledirectivetodisplaya"Helloworld"messageintheheadingformat:

//helloworld.component.ts

import{Component}from'angular2/core';

@Component({

selector:"helloworld",

template:"<h1>Helloworld</h1>"

})

exportclassHelloWorldComponent{

}

Thefollowingexampleisthecomponentthatusesthisdirective.Whenusinganydirective,ithastobefirstimportedthroughtheimportstatement,thenthe@Componentmetadatapropertyneedstobesettoaccessitintheassociatedtemplate:

import{Component,View,provide,Inject}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

import{HelloWorldComponent}from'./helloworld.component';

@Component({

selector:"my-app",

template:`<helloworld></helloworld>`,

directives:[,HelloWorldComponent],

})

exportclassAppComponent{

}

bootstrap(AppComponent);

Thisdirectivecanbeusedonthepageasfollows:

<helloworld></helloworld>

Structuraldirectives

StructuraldirectivescanbeusedtoaddorremoveDOMelements.Forexample,wecanaddthelistofcountriesasatablethrough*ngFor,asshowninthefollowingcode,andhideorunhidethedivthroughthe*ngIfdirective:

<div*ngIf="display">

<table>

<thead>

Page 206: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<tr>

<th>

Country

</th>

<th>

Currency

</th>

</tr>

</thead>

<tbody*ngFor="#countryofcountries">

<tr><td>{{country.CountryName}}</td><td>{{country.Currency}}</td></tr>

</tbody>

</table>

</div>

Hereisthebackendcountries.component.ts,whichusestheHTTPmoduletocalltheASP.NETWebAPIservice.Itreturnsalistofcountries,whichisassignedtothecountriesarray.Thedisplaydefaultvalueissettotrue,whichgeneratesthetable.Bysettingthedisplayvaluetofalse,thetablewillnotbegenerated:

///<referencepath="../../node_modules/angular2/typings/browser.d.ts"/>

import{Component}from'angular2/core';

import{Http,Response}from'angular2/http';

@Component({

selector:'app',

templateUrl:'Countries'

})

exportclassTodoAppComponent{

countries=[];

display:boolean=true;

//constructor

constructor(privatehttp:Http){

}

//PageInitializedEventHandler

ngOnInit(){

this.getCountries();

}

getCountries(){

this.http.get("http://localhost:5000/api/todo").map((res:Response)=>

res.json())

.subscribe(data=>{

this.countries=data;

},

err=>console.log(err),

()=>console.log("done")

);

}

}

ThisishowstructuraldirectivescanbeusedinAngular2.Inthefollowingchapter,wedevelopasampleapplicationanddiscusseachartifactformakingHTTPGETandPOST

Page 207: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

requestsusingAngular2.

Attributedirective

Anattributedirectiverequiresbuildingacontrollerclassannotatedwith@Directiveanddefinesaselectortoidentifytheattributeassociatedwithit.Inthefollowingexample,wewilldevelopasimplemyFontdirectivethatchangesthetexttoitalicwhenitisappliedtoanypageelements.Hereisthefont.directive.tsfile:

import{Directive,ElementRef,Input}from'angular2/core';

@Directive({selector:'[myFont]'})

exportclassFontDirective{

constructor(el:ElementRef){

el.nativeElement.style.fontStyle='italic';

}

}

Foreachmatchingelementonthepage,AngularcreatesanewinstanceandinjectsElementRefintotheconstructor.ElementRefisaservicethroughwhichwecandirectlyaccesstheelementthroughitsnativeElementpropertyandaccessotherattributes.Intheprecedingcodesnippet,wearechangingthefontstyletoitalicfortheelementsthathavethemyFontdirectiveapplied.

Onthepagelevel,itcanbeusedasfollows:

<pmyFont>myFontisanAttributedirective</p>

Providers

ProvidersareusedtoregisterthetypesthatgetsinstantiatedthroughthedependencyinjectionframeworkofAngular2.Whenacomponentisinitialized,Angularcreatesadependencyinjectorwhichregistersallthetypesspecifiedintheprovidersarray.Thenattheconstructorlevel,ifthereisanytypedefinedintheprovidersarray,itwillgetinitializedandinjectedintotheconstructor.

ThefollowingexampleisMathComponent,whichwillbeinjectedintothemainappcomponentconstructorandcallthesummethodtoaddtwonumberstogether:

//math.component.ts

import{Component}from'angular2/core';

@Component({})

exportclassMathComponent{

publicsum(a:number,b:number):number{

returna+b;

}

publicdivide(a:number,b:number):number{

returna/b;

}

publicsubtract(a:number,b:number):number{

Page 208: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

returna-b;

}

publicmultiply(a:number,b:number):number{

returna*b;

}

}

ThefollowingexampleisAppComponent,showinghowtoimportamathcomponent,thendefiningtheproviderandinjectingitattheconstructorlevel:

//app.component.ts

import{Component,View}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

import{MathComponent}from'./servicemanager.component';

@Component({

selector:"my-app",

template:"<button(click)="add()">Log</button>",

providers:[MathComponent]

})

exportclassAppComponent{

obj:MathComponent;

constructor(mathComponent:MathComponent){

this.obj=mathComponent;

}

publicadd(){

console.log(this.obj.sum(1,2));

}

}

bootstrap(AppComponent);

OtherprimitivetypescanalsobeinjectedinaslightlydifferentwayusingtheInjectAngularmodule.Wecanalsodefineatypeusingtheprovidekeyword,whichtakesakeyandthevalue:

providers:[provide('Key',{useValue:'HelloWorld'})]

Theprecedingsyntaxcanalsobeusedwhendefiningtypesinproviders,asfollows:

providers:[provide(MathComponent,{mathComponent:MathComponent})]

Oneofthemainbenefitsofdefiningproviderswiththeprovidekeywordiswhentesting.Whentestingapplications,wecanreplacetheactualcomponentswiththemockortestcomponents.Forexample,supposewehaveaclassthatcallssomeSMSservicetosendSMSusingsomepaidgateway,andinthetestingcyclewedon'twanttousetheproductionSMSgatewaycomponent,butratherwewouldliketohavesomecustomtestcomponentthatjustinsertstheSMSintoalocaldatabase.Inthiscase,wecanassociatesomemockclass,suchasSMSTestComponent,toperformtestingscenarios.

Thefollowingexampleinjectsthestringvalueintotheconstructor.WeneedtoaddtheInjectmoduleasspecifiedinthefollowingcode,andthenuse@Injecttoinjectthevalueassociatedtothekey:

Page 209: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

//app.component.ts

import{Component,View,provide,Inject}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

import{MathComponent}from'./servicemanager.component';

@Component({

selector:"my-app",

template:`button(click)="logMessage()">Log</button>`,

providers:[MathComponent,provide('SampleText',{useValue:'SampleValue'})]

})

exportclassAppComponent{

obj:MathComponent;

Val:string;

constructor(mathComponent:MathComponent,@Inject('SampleText')value){

this.obj=mathComponent;

this.Val=value;

}

publiclogMessage(){

alert(this.kVal);

}

}

bootstrap(AppComponent);

Page 210: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DependencyinjectioninAngularAngularchainsdependencyinjectionandinjectscomponentsintothechildcomponentsiftheyaredefinedintheprovidersarrayoftheparentcomponent.However,achildcomponentcandefinethesamecomponentinitsownprovidersarray.Thescopeofthecomponenttravelsthroughthechainofcomponents.However,componentsthataredefinedintheviewprovidersarrayaren'tinjectedorinheritedbythechildcomponentsinthehierarchicalchain.

Let'stakeasimpleexamplethatcontainsonemaincomponentinapp.tsandAppComponentdefinestwoproviders:ChildComponentandMathComponent.ChildComponentisthechildoftheparentcomponent,whereasMathComponentisusedinboththeparentandchildcomponents.Ifyounotice,inthefollowingcodesnippet,wehavenotspecifiedtheMathComponentintheprovidersarrayoftheChildComponent,andasitisdefinedintheParentComponent,itisalreadyinjectedbytheAngulardependencyinjectionmodule.

HereisthecodesnippetforAppComponent(parent):

//app.component.ts

import{Component}from'angular2/core';

import{bootstrap}from'angular2/platform/browser';

import{MathComponent}from'./servicemanager.component';

import{ChildComponent}from'./child.component';

@Component({

selector:"my-app",

template:`<button(click)="callChildComponentMethod()">Log</button>`,

providers:[MathComponent,ChildComponent]

})

exportclassAppComponent{

childObj:ChildComponent;

constructor(childComponent:ChildComponent){

this.childObj=childComponent;

}

publiccallChildComponentMethod(){

this.childObj.addNumbers(1,2);

}

}

bootstrap(AppComponent);

ThefollowingisthecodesnippetforMathComponent,whichcontainssomebasicarithmeticoperations:

//math.component.ts

import{Component}from'angular2/core';

@Component({})

exportclassMathComponent{

publicsum(a:number,b:number):number{

returna+b;

Page 211: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

publicdivide(a:number,b:number):number{

returna/b;

}

publicsubtract(a:number,b:number):number{

returna-b;

}

publicmultiply(a:number,b:number):number{

returna*b;

}

}

Finally,hereistheChildComponentcode,whichdoesnothavetheMathComponentproviderdefinedintheprovidersarray:

//child.component.ts

import{Component}from'angular2/core';

import{MathComponent}from'./servicemanager.component';

@Component({

selector:'child-app',

template:'<h1>HelloWorld</h1>'

})

exportclassChildComponent{

obj:MathComponent;

constructor(mathComponent:MathComponent){

this.obj=mathComponent;

}

publicaddNumbers(a:number,b:number){

alert(this.obj.sum(a,b));

}

}

Page 212: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

RoutinginAngularRoutinghasanessentialrolewhenworkingwithlargeapplications.Routingisusedtonavigatetodifferentpages.Routingcanbedefinedinthreesteps:

1. Define@RouteConfigatanycomponentlevel:

@RouteConfig([

{path:'/page1',name:'Page1',component:Page1Component,useAsDefault:

true},

{path:'/page2',name:'Page2',component:Page2Component}]

)

2. Usethe[routerLink]attributeontheanchorHTMLtagandspecifytheroutenameconfiguredin@RouteConfig.

3. Finally,addthe<router-outlet>tagtorenderthepageonthecurrentnavigatedroute.

Thefollowingexamplecontainstwocomponents,Page1ComponentandPage2Component,andthemainAppComponenthasroutingdefinedlikethis:

//app.component.ts

import{Component}from'angular2/core';

import{RouteConfig,ROUTER_DIRECTIVES}from'angular2/router';

import{Page1Component}from'./page1.component';

import{Page2Component}from'./page2.component';

@Component({

selector:"my-app",

template:`{{name}}

<a[routerLink]="['Page2']">Page2</a>

<router-outlet></router-outlet>`,

directives:[ROUTER_DIRECTIVES],

})

@RouteConfig([

{path:'/',name:'Page1',component:Page1Component,useAsDefault:true},

{path:'/page2',name:'Page2',component:Page2Component}]

)

exportclassAppComponent{

}

Intheprecedingcode,firstweimportedtheRouteConfigandROUTER_DIRECTIVESfromangular2/routerandthendefinedtheRouteConfigforpage1andpage2.Intheinlinetemplate,weplacedtheanchortaganddefinedtheroutenameforpage2.Whentheapplicationruns,page1issetasadefaultpageonarootpath/,sothepage1contentwillbedisplayedinplaceoftherouteroutlet.WhentheuserclicksonthePage2link,thepage2contentwillberenderedinthesameplace.

Hereisthecodeofpage1.component.ts:

//page1.component.ts

import{Component}from'angular2/core';

Page 213: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

@Component({

template:'<h1>Page1Content</h1>'

})

exportclassPage1Component{

}

Hereisthecodeofpage2.component.ts:

//page2.component.ts

import{Component}from'angular2/core';

@Component({

template:'<h1>Page2Content</h1>'

})

exportclassPage2Component{

}

Page 214: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Developingato-doapplicationinASP.NETCoreWehavelearnedthecorefeaturesofAngular2andhowtowriteprogramsinTypeScript.Nowit'stimetodevelopasimpleto-doapplicationusingAngular2andASP.NETCore.ASP.NETCoreisthelatestwebdevelopmentplatformfromMicrosoft,whichismoreoptimizedandmodularthanpreviousversionsofASP.NET.Itprovidesanoptiontousethemachine-wide.NETFramework,oranew.NETCorewhichrunsonanapp-by-appbasisandevencontainstheframeworkbinariesinthepublishedwebapplicationfolderitself.WiththenewASP.NETCore,wearenotdependentforrunningourapplicationonIIS,andthereareseveralotherserversprovidedtoruncross-platformusingKestrel.TolearnmoreaboutASP.NETCore,pleaserefertohttp://docs.asp.net.

Wewillgothroughastep-by-steptutorialthatleadstoaworkingto-doapplication.Thefollowingscreenshotshowasnapshotofthemainpage.Oncetheuserlogsin,itwillshowalistofalltheto-doitemsavailable.Usercanaddanewto-doitembyclickingaCreateTodobuttonanddeletingtheexistingoneaswell.Wewillnotbecoveringthesecurityauthenticationandauthorizationmoduleinthischapter,insteadfocusingonhowtouseAngular2withASP.NETCore:

Inthisapplication,wewillhavethreeprojects.TodoWebAppcallstheTodoServiceApp,andCommonisusedbyWebAPI,whichholdstheentitymodels.ThefollowingdiagramshowshowtodevelopthesethreeprojectsandconfigureanduseAngular2:

Page 215: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer
Page 216: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CreatingaCommonprojectCommonprojectsholdtheentitiesthatwillbeusedbytheEntityframeworktocreateadatabase.WewillreferencethisassemblyintheWebAPIprojectatalaterstage:

1. Createa.NETCoreClassLibraryproject:

2. Addanewfolder,Models,andaddaTodoItemclassasfollows:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Threading.Tasks;

namespaceCommon

{

publicclassTodoItem

{

publicintId{get;set;}

publicstringTitle{get;set;}

publicstringDescription{get;set;}

publicDateTimeDueDateTime{get;set;}

publicintUserId{get;set;}

}

}

TheprecedingTodoItemclasscontainstheId(primarykey)andTitle,Description,DueDateTime,andtheUserIDtosaveto-dosforaspecificuser.

Page 217: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CreatingaTodoServiceAppprojectInthisproject,wewillcreateawebAPIthatwillreferencetheCommonprojectwhichcontainstheTodoItemPOCOmodel.Inthisproject,wewillexposeservicesandcreateadatabaserepositorythatwilluseEntityFrameworkCoretoperformCreate,Read,Update,andDelete(CRUD)operationsintheMicrosoftSQLServerdatabase:

1. CreateanewWebAPIproject,choosingASP.NETCoretemplate.WebAPIandASP.NETMVChavebeenmergedintooneunifiedframework,sothereisnoseparateprojecttemplateforWebAPI.Inthiscase,wewillusetheEmptyProjectModelavailableintheASP.NETCoreprojecttemplates.

2. Openproject.jsonandaddareferencetoourCommonassembly:

"dependencies":{

"Microsoft.NETCore.App":{

"version":"1.0.0-rc2-3002702",

"type":"platform"

},

"Microsoft.AspNetCore.Server.IISIntegration":"1.0.0-rc2-final",

"Microsoft.AspNetCore.Server.Kestrel":"1.0.0-rc2-final",

"Common":"1.0.0-*"

}

EnablingMVCinaWebAPIproject

InordertoenabletheMVCproject,wehavetocallAddMvc()intheConfigureServicesmethod,andUseMvc()intheConfiguremethod:

1. AddtheMVCpackageinproject.json:

"Microsoft.AspNetCore.Mvc":"1.0.0-rc2-final"

2. CallAddMvc()fromtheConfigureServicesmethod:

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddMvc();

}

3. Finally,callUseMvc()fromtheConfiguremethod:

publicvoidConfigure(IApplicationBuilderapp)

{

app.UseMvc();

}

InstallingEntityFramework

HerearethestepstoinstallEntityFramework:

1. AddtwoEntityFrameworkassemblies,Microsoft.EntityFrameworkCore.SqlServerandMicrosoft.EntityFrameworkCore.Tools,asshowninthefollowingcode:

Page 218: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

"dependencies":{

"Microsoft.NETCore.App":{

"version":"1.0.0-rc2-3002702",

"type":"platform"

},

"Microsoft.AspNetCore.Server.IISIntegration":"1.0.0-rc2-final",

"Microsoft.AspNetCore.Server.Kestrel":"1.0.0-rc2-final",

"common":"1.0.0-*",

"Microsoft.AspNetCore.Mvc":"1.0.0-rc2-final",

"Microsoft.EntityFrameworkCore.SqlServer":"1.0.0-rc2-final",

"Microsoft.EntityFrameworkCore.Tools":{

"type":"build",

"version":"1.0.0-preview1-final"

}

}

AddingAppSettingstostoreaconnectionstring

ASP.NETCoreprovidesvariousoptionsforstoringapplicationsettings.Thedefaultconfigurationfileisnowappsettings.json,whichstoresthedatainaJSONformat.However,thereareothermethodsavailableaswelltostoredataintheenvironmentvariables,XML,andINIformatsaswell.Inthisproject,wewillstoretheconnectionstringintheappsettings.jsonfile:

1. AddtheASP.NETconfigurationfileappsettings.jsonandspecifytheconnectionstringasfollows:

{

"Data":{

"DefaultConnection":{

"ConnectionString":"DataSource=.;InitialCatalog=tododatabase;

IntegratedSecurity=True;MultiSubnetFailover=False;"

}

}

}

2. Addthefollowingpackagesinproject.json:

"Microsoft.Extensions.Configuration.Json":"1.0.0-rc2-final",

"Microsoft.Extensions.Options.ConfigurationExtensions":"1.0.0-rc2-final",

ConfiguringAppSettingsintheStartupclass

ThenewconfigurationsystemofASP.NETCoreisbasedonSystem.Configuration.Tousesettingsinourproject,wewillinstantiateaConfigurationobjectinourStartupclassandusetheOptionspatterntoaccessindividualsettings.

TheOptionspatternconvertsanyclassintoasettingsclassandthenwecaninjectthatclassintothecontrollersthroughASP.NET'sbuilt-independencyinjection.Throughtheoptionsclass,thedevelopercanaccessthesettingskeysandvalues,asshowninthefollowingsteps:

1. IntheStartupclassconstructor,wewilladdtheappsettings.jsonfileusingthe

Page 219: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ConfigurationBuilderobject.ConfigurationBuilderallowsaprovisiontoadddifferentprovidersandhaveabuildmethodthatbuildstheconfigurationstoresindifferentprovidersandreturnstheIConfigurationRootinstance:

publicStartup()

{

//Setupconfigurationsources.

varbuilder=newConfigurationBuilder()

.AddJsonFile("appsettings.json")

Configuration=builder.Build();

}

publicIConfigurationRootConfiguration{get;set;}

Tip

Ifmultipleprovidershavethesamekeys,thelastonespecifiedintheConfigurationBuilderwillbeused.

2. NowwecanusetheConfigurationpropertytoaccesstheconnectionstring,asfollows:

Configuration["Data:DefaultConnection:ConnectionString"];

AddingdataaccessinWebAPI

Inthissection,wewilladdaTodoContextandTodoRepositoryclasstoperformCRUDoperations:

1. Addanewfolder,DataAccess,andaddtheTodoContextclass,whichwillbederivedfromtheDbContextclass.ThisisthemainTodoContextclassEntityFrameworkusedtocreatethedatabase:

usingCommon;

usingMicrosoft.Data.Entity;

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Threading.Tasks;

namespaceTodoServiceApp.DataAccess

{

publicclassTodoContext:DbContext

{

publicDbSet<TodoItem>TodoItem{get;set;}

}

}

2. WehavetonowoverridetheOnConfiguring()methodandcalltheUseSqlServer()methodoftheDbContextOptionsBuilderobject.TheOnConfiguring()methodiscalledeverytimetheContextobjectisinitializedandconfigurestheoptionsspecified.TheUseSqlServer()methodtakestheconnectionstringthatisdefinedintheappsettings.jsonfile,whichwehaveconfiguredintheStartupclass.Nowwewantto

Page 220: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

injecttheappsettingsobjectintothisclass.Inordertodoso,wewillusetheOptionspattern.Aspertheoptionspattern,weshouldn'tusetheConfigurationpropertywehavedefinedintheStartupclassdirectly,andinsteadwewillcreateacustomPOCOclassthatcontainsthesamekeyswehaveinourappsettingsfileandoverloadthedefaultTodoContextconstructor,whichacceptsIOptions<T>,whereTisourcustomPOCOappsettingsclass.

3. Astheconnectionstringisdefinedinanestedobject,ourDataclasswillbeasfollows:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Threading.Tasks;

namespaceTodoServiceApp

{

publicclassData

{

publicDefaultConnectionDefaultConnection{get;set;}

}

publicclassDefaultConnection{

publicstringConnectionString{get;set;}

}

}

4. IntheStartupclass,wewillcalltheservices.Configure()methodtopopulatethisDataobjectwiththekeysspecifiedintheappsettings.jsonfile,andinjectitintherepositorywewillbecreatingnext.

5. CreateaTodoRepositoryclassthatcontainsanITodoRepositoryinterfaceanditsimplementation,TodoRepository.ThisclasswillusetheTodoContextobjecttoperformdatabaseoperations.HereisthecodesnippetfortheTodoRepositoryclass:

usingCommon;

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Threading.Tasks;

usingTodoServiceApp.DataAccess;

namespaceTodoServiceApp.Repository

{

publicinterfaceITodoRepository

{

voidCreateTodo(TodoItemtodoItem);

voidDeleteTodo(inttodoItemId);

List<TodoItem>GetAllTodos(intuserId);

voidUpdateTodo(TodoItemtodoItem);

}

publicclassTodoRepository:ITodoRepository

{

privateTodoContextcontext;

Page 221: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

publicTodoRepository()

{

context=newTodoContext();

}

publicList<TodoItem>GetAllTodos(intuserId)

{

returncontext.TodoItems.ToList();

}

publicvoidCreateTodo(TodoItemtodoItem)

{

context.TodoItems.Add(todoItem);

context.SaveChanges();

}

publicvoidDeleteTodo(inttodoItemId)

{

varitem=context.TodoItems.Where(i=>i.Id==

todoItemId).FirstOrDefault();

context.Remove(item);

context.SaveChanges();

}

publicvoidUpdateTodo(TodoItemtodoItem)

{

context.Update(todoItem);

context.SaveChanges();

}

}

}

6. IntheStartupclass,addtheEntityFrameworkintheConfigureServices()method,asshownthefollowingcode.OurWebAPIcontrollerswillhaveanoverloadedconstructorthattakestheITodoRepositoryobject.Wewillusetheservices.AddScoped()methodtoinjectTodoRepositorywhereverITodoRepositoryisrequired.Finally,calltheservices.Configure()methodtopopulatetheDataobjectwiththekeysspecifiedintheappsettings.jsonfile:

publicvoidConfigureServices(IServiceCollectionservices)

{

stringconnString=

Configuration["Data:DefaultConnection:ConnectionString"];

services.AddDbContext<TodoContext>(options=>

options.UseSqlServer(connString));

services.AddMvc();

services.AddScoped<ITodoRepository,TodoRepository>();

services.Configure<Data>(Configuration.GetSection("Data"));

}

EnablingCORSintheASP.NETWebAPI

WelearnedaboutCORSinthepreviouschapter;wehavetoenableCORSinourWebAPIproject,sothatfromAngularserviceswecanmakearequesttoaccesstheTodoService

Page 222: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

methods:

1. Callservices.AddCors()intheConfigureServicesmethodintheStartupclass:

services.AddCors(options=>{options.AddPolicy("AllowAllRequests",builder

=>builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());});

2. Callapp.UseCors()intheConfiguremethodinStartupclass:

app.UseCors("AllowAllRequests");

Runningdatabasemigration

WeareusingtheEntityFrameworkCodeFirstmodel,sonowwewanttocreateadatabaseinMicrosoftSQLServer.Todoso,wewillfirstaddtheEntityFrameworktoolsupportintheproject.jsonfileoftheTodoServiceApp,andthenrun.NETCLIcommandstoaddmigrationsandcreatethedatabase:

1. AddMicrosoft.EntityFrameworkCore.Toolsintheproject.jsonfile,asshownhere:

"tools":{

"Microsoft.AspNetCore.Server.IISIntegration.Tools":{

"version":"1.0.0-preview1-final",

"imports":"portable-net45+win8+dnxcore50"

},

"Microsoft.EntityFrameworkCore.Tools":{

"imports":["portable-net451+win8"],

"version":"1.0.0-preview1-final"

}

},

2. Nowwecanruncommands,createmigrations,andupdatethedatabase.3. Tocreatemigrations,gotothecommandpromptandnavigatetotheTodoServiceApp

projectwhereproject.jsonresides.4. Then,rundotnetefmigrationsaddInitial,whereInitialisthenameofthe

migrationcreated.RunningthiscommandwilladdtheMigrationsfolderandaclasscontainingcodeabouttheDDLoperations.

ThefollowingscreenshotshowstheMigrationsfoldercreatedafterrunningtheprecedingcommand,andthecreationofthe20160405115641_Initial.csfilethatcontainstheactualmigrationcodesnippetstoapplyorremovemigrationfromthedatabase:

Page 223: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

5. Tocreateadatabase,weneedtoexecuteanothercommandinthesamefolderwhereproject.jsonresidesintheTodoServiceAppproject:

dotnetefdatabaseupdate–verbose

6. Thiswillcreateadatabase,andwecannowgothrough,addingacontrollertohandledifferentHTTPrequestsandaccessthedatabase.

Creatingacontroller

Followthesestepstocreateacontroller:

1. AddanewControllersfolderandaddaclassnamedTodoController.2. HereisthecodesnippetfortheTodoControllerclass:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Linq;

usingSystem.Threading.Tasks;

usingMicrosoft.AspNetCore.Mvc;

usingCommon;

usingTodoServiceApp.Repository;

namespaceTodoApi.Controllers

{

[Route("api/[controller]")]

publicclassToDoController:Controller

{

ITodoRepositoryrepository;

publicToDoController(ITodoRepositoryrepo)

Page 224: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

{

repository=repo;

}

//GET:api/values

[HttpGet]

publicIEnumerable<string>Get()

{

returnrepository.GetAllTodos();

}

//GETapi/values/5

[HttpGet("{id}")]

publicIEnumerable<TodoItem>Get(intid)

{

returnrepository.GetAllTodos(id);

}

//POSTapi/values

[HttpPost]

publicvoidPost([FromBody]TodoItemvalue)

{

repository.CreateTodo(value);

}

//PUTapi/values/5

[HttpPut("{id}")]

//DELETEapi/values/5

[HttpDelete("{id}")]

publicvoidDelete(intid)

{

repository.DeleteTodo(id);

}

}

}

NowwehavecompletedourTodoServiceproject,sowewilldevelopatodowebapplicationprojectandconfigureAngular2.

Page 225: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CreatingaTodoWebAppprojectWewilldevelopasingle-pageapplicationandusetheMVCviewtorenderitusingAngular2.Thisapplicationwillhaveonemainpagethatlistsalltheto-doitemsforaparticularuser,whereastoaddanewto-doitem,anewpagewillopeninamodaldialogwindow:

1. Tostart,let'screateanemptyprojectusingtheASP.NETCoreprojecttemplateavailableinVisualStudio2015,andnameitTodoWebApp.

2. AddanMVCreferenceinproject.json:

"Microsoft.AspNetCore.Mvc":"1.0.0-rc2-final",

"Microsoft.AspNetCore.StaticFiles":"1.0.0-rc2-final",

3. IntheStartupclass,addtheAddMvc()methodintheConfigureServicesmethodandtheUseMvc()methodintheConfiguremethod.HereisthecodesnippetoftheStartupclass:

namespaceTodoWebApp

{

publicclassStartup

{

//Thismethodgetscalledbytheruntime.Usethismethodtoadd

servicestothecontainer.

//Formoreinformationonhowtoconfigureyourapplication,visit

http://go.microsoft.com/fwlink/?LinkID=398940

publicvoidConfigureServices(IServiceCollectionservices)

{

services.AddMvc();

}

//Thismethodgetscalledbytheruntime.Usethismethodtoconfigure

theHTTPrequestpipeline.

publicvoidConfigure(IApplicationBuilderapp)

{

app.UseStaticFiles();

app.UseMvc(routes=>

{

routes.MapRoute(name:"default",template:"

{controller=Home}/{action=Index}/{id?}");

}

}

ConfiguringAngular2intheTodoWebAppproject

Angular2ispartoftheNodemodule,andwecanaddNodepackagesthroughtheNodePackageManager(NPM)configurationfile,package.json.Inpackage.json,wecanaddpackagesthroughthedevDependenciesnodeandthedependenciesnode.ThedevDependenciesnodeholdsthepackagesthatareusedduringdevelopment,suchasGulp,whichcanbeusedtoconcatenateandminifyJavaScriptandCSSfiles,TypeScriptfordevelopingAngular2components,andrimraftodeletethefiles.Inthedependenciesnode,wewillspecifypackagessuchasangular2,systemjs,reflect-metadata,rxjs,andzone.js,whichwillbeusedwhentheapplicationruns:

1. Addanewpackage.jsonfilefromtheVisualStudioprojecttemplateoptionNPM

Page 226: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ConfigurationFileandaddthefollowingJSONsnippet:

{

"name":"ASP.NET",

"version":"0.0.0",

"dependencies":{

"angular2":"2.0.0-beta.9",

"systemjs":"0.19.24",

"reflect-metadata":"0.1.3",

"rxjs":"5.0.0-beta.2",

"zone.js":"0.6.4"

},

"devDependencies":{

"gulp":"3.8.11",

"typescript":"1.8.7",

}

}

2. VisualStudioautomaticallydownloadsandrestorespackagesspecifiedinthepackage.jsonfile,createsanode_modulesfolderintheprojectitself,andplacesallthepackagesthere.TheNode_modulesfolderisbasicallyhiddenbydefaultinVisualStudio,butcanbemadevisiblebyenablingtheShowAllFilesoption.

Dependencies

Thefollowingisthelistofdependencieswiththeirdescriptions:

angular2:ItistheAngular2package.systemjs:ItprovidesSystem.importtohookupthemainentrypointofAngular.reflect-metadata:ItisaproposaltoadddecoratorstoES7.Throughthis,wecanspecifythemetadatatoourclassinAngular2.rxjs:Itisareactivestreamslibrarythatallowsworkingwithasynchronousdatastreams.zone.js:Itprovidesanexecutioncontextthatpersistsacrossasynchronoustasks.

Developmentdependencies

Thefollowingisthelistofdevelopmentdependencieswiththeirdescriptions:

gulp:Usedtocopythefilestothewwwrootfoldertypescript:UsedtowriteprogramsinTypeScript

ConfiguringTypeScript

ToconfigureTypeScript,performthefollowingsteps:

1. AddtheScriptsfolderwherealltheTypeScriptfilesreside.InthecurrentversionofASP.NET,thereisarestrictiononnamingthisfolderScripts,anditshouldbeaddedintherootoftheproject;otherwise,TypeScriptfileswillnotbetranspiledtoJavaScriptfiles.

2. AfteraddingtheScriptsfolder,addtheTypeScriptconfigurationfile(tsconfig.json)andaddthefollowingconfigurationtoit:

{

Page 227: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

"compilerOptions":{

"noImplicitAny":false,

"noEmitOnError":true,

"removeComments":false,

"sourceMap":true,

"target":"es5",

"module":"commonjs",

"moduleResolution":"node",

"outDir":"../wwwroot/todosapp",

"mapRoot":"../scripts",

"experimentalDecorators":true,

"emitDecoratorMetadata":true

},

"exclude":[

"node_modules",

"wwwroot"

]

}

ConfigurationsdefinedwithinthecompilerOptionsnodeareusedbyVisualStudiowhenyoubuildyourproject.Basedontheconfiguration,theJavaScriptfilesaregeneratedandstoredintheoutputdirectory.Thefollowingtableshowsthedescriptionofeachpropertyspecifiedintheprecedingcode:

Compileroptions Description

noImplicitAny Iftrue,thenitwarnstheexpressionimpliedwithanytype

noEmitOnErrorIftrue,itdoesnotgenerateJavaScriptifanyerrorsarepresentintheTypeScript

removeComments Ittrue,removescommentswhengeneratingJavaScriptfiles

sourceMap Iftrue,thengeneratesthecorrespondingmapfile

Target SetsthetargetECMAscriptversion,suchasES5

modulezSpecifiesthemodulethatgeneratedthecode,suchascommonjs,AMD,orsystem

moduleResolution Specifiesthemoduleresolutionstrategy,suchasnode

Page 228: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

outDir PathwherethegeneratedJavaScriptfileswillbedumped

mapRoot Pathwherethemapfileswillbelocated

experimentalDecorators Iftrue,itenablessupportforES7experimentaldecorators

emitDecoratorMetadataIftrue,itemitsdesign-typemetadatafordecoratordeclarationsinsource

ConfiguringGulp

Inthissection,wewilluseGulptominifytheJavaScriptgeneratedbytheTypeScriptcompiler:

1. AddtheGulpconfigurationfile,gulpfile.js.2. Gulpisusedtoruntasks,andVisualStudioprovidesataskrunnerwindowthatlistsall

thetasksspecifiedinthegulpfile.js,andalsoallowsustobindthosetaskstobuildevents.

3. Let'saddthefollowingscriptingulpfile.js:

///<bindingClean='clean'/>

"usestrict";

vargulp=require("gulp")

varpaths={

webroot:"./wwwroot/"

};

varconfig={

libBase:'node_modules',

lib:[

require.resolve('systemjs/dist/system.js'),

require.resolve('systemjs/dist/system.src.js'),

require.resolve('systemjs/dist/system-polyfills.js'),

require.resolve('angular2/bundles/angular2.dev.js'),

require.resolve('angular2/bundles/angular2-polyfills.js'),

require.resolve('angular2/bundles/router.dev.js'),

require.resolve('angular2/bundles/http.dev.js'),

require.resolve('angular2/bundles/http.js'),

require.resolve('angular2/bundles/angular2'),

require.resolve('rxjs/bundles/Rx.js')

]

};

gulp.task('build.lib',function(){

returngulp.src(config.lib,{base:config.libBase})

.pipe(gulp.dest(paths.webroot+'lib'));

});

Page 229: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Intheprecedinggulpfile.js,wehavefirstdeclaredtheobjectsofGulp.Thenthepathsvariabledefinestherootfolder(./wwwroot)forstaticfiles.InASP.NETCore,allthestaticfilesshouldresideunderthewwwrootfolder;otherwise,theycannotbeaccessed.NowweneedtocopytheAngularandotherrelatedJavaScriptfilesintothewwwrootfolder.Therefore,wehaveaddedthetaskbuild.libthatcallsgulp.src()andchainsthegulp.dest()methodtocopythefilesfromthenode_modules/*foldertothewwwroot/libfolder.Hereisthescreenshotofthewwwrootfolder,whichcreatesthelibfolderwhenyouruntheprecedingsteps:

Tip

TaskscanrunthroughthetaskrunnerwindowinVisualStudio.

AddingAngularcomponents

WehaveinstalledtheAngularpackagesandconfiguredGulptocopythepackagedJavaScriptfilestothewwwrootfolder.NowwewilladdAngularcomponentstodefineourmainapplicationselectorandrendertheASP.NETpageinsideit:

1. IntheScriptsfolder,createtwofolders,appandservices.Theappfolderholdsthecomponentsthatwewilluseintheview,whereastheservicesfolderholdstheservicesthatwillbeusedtocalltheWebAPImethods.

2. AddamainTypeScriptfile,whichwillbootstrapthemainTodoAppComponent.Hereisthe

Page 230: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

codeofmain.ts:

//main.ts

import{bootstrap}from'angular2/platform/browser';

import{TodoAppComponent}from'./apps/todoapp.component';

import{HTTP_PROVIDERS}from'angular2/http';

import'rxjs/add/operator/map';

bootstrap(TodoAppComponent,[HTTP_PROVIDERS]);

Intheprecedingcodesnippet,wehaveaddedabootstrapcomponenttobootstrapourfirstTodoAppComponent.HTTP_PROVIDERScontainsalltheproviderstomakeanyHTTPrequest.Itisprovidedwhilebootstrapping,sotheTodoAppComponentorthechainofcomponentsinthefollowinghierarchycandoHTTP-basedoperations.Rxjs/add/operator/mapisadependentpackageforHTTP_PROVIDERS,whichneedstobeaddedaswell:

1. AddanewTypeScriptfileandnameittodoapp.component.ts.2. AddthefollowingcodesnippetforTodoAppComponent.Inordertofirsttestwhether

everythingisconfiguredproperly,wewillsimplyaddasampleheadingtagthatshowsHelloWorld:

//todoapp.component.ts

///<referencepath="../../node_modules/angular2/typings/browser.d.ts"/>

import{Component}from'angular2/core';

@Component({

selector:'todo',

template:'<h1>{{message}}</h1>'

})

exportclassTodoAppComponent{

message:string="HelloWorld";

}

3. Nowwewilladdtwofiles,importer.jsandangular_config.js.importer.jscallsSystem.importandpointstothemainfilethatbootstrapstheapplicationcomponent.angular_config.jsholdstheconfigurationpropertytoallowdefaultJavaScriptextensionstobesettotrue.

Hereisthecodesnippetforimporter.js:

System.import('todosapp/Main')

.then(null,console.error.bind(console));

Hereisthecodeforangular_config.js:

System.config({defaultJSExtensions:true});

4. NowweneedtoaddtheMVClayoutpageandaddallthescripts.Addthefollowingscripts:

Page 231: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

//_Layout.cshtml

<environmentnames="Development">

<linkrel="stylesheet"href="~/lib/bootstrap/dist/css/bootstrap.css"/>

<linkrel="stylesheet"href="~/css/site.css"/>

<scriptsrc="~/lib/angular2/bundles/angular2-polyfills.js"></script>

<scriptsrc="~/lib/systemjs/dist/system.js"></script>

<scriptsrc="~/lib/custom/angular_config.js"></script>

<scriptsrc="~/lib/rxjs/bundles/Rx.js"></script>

<scriptsrc="~/lib/angular2/bundles/angular2.dev.js"></script>

<scriptsrc="~/lib/angular2/bundles/router.dev.js"></script>

<scriptsrc="~/lib/angular2/bundles/http.js"></script>

<scriptsrc="~/lib/custom/importer.js"></script>

<scriptsrc="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"

asp-fallback-src="~/lib/jquery/dist/jquery.min.js"

asp-fallback-test="window.jQuery">

</script>

<script

src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/bootstrap.min.js"

asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"

asp-fallback-test="window.jQuery&&window.jQuery.fn&&

window.jQuery.fn.modal">

</script>

</environment>

5. Nowlet'saddHomeControllerandviewIndex.cshtml.6. InIndex.cshtml,addtheto-doselectortodo-app:

@{

ViewData["Title"]="TodoApplications";

Layout="~/Views/Shared/_Layout.cshtml";

}

<divid="myCarousel"class="container"data-ride="carousel"data-

interval="6000">

<todo-app>Loading...</todo-app>

</div>

7. BuildandruntheapplicationanditwillshowHelloWorld:

Page 232: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Addingtheto-doservicecomponent

WewillnowaddthecomponentsinsidetheservicesfolderthatwillberesponsibleforgettingdatabycallingtheTodoservice:

1. Firstofall,addtheBaseServicecomponent,whichcontainsbaseURL.AlltheservicecomponentswillderivefromBaseServicesotheycanusethebaseURLpropertyformakingAjaxrequests.AddanewTypeScriptfileandnameitbaseservice.component.ts.Hereisthecodesnippetforbaseservice.component.ts:

//baseservice.component.ts

import{Component}from'angular2/core';

import{Http,Headers}from'angular2/http';

@Component({})

exportclassBaseService{

baseUrl:string;

constructor(){

this.baseUrl="http://localhost:7105/api/";

}

}

2. Nowaddtodoservice.component.ts,whichcontainsthemethodstogetallto-doitems,addanewto-doitem,anddeleteanexistingto-doitem.HereisthecodesnippetforTodoService:

//todoservice.component.ts

import{Component}from'angular2/core';

import{Http,Headers}from'angular2/http';

import{BaseService}from'../services/baseservice.component';

@Component({

providers:[TodoService]

})

exportclassTodoServiceextendsBaseService{

constructor(privatehttp:Http){

super();

}

publicgetTodoItems(){

returnthis.http.get(this.baseUrl+'todo/1');

}

publiccreateTodo(item){

varpath=this.baseUrl+'todo';

constheaders=newHeaders({'Content-Type':'application/json'});

returnthis.http.post(path,JSON.stringify(item),{headers:headers});

}

publicdeleteTodo(itemId){

varpath=this.baseUrl+'todo';

returnthis.http.delete(path+"/"+itemId);

}

}

Page 233: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Intheprecedingcode,weimportedthehttpcomponentandinjectedtheconstructor.Thehttpobjectprovidesmethodssuchasget,post,put,anddeletetoread,insert,update,anddeleteoperations.InourTodoServiceWebAPIproject,wehavethesemethodsavailable,whichwecallasshownintheprecedingcode.Eachmethodreturnsapromise,andinthecallingcomponentswewillchecktheresultandtakeappropriateactions.

Addingato-doviewcomponent

Wehavealreadyaddedtodoapp.component.tsintheprecedingsteptocheckwhetherAngularisconfiguredproperly.NowwewillmodifythesamecomponenttocalltheTodoServiceComponentanddisplaytheresultsonawebpage.

HereisthecodesnippetforTodoApp.Component.ts:

//todoApp.component.ts

///<referencepath="../../node_modules/angular2/typings/browser.d.ts"/>

import{Component}from'angular2/core';

import{Http,Response}from'angular2/http';

import{CreateTodoComponent}from'../apps/createTodo.component';

import{TodoService}from'../services/todoservice.component';

@Component({

selector:'todo-app',

templateUrl:'Todo',

directives:[CreateTodoComponent],

providers:[TodoService]

})

exportclassTodoAppComponent{

//membervariables

todos=[

];

//constructor

constructor(privatehttp:Http,privatetodoService:TodoService){

}

//PageInitializedEventHandler

ngOnInit(){

this.getTodoItems();

}

//MemberFunctions

getTodoItems(){

this.todoService.getTodoItems().map((res:Response)=>res.json())

.subscribe(data=>{

this.todos=data

this.parseDate();

},

err=>console.log(err),

()=>console.log('done')

);

}

deleteTodoItem(itemID){

varr=confirm("Areyousuretodeletethisitem");

Page 234: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

if(r==true){

this.todoService.deleteTodo(itemID)

.map(r=>r.json())

.subscribe(result=>{

alert("recorddeleted");

});

}

this.getTodoItems();

}

parseDate(){

for(lettodoofthis.todos){

lettodoDate=newDate(todo.DueDateTime);

todo.DueDateTime=todoDate;

}

}

handleRefresh(args){

this.getTodoItems();

}

}

InTodoAppComponent,wehavefirstaddedtheCreateTodoComponentdirectivewewillbeusingintheTodo/Index.cshtmlpageinalaterstep.WehaveimplementedthengOnInit()eventhandlerthatgetsthelistofto-dosandboundittothetodosarrayobject.ThegetTodoItems()methodcallstheTodoServicetogetthelistofto-doitems,whereasdeleteTodoItem()isusedtodeletetheitem.

EveryrequestinAngularreturnsanObservableresponseobjectthatprovidesamapmethodtotellAngulartoparsetheresponseinaspecificformat.ThemapalsoreturnstheObservableobject,whichcanbeusedtosubscribetothedataonceitisparsedintotheJSONformat,asinourcase.Finally,wehavecalledthesubscribemethodandsenttheJSONresponsedatatothetodosarray.Tohandleerrors,wecanchainthecallwiththeerrmethod.Theanonymousexpression()methodisinvokedineverycall,irrespectiveoftheresponsestatus.Thatmeanswhethertheresultisasuccessoranerror,thecodedefinedundertheanonymousexpression()methodwillbeexecuted.

Forcreatingnewto-dos,wewillcreateanotherCreateTodoComponentlater,whichwillcallthehandleRefresh()methodthroughtheOutputseventtorefreshthelistandreflectthenewlyaddeditemonthemainpage.

Creatingthemainto-dopage

WehavecreatedtheAngularcomponentsthatwewilluseintheMVCview.WehavealreadybootstrappedtheAngularcomponentsintheprevioussectionandplacedthe<todo-app>tagintheHome/Index.cshtmlpage,whichisthelandingpageofourapplication.Next,wewillcreateacustomtaghelper,thenaddaTodoController,andusethistaghelperintheindexpage.

Creatingacustomto-dotaghelper

Page 235: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Onthemainpage,wewilllistalltheto-doitemsforaparticularuser.Forthis,wewillcreateacustomtaghelperinASP.NET:

Performthefollowingstepstocreatethistaghelper:

1. CreateanewcontrolsfolderintherootoftheTodoWebAppprojectandaddaTodoTagHelperclass.HereisthecodeforTodoTagHelper,whichusesAngular2ngControltobindvaluesfromAngularTodoAppComponenttotheform:

[HtmlTargetElement("todo")]

publicclassTodoTagHelper:TagHelper

{

publicoverridevoidProcess(TagHelperContextcontext,TagHelperOutput

output)

{

stringtodo="<divclass='thumbnail'><divclass='caption'><nav

class='navnavbar-inverse'role='navigation'></nav>";

todo+="<labelclass='date'>{{todo.DueDateTime|date:'short'}}

</label><imgsrc='images/delete.png'(click)=deleteTodoItem(todo.Id)/>";

todo+="<h4><ahref='#'>{{todo.Title}}</a></h4>";

todo+="<textareareadonlyclass='form-control'style='resize:none;'

rows='4'cols='28'>{{todo.Description}}</textarea></div></div>";

output.Content.AppendHtml(todo);

}

}

2. Addthetaghelperin_ViewImports.cshtml:

@addTagHelper"*,TodoWebApp"

Addingato-doMVCcontroller

AddTodoControllerintheTodoWebAppprojectandspecifytwomethodsfortheindexview,whichisthemainviewthatdisplaysalltheitemsandcreatesanewto-doitem:

usingSystem.Linq;

Page 236: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

usingMicrosoft.AspNetCore.Mvc;

usingTodoNotes.Models;

namespaceTodoNotes.Controllers

{

publicclassTodoController:Controller

{

publicTodoController()

{

_context=context;

}

//GET:Todo

publicIActionResultIndex()

{

returnView();

}

//GET:Todo/Create

publicIActionResultCreate()

{

returnView();

}

}

GeneratingviewsfortheTodoControlleractionmethods

GenerateviewsfortheprecedingactionmethodsIndexandCreate.

HereisthecodesnippetforTodo/Index.cshtml:

@{

Layout=null;

}

<divclass="col-md-3">

<pclass="lead">ToDoItems</p>

<divclass="list-group">

<h4>

<ahref="#">WanttoaddnewTodo?</a>

</h4>

<p>Clickonthebuttonbelow</p>

<divclass="col-md-3">

<aclass="btnbtn-primary"data-toggle="modal"data-

target="#todoModal">CreateTodo</a>

</div>

</div>

</div>

<divid="todoModal"class="modalfade"role="dialog">

<divclass="modal-dialog">

<!--Modalcontent-->

<divclass="modal-content">

<divclass="modal-header">

<buttontype="button"class="close"data-dismiss="modal">&times;</button>

<h4class="modal-title">InsertTodo</h4>

Page 237: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

</div>

<divclass="modal-body">

<createTodo(refreshTodos)="handleRefresh($event)"></createTodo>

</div>

</div>

</div>

</div>

<divclass="col-md-9">

<divclass="row">

<divclass="col-sm-4col-lg-4col-md-4"*ngFor="#todooftodos">

<todo></todo>

</div>

</div>

</div>

IntheprecedingHTMLmarkup,wehavefirstdefinedabuttonthatopensupamodaldialog,todoModal.InthetodoModaldialogmarkup,wehaveusedthecreateTododirective,whichisdefinedinthetodoapp.component.tsfileassociatedwiththispage,andthelinkactuallypointstotheTodo/CreateMVCview,whichwillberenderedattheplaceofrouter-outlet.Withthecombinationoftherouterlinkandtherouteroutlet,wecanrenderthetemplate.Intodoapp.component.ts,wewillseehowwecanuseroutinginAngular.Finally,wehaveusedthecustomtaghelper<todo>todisplayeachitemavailableintheto-dolist.

DevelopingtheCreateTodocomponent

Inthissection,wewilladdtheAngularcomponentandnameitCreateTodoComponent.ThisisneededbecausewewillbeopeninganewMVCviewinamodaldialogthroughacustomcreateTodoselector,andCreateTodoComponenthasamethodtosaveanewto-dointhedatabase,asshowninthefollowingcode.

Addanewcreatetodo.component.tsundertheScripts>appsfolder,andthenaddthefollowingcodesnippet:

//createtodo.component.ts

///<referencepath="../../node_modules/angular2/typings/browser.d.ts"/>

import{Component}from'angular2/core';

import{Http,Response}from'angular2/http';

import{FormBuilder,Validators}from'angular2/common';

import{TodoService}from'../services/todoservice.component';

@Component({

selector:'createTodo',

templateUrl:'Todo/Create'

})

exportclassCreateTodoComponent{

@Output()refreshTodos=newEventEmitter();

addTodoForm:any;

Page 238: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

constructor(fb:FormBuilder,privatetodoService:TodoService){

this.addTodoForm=fb.group({

title:["",Validators.required],

description:["",Validators.required],

dueDateTime:["",Validators.required]

});

}

addTodoItem():void{

this.todoService.createTodo(this.addTodoForm.value)

.map(r=>r.json())

.subscribe(result=>{});

this.refreshTodos.next([]);

alert("Recordaddedsuccessfully");

}

}

Intheprecedingcodesnippet,wehaveimportedtheHttpandResponseobjectstohandletheresponsereceivedfromTodoService.Inthe@Componentannotation,wehavedefinedtheselectorthatisusedintheparentTodoAppComponentcomponenttorendertheCreateTodoviewinsidethemodaldialog.

FormBuilderandValidatorareusedtodefinepropertieswithspecificvalidatorsthatcanbeboundtotheHTMLformusingthengControldirective.Lastly,wehavetheaddTodoItemmethod,whichwillbeinvokedonformsubmissionandmakeato-doentryinthedatabasebycallingTodoService.

Nowlet'saddthefollowingcodeinCreate.cshtml:

@{

Layout=null;

}

<form[ngFormModel]="addTodoForm"(submit)="addTodoItem($event)"

class="container">

<divclass="form-horizontal">

<divclass="form-group">

<labelclass="col-md-2control-label">Title</label>

<divclass="col-md-10">

<inputngControl="title"class="form-control"id="Title"

placeholder="EnterTodoTitle"[(ngModel)]="title"/>

</div>

</div>

<divclass="form-group">

<labelclass="col-md-2control-label">Description</label>

<divclass="col-md-10">

<textareangControl="description"class="form-control"

placeholder="EnterDescription"></textarea>

{{description}}

</div>

</div>

<divclass="form-group">

<labelclass="col-md-2control-label">DueDate</label>

<divclass="col-md-10">

Page 239: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<inputngControl="dueDateTime"class="form-control"type="datetime-local"

placeholder="EnterDueDate"/>

</div>

</div>

<divclass="form-group">

<divclass="col-md-offset-2col-md-10">

<inputtype="submit"value="Create"class="btnbtn-primary"/>

</div>

</div>

</div>

</form>

@sectionScripts{

<scriptsrc="~/lib/jquery/dist/jquery.min.js"></script>

<scriptsrc="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>

<scriptsrc="~/lib/jquery-validation-

unobtrusive/jquery.validate.unobtrusive.min.js"></script>

}

Intheprecedingcodesnippet,wehavesetthengFormModeltothemodelwedefinedinthecreatetodo.component.tsandthesubmitform,andwearecallingtheaddTodoItemmethod,whichsendsallthevaluesboundwiththengControldirective.ngControlisanewdirectiveintroducedinAngular2thatprovidesunidirectionalbinding.Withforms,ngControlnotonlybindsthevalue,butalsotracksthestateofthecontrol.Ifthevalueisinvalid,itupdatesthecontrolwithspecialCSSclassestotelltheuserthatthevalueisinvalid.

Page 240: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryInthischapter,welearnedaboutthecorecomponentsofTypeScriptandwritingprogramsusingTypeScript.WealsolearnedthecorefundamentalsandconceptsoftheAngular2frameworkanddevelopedasimpleto-doapplicationusingASP.NETCore,Angular2,MVC6forWebAPI,andEntityFrameworkCorefordataaccessproviders.Inthenextchapter,wewilllearnaboutWindowsJavaScriptLibrary(WinJS),developedbyMicrosoft,andseehowwecanaccessWindowsruntimefeatures,changetheappearanceofHTMLcontrols,andotheroptionsavailableinthislibrary.

Page 241: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter6.ExploringtheWinJSLibraryWebdevelopmenthasledtorevolutionaryexperiences.Withframeworkslikebootstrap,material,andothers,wearenowabletorunwebapplicationsattheirbestondifferentscreensizesandadjusttheircontentaccordingly.Developerstargetwebapplicationstorunondifferentplatformsprovidingaconsistentexperiencetotheircustomers.Forexample,anywebapplicationusingbootstrapandotherframeworkscanrunonabrowser,tablet,andamobiledeviceprovidingthebestuserexperienceeverimagined.Withthesebenefits,newprospectswereintroducedandallowwebapplicationstotargetdifferentdevicesbringingtheneedforaccessingclient-sidedevice-specificfeaturesandlayoutsaswell.Withtheserevolutionaryexperiences,companiesstartedbringingJavaScript-basedlibrariesthatnotonlychangedthelookandfeeloftheapplicationsrunningondevicesbutalsoalloweddeveloperstousedevice-specificfeatureslikesendingtoastnotifications,accessingthecameratouploadpictures,andsoon,leveraginguserexperience.

Page 242: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

IntroductiontoWinJSWindowsJavaScript(WinJS)libraryisanopensourceJavaScriptlibrarydevelopedbyMicrosoft.ItwasreleasedinApril2014duringtheMicrosoftbuildconferenceandwithWindows10,Microsoftofficiallyreleasedversion4.0.Currentlyit'sopensourceandunderanApache2.0license.

ItwasinitiallytargetedforWindowsstoreappsthatwerebasedonJavaScript,CSS,andHTMLbutlatersupportedinmodernbrowsersaswell.TodaydeveloperscandevelopmobileapplicationsforanyplatformincludingWindowsapps,Androidapps,andiOSappsusingJavaScript,CSS,andHTMLandtheycanusethislibrarytotransformtheuserinterface(UI)toanativemobileinterfacewiththeprovisionofaccessingfeaturesoftheWindowsruntime.TheWinJSlibraryexposesnotonlytheWindowsruntimemodulesbutalsoprovidesWindowsUIcontrolsetupforuseinwebapplications.WinJSprovidesWindowsruntimefeaturesliketheclassesandruntimecomponentsandtheycanbeaccessedthroughJavaScriptcode.Userscanbuildappsthataccessdevicefeatureslikethecamera,storage,geolocations,filesystems,andstyleapplicationsthatgivethebestuserexperience.Italsoprovidesalayerofsecuritywhichkeepsthedevicefeaturessafeandprotectsthemfrommaliciousattacks.Asfarasbrowsercompatibilityisconcerned,allthemodernbrowsersincludingMicrosoftEdge,GoogleChrome,andotherssupportthislibrary.ThebasicadvantageisthatnowwebdeveloperscanbuildWindowsstoreapplicationsusingWinJScontrolssuiteandlibrarytouseWindowsruntimefeatures.Moreover,MicrosofthasalsoempoweredWinJSlibrarytointegratewithpopularclient-sideframeworkslikeAngularJS,Knockout,Ember,andBackboneandyoucanuseWinJSdirectivesinyourHTMLwithothercontrolsdirectivesanditworksasexpected.

Page 243: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WinJSfeaturesWinJSisnotonlydesignedtoserveuniversalwindowsappsthatarebasedonHTMLandJavaScriptbutageneralizedJavaScriptlibrarythatcanbeusedwithwebapplicationsaswell.WinJSbringsvariousfeaturesthatwewilldiscussinthefollowingsection.

JavaScriptcodingandlanguagepatterns

WinJSprovidesthecodingpatternofdefiningcustomnamespacesandclassesperformingbindingimplementationsandpromises.

Stylesheets

Itprovidestwostylesheets,namelyUI-darkandUI-light,whichcanbeusedwithHTMLelementstogiveaparticularWindowsappathemedappearance.Also,itallowsyoutohandledifferentscreensizesandorientationlikelandscapeandportrait.

Windowsruntimeaccess

Wecanaccessthewindowsruntimefeatureslikefilesystem,camera,geo-location,andotherswhichareapplicablethroughthenativeapplicationAPI.

Security

Withtheprovisionofenablingwindowsruntimefeatures,WinJSalsorestrictstheaccesstosensitivedataonthedevice.

Appmodel

AppmodelofferseventsinitiatedbyaWindowsapplicationandcanberegisteredinourJavaScripttodoaspecificoperation.Forexample,suspend,resume,andinitializationaresomeusefuleventswecanusetohandlespecifictasksthroughregisteringtheminWinJS.

Databinding

JustlikeotherframeworkslikeAngularJS,KnockOut,andsoon,WinJSalsoprovidesspecificdatabindingdirectivesandsyntaxthatisusedtobindHTMLcontrolswiththedatasuppliedorthatexistinyourJavaScriptcode.

Controls

WinJSprovidesspecificcontrolsapartfromtheextendedattributesonHTMLelements.ThesecontrolsareavailableinthenativeWindowsappsprojectandwithWinJSwecanusetheminourHTMLpagetobringthesameexperience.

Utilities

WinJSprovidesseveralutilitiestoperformlocalization,animations,andDOMselectors.

Page 244: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UsageofWinJSMicrosofthasdevelopedvariousapplicationsusingWinJSlibrary.ApplicationslikeSkype,Store,Weather,News,andothersarealldevelopedinHTML,CSS,andJavaScriptusingWinJSlibrary.ThemoderneraofwebdevelopmentmadeJavaScriptacoreframeworkofdevelopingresponsiveandrichapplicationsthatrunonanyplatformandonanydevice.ThisleadMicrosofttoinvestheavilyonWinJSandtomakethislibraryusefulforwebdeveloperswhowanttocreateWindowsappsoruseWindowsplatformfeaturesfromwebapplications.WiththereleaseofUniversalWindowsPlatform(UWP),MicrosoftreleasedthenewUniversalAppPlatform(UAP),asupersetoftheWinRTplatformusedbyWindows8applications.WithUWPthereisanewHostedappconceptintroduced,thatallowsanywebapplicationtoconvertintotheWindowsappwithaveryminimumsetofconfigurationproperties.

Page 245: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AddingtheWinJSlibraryintheASP.NETapplicationWinJScanbeaddedthroughNodePackageManager(NPM),NuGet,andbyreferencingaCDN.ThisdependsonwhetheryouwanttokeepthefileslocalontheserverorasreferencefromCDN.

Page 246: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CDNHereistheCDNlibrarythatcontainsJavaScriptandCSSfilesthatyoucanaddinyourapplication:https://cdnjs.com/libraries/winjs.

Page 247: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

NPMToinstallitwithNPMyoucanrunnpminstallwinjsorjustaddthewinjspackageinthepackage.jsonfilewhenworkingintheASP.NETcoreapplication.

Page 248: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

NuGetToinstallitviaNuGetyoucanaddtheWinJSpackagethroughtheNuGetpackagemanagerconsoleorjustrunthefollowingcommandintheASP.NETapplication:

Install-PackageWinJs

TheWinJSpackagecomeswithasetofJavaScriptfilesandtheCSSstylesheetsfordarkerorlighterUI.Thefollowingtabledefinesthefilesandtheirusage:

File Type Usage

Base.js JavaScript ThisisacoremoduleanditisusedbyUI.jstoprovideWindowsruntimefeatures

UI.js JavaScript ContainsUIcontrols

WinJS.intellisense.js JavaScript ProvideintellisensewhenusingWinJScomponentsinJavaScript

ui-dark.css CSS StylesheetfordarkerUItheme

ui-light.css CSS StylesheetforlighterUItheme

Page 249: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

GettingstartedwithWinJSMicrosofthasprovidedcertaintemplatesinVisualStudiotodevelopstoreapplicationsusingJavaScriptandHTML,ontheotherhand,wecanalsoadditinourASP.NETapplicationtobringcertainfunctionalitiesofWindowsruntimefeaturesorchangingalookandfeelaccordingly.

Page 250: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UsingWinJSintheASP.NETapplicationYoucanstartusingWinJSbyaddingtheJavaScripttouseWindowsruntimefeaturesandCSStomakeUIasWindowsapplications.IntheASP.NETwebapplicationyoucanaddthepackagethroughNPMbymakinganentry,asfollows:

Onsavingthefile,thepackagewillbedownloadedautomaticallyinVisualStudio2015underthenode_modules\npmfolder.

HereisascreenshotofthefolderstheWinJSlibrarycontains.JScontainswinjsmodules,css,andfontsthatcanbeusedtochangeUIlookandfeel:

YoucanuseGulp.jstocopythecssandjsfilestothewwwrootfolderandreferencethemonthepage,wecanaddthefollowingsamplecodethatdisplaystheYouhaveclicked!textonabuttonclickevent:

<!DOCTYPEhtml>

<html>

<head>

<metacharset="utf-8"/>

<title></title>

<scriptsrc="lib/winjs/js/base.js"></script>

<scriptsrc="lib/winjs/js/ui.js"></script>

<scriptsrc="lib/winjs/js/winjs.intellisense-setup.js"></script>

<scriptsrc="lib/winjs/js/winjs.intellisense.js"></script>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.js"></script>

<linkrel="stylesheet"href="lib/winjs/css/ui-dark.css"/>

</head>

<body>

<divclass="win-container">

<buttonclass="win-button"id="btn">Show</button>

Page 251: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<spanid="txtMessage"></span>

</div>

<script>

(function(){

WinJS.UI.processAll().done(function(){

$('#btn').click(function(){

$('#txtMessage').text("Youhaveclicked!");

});

});

})();

</script>

</body>

</html>

Thefollowingistheoutput:

Onpageload,thefunctionwillbeexecutedthatregisterstheclickeventforthebuttonwhenalltheWinJScontrolsareprocessed.TheWinJS.UI.processAll()methodparseswholedocumentobjectmodel(DOM)andsearchesfortheWinJScontrolstoprocessandreturnapromiseafterthebindingisdoneforallthecontrols.

Underthehood,WinJS.UI.processAll()onlyprocessesthosecontrolswhichhavetheisDeclarativeControlContainerpropertysetastrue.ThistellsWinJSwhichcontrolsneedtobeboundwiththeWinJSlibrary.IfyouareusingcustomcontrolsthenyouneedtospecifythisisDeclarativeControlContainerpropertysoitcanbeprocessedbyWinJS.

EventscanberegisteredthroughdeclarativebindingorbyregisteringaneventfromJavaScript.IntheprecedingcodewehaveregisteredthebuttonclickeventthroughJavaScripthowever;declarativelyyoucanalsosettheeventandcallsomeJavaScriptfunctionsthatcanbeinvokedwhenthebuttonisclicked.

Page 252: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ExistingWindowsapptemplateinVisualStudioWindowsappscanbedevelopedeitherusingtheXAMLandC#orbyusinganHTML,CSS,andJavaScriptprojecttemplate.VisualStudioprovidescertaintemplatesforboththemodelsandautoconfigurestheWinJSlibrarytostartaddingfeaturesinyourapplicationinsteadofaddingpackagesandconfigurationsforeachprojectmanually.YoucanaddthenewprojectformwiththefollowingoptionsinVisualStudio2015.Asshowninthefollowingscreenshot:

ThistemplateaddsalltherelatedCSS,JavaScript,andrelatedimagesthatWinJSprovidesandalsoaddsthedefault.jsfilethatcontainsthewinJs.ProcessAll()functiontobindtheHTMLelementswithWinJSlibrary.Thefollowingisthedefault.htmlpagesnippetthatcontainstheWinJSlibrariesanddefault.js:

<!DOCTYPEhtml>

<html>

<head>

<metacharset="utf-8"/>

<title>App1</title>

<!--WinJSreferences-->

<linkhref="WinJS/css/ui-dark.css"rel="stylesheet"/>

<scriptsrc="WinJS/js/base.js"></script>

<scriptsrc="WinJS/js/ui.js"></script>

<!--App1references-->

<linkhref="/css/default.css"rel="stylesheet"/>

Page 253: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<scriptsrc="/js/default.js"></script>

</head>

<bodyclass="win-type-body">

<p>Contentgoeshere</p>

</body>

</html>

Andhereisthecodesnippetfordefault.js:

(function(){

"usestrict";

varapp=WinJS.Application;

varactivation=Windows.ApplicationModel.Activation;

app.onactivated=function(args){

if(args.detail.kind===activation.ActivationKind.launch){

if(args.detail.previousExecutionState!==

activation.ApplicationExecutionState.terminated){

}else{

}

args.setPromise(WinJS.UI.processAll());

}

};

app.oncheckpoint=function(args){

};

app.start();

})();

Page 254: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ExploringWinJScorefundamentalsBeforeusingWinJSlibraryinanyoftheprojects,itisbesttoknowthecoreconceptsthathelpustowritequalityprogramsandusethebestofwhatthelibraryoffers.

Page 255: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ClassesandnamespacesThroughWinJSwecancreateclassesandnamespacewithsomespecialsyntax.ThisisprovidedintheWinJSlibrarytohandlecomplexscenarios.Asweknow,classesandnamespacesarethefeaturesofECMAScript6,butunfortunatelynoneofthebrowsershaveproperimplementationyet.However,withWinJSwecandefineclassesandnamespacesandit'sausefuloptiontousethemwhereneeded.

DefiningclassesinWinJS

ClassesinWinJScanbedefinedthroughtheWinJS.Class.define()method.HereisthesamplecodeofaclassinWinJS:

<script>

varLogger=WinJS.Class.define(function(value){

//constructor

console.log("Constructorisexecuting,valuepassedis:"+value);

}

);

//InitializingLoggerclassobject

varlog=newLogger("HelloWorld");

</script>

IntheprecedingcodewehavecreatedaclassnamedLogger,wherethefirstfunction'sparameteristheconstructor,secondisforanyinstanceMemberslikepropertiesandmethodsandthirdforstaticMemberstodefinestaticmembersandproperties.Thefollowingisthesignatureofthedefinemethod:

Nowlet'saddthepropertymessageandtheLogMessage()methodinthesameclassLogger:

<script>

varLogger=WinJS.Class.define(function(value){

this.logName=value;

this.enabled;

//constructor

console.log("Constructorisexecuting,valuepassedis"+value);

},{

logMessage:function(message){

if(this.logEnabled){

alert("Themessageis"+message);

}

},

logEnabled:{

get:function(){returnthis.enabled;},

Page 256: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

set:function(value){this.enabled=value;}

}

}

);

varlog=newLogger("Samplelog");

log.logEnabled=true;

log.logMessage("HelloWorld");

<script>

Thesyntaxofdefiningthemethodsfortheclassisamethodnamefollowedwithacolon(:)andthefunctionbodyasfollows:

logMessage:function(message){

alert("Themessageis"+message);

}

Thepropertiescanbedefinedwithgetandsetfunctionmethodsasshowninthefollowingcode:

logEnabled:{

get:function(){returnthis.enabled;},

set:function(value){this.enabled=value;}

}

Multiplepropertiesandmethodscanbedefinedinasamewayseparatedwithcommaasshowninthefollowingcode:

logEnabled:{

get:function(){returnthis.enabled;},

set:function(value){this.enabled=value;}

},

logType:{

get:function(){returnthis.loggerType;},

set:function(value){this.loggerType=value;}

}

DerivingclassesinWinJS

ClassesinWinJScanbederivedbyusingtheWinJS.class.derive()method.Consideringthepreviousexample,wecanalsoaddthelogEnabledandlogTypepropertiesonthebaseclassandthenderivetheLoggerclassfromtheBaseLoggerclass.HereisthecodetoderiveclassesinWinJS:

<script>

varBaseLogger=WinJS.Class.define(function(logName){

this.enabled;

this.loggerType;

this.loggerName=logName;

},{

logEnabled:{

get:function(){returnthis.enabled;},

set:function(value){this.enabled=value;}

Page 257: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

},

logType:{

get:function(){returnthis.loggerType;},

set:function(value){this.loggerType=value;}

}

});

varLogger=WinJS.Class.derive(BaseLogger,function(logName){

//callingbaseconstructorandpassingtheLogNametothebase

constructor

BaseLogger.call(this,logName);

},

{

logMessage:function(message){

if(Object.getOwnPropertyDescriptor(BaseLogger.prototype,

"logEnabled").get.call(this)==true){

alert("Themessageis"+message);

}

},

}

);

varlog=newLogger("HelloWorld");

log.logEnabled=true;

log.logType="Alert";

log.logMessage("hello");

</script>

IntheabovescriptwehavetakenboththepropertieslogTypeandlogEnabledtothebaseclassBaseLogger.InWinJS,basepropertiescanbeaccessedthroughthefollowingsyntax:

Object.getOwnPropertyDescriptor(BaseLogger.prototype,

"logEnabled").get.call(this)

SettingscanbedonebycallingthesetmethodafterthegetOwnPropertyDescriptor()methodcall:

Object.getOwnPropertyDescriptor(BaseLogger.prototype,

"logEnabled").set.call(this)=true;

NowifyouwanttotakethelogMessage()methodontheBaseLoggerclass,wecandoitthroughprototyping,asfollows:

BaseLogger.prototype.logMessage.call(this);

NamespacesinWinJS

Inobjectorientedprogramming,namespacesplayanimportantroleinorganizingclassesandcategorizingyourcode.Forexample,theservicescanresideundertheApplicationName.Servicesnamespace;modelscanresideundertheApplicationName.Modelsnamespace,andsoon.

Page 258: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Weshouldalwaysusenamespaceswherepossibleasitsolvesmanyproblemsthatcouldoccurinmid-sizetolargerprojects.Forexample,wehavetwoJavaScriptfilesaddedinourpagethathavesimilarnamesofpropertiesorfunctions.Theonereferencedlaterwillsupersedethememberfunctionsorvariablesofthepreviousonesiftheyhavethesamename.

WinJSprovidesaneasywaytologicallyorganizeclassesintonamespacesandyoucandefineanamespacebycallingWinJS.Namespace.define("namespacename",{}))).

HereistheexamplethatencapsulatesboththeBaseLoggerandLoggerclassintotheDemo.App.Utilitiesnamespace:

WinJS.Namespace.define("DemoApp.Utilities",{

//BaseLoggerclass

BaseLogger:WinJS.Class.define(function(logName){

this.enabled;

this.loggerType;

this.loggerName=logName;

},{

logEnabled:{

get:function(){returnthis.enabled;},

set:function(value){this.enabled=value;}

},

logType:{

get:function(){returnthis.loggerType;},

set:function(value){this.loggerType=value;}

},

}),

//Loggerclass

Logger:WinJS.Class.derive(BaseLogger,function(logName){

//callingbaseconstructorandpassingtheLogNametothebase

constructor

BaseLogger.call(this,logName);

},

{

logMessage:function(message){

if(Object.getOwnPropertyDescriptor(BaseLogger.prototype,

"logEnabled").get.call(this)==true){

alert("Themessageis"+message);

}

},

})

});

NowtheLogclasscanbeaccessedbyspecifyingitsnamespace,asshowninthefollowingcode:

varlog=newDemoApp.Utilities.Logger("SampleLogger");

log.logEnabled=true;

log.logType="Alert";

log.logMessage("hello");

Page 259: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

MixinMostofthelanguagesdonotsupportmultipleinheritance.However,inWinJSwecandoitthroughmixins.Likeclass,mixinisacollectionofmethodsandpropertiesbuttheobjectofmixinscannotbeinstantiated.Itisusedtomixwithaclasstobringthemethodsandpropertiesthatmixinshave.Forexample,thefollowingisaMixinlogMixinthatcontainsalogMessage()method:

varlogMixin={

logMessage:function(message){

alert(message);

}

};

varSampleClass=WinJS.Class.define(function(){

});

WinJS.Class.mix(SampleClass,logMixin);

varsample=newSampleClass();

sample.logMessage("Mixin");

Wecanaddasmanymixinswhencallingthemixmethod.Iftwoormorehavecommonmethodsorproperties,lateronewilloverridetheexistingone.Let'slookintotheexampleswhichhavetwomixins,namelylogMixinandlogConsoleMixin.BoththemixinsandaSampleClasshaveasamelogMessage()method.Nowbasedonthespecification,themethodswillbeoverriddenandwhenthelogMessage()isinvokeditwillwriteamessageonaconsolelog:

//FirstMixin

varlogMixin={

logMessage:function(message){

alert(message);

}

};

//SecondMixin

varlogConsoleMixin={

logMessage:function(message){

console.log(message);

}

}

//Class

varSampleClass=WinJS.Class.define(function(){

},

logMessage=function(message){

varresult=confirm(message);

});

Page 260: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WinJS.Class.mix(SampleClass,logMixin,logConsoleMixin);

varsample=newSampleClass();

sample.logMessage("Mixin");

Page 261: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

EventsinWinJSWinJSprovidesaneventMixinobjectthatcanbeusedtoregister,unregister,anddispatcheventsthroughthefollowingbasicsteps:

1. Firstofall,theclassfromwhichweneedtocallthedispatcheventneedstohaveWinJS.Utilities.eventMixinadded.WecanaddthisthroughtheWinJS.Class.mixmethod,asfollows:

WinJS.Class.mix(SampleClass,WinJS.Utilities.eventMixin);

2. OncetheeventMixinisinheritedbytheSampleClass,wecancallthedispatchEvent()methodtodispatchonaparticularaction.HereisthecodeoftheSampleclassthatdispatchestheeventoncetheexecutemethodiscalled:

varSampleClass=WinJS.Class.define(function(){

},

{

execute:function(message){

this.dispatchEvent("executeInvoked",{message:"Executed"

});

}

});

3. Next,wecanaddtheaddEventListener()methodandprovidetheeventHandler()thatwillbeinvokedoncethedispatchmessageiscalled:

varsampleClass=newSampleClass();

varsampleEventHandler=function(event){

alert(event.detail.message);

};

sampleClass.addEventListener("executeInvoked",sampleEventHandler);

sampleClass.execute("hello");

Page 262: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DatabindingWinJSprovidesaneasywayofbindinganyJavaScriptdatasourcetotheHTMLelement.AnyJavaScriptdatasourcecanbeboundusingdata-win-bindattributeonanHTMLelement.DatabindingfacilitatesinseparatingthedatawiththeviewandallowsyoutowritelesscodeandbindthedatawiththeelementsusingWinJS,whichprovidesthreetypesofdatabindingasfollows.

Onetimedatabinding

OnetimedatabindingisusedtobindtheelementonanHTMLpagefromaJavaScriptdatasource.Itisunidirectional,thatmeansiftheJavaScriptdatasourceisupdateditwillnotreflectthechangeontheHTMLtowhichitisboundto.

HereistheHTMLcodethathastwocontrolswhichbindsthepropertiesnameanddescriptionwiththeviewmodeldefinedinyourJavaScript:

<divid="rootDiv">

<div>CourseName:

<spanid="divForm"data-win-bind="innerText:name">loading</span>

</div>

<div>

CourseDescription:

<spanid="divForm"data-win-bind="innerText:

description">loading</span>

</div>

</div>

BelowistheJavaScriptcodewhichdefinestheviewmodel

letViewModel=WinJS.Class.define(function(){

this.nameProp;

this.descProp;

},

{

name:{

get:function(){returnthis.nameProp;},

set:function(value){this.nameProp=value;}

},

description:{

get:function(){returnthis.descProp;},

set:function(value){this.descProp=value;}

}

});

letviewModel=newViewModel();

viewModel.name="WinJSdatabinding";

viewModel.description="IntroductiontoWinJSdatabinding";

varpersonDiv=document.querySelector('#rootDiv');

WinJS.Binding.processAll(personDiv,viewModel);

Onewaydatabinding

Onewaydatabindingisaunidirectionalbinding.OncetheHTMLelementisboundtothe

Page 263: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

JavaScriptdatasource,anychangesinthedatasourcewillreflectthechangeontheHTMLpagebutifsomethingisupdatedontheHTMLelement,itwillnotupdatethebackendJavaScriptdatasource.Onewaydatabindingcanbedonebymakingthesourcemodelobservable.SoifanythingchangesonthesourceobjectitwillupdatetheUIelementtowhichitisboundto.ItcaneitherbedonebyusingtheWinJS.binding.as()methodoraddingtheobservableMixinwiththesourceclass.

ThefollowingisanexampleofonewaydatabindingthatbindsthepropertiesNameandDescriptionandonthebuttonclickevent,updatestheHTMLelementandsetsthevaluesetfromthebackenddatasource.AddingabuttoninthepreviousHTMLpageaddedintheOnetimedatabindingsection:

//HTMLmarkup

<buttonid="btnUpdate">Click</button>

//JavaScript

letViewModel=WinJS.Class.define(function(){

this.nameProp;

this.descProp;

},

{

name:{

get:function(){returnthis.nameProp;},

set:function(value){this.nameProp=value;}

},

description:{

get:function(){returnthis.descProp;},

set:function(value){this.descProp=value;}

}

});

letviewModel=newViewModel();

viewModel.name="WinJSdatabinding";

viewModel.description="IntroductiontoWinJSdatabinding";

varpersonDiv=document.querySelector('#rootDiv');

letobservableViewModel=WinJS.Binding.as(viewModel);

WinJS.Binding.processAll(personDiv,observableViewModel);

document.querySelector('#btnUpdate').onclick=function(){

observableViewModel.name="newname";

observableViewModel.description="newdescription";

}

Twowaydatabinding

Twowaydatabindingworksinbothdirections.OncetheJavaScriptobjectisboundtotheHTMLcontrol,anychangesdoneonthecontrolitselforifthevalueoftheJavaScriptobjectgetschanged,thecontrolvaluewillbeupdatedandviceversa.ImplementingtwowaybindinginWinJSisnotstraightforward.Weneedtohavetheonewaybindinginplacetoreflectanychangehappeningonthebackenddatasourcetoreflectonthefrontend,aswellastoupdate

Page 264: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

thebackenddatasourcefromanychangesdoneontheUIelement.ThiscanbedonebyimplementingonPropertyChange(),onKeyDown(),onChange(),oronClick()andothersbasedontheHTMLelement:

someTextboxElement.onpropertychange=function(){

someModel.property=someTextboxElement.value;

}

Anotherapproachistoimplementacustombindinginitializerwhichcanbeusedashighlightedinthefollowingcode:

<inputtype="text"data-win-bind="value:somePropertyBindingtwoWayBinding"/>

Let'screateacustomtwowaybindinginitializerandextendthesameviewModeltoacceptthenameanddescriptionupdatesthroughtextboxes.Hereisthecodeofourcustomtwowaybindinginitializer:

//DefiningBindinginitializertosupporttwowaybinding

WinJS.Namespace.define("Binding.Mode",{

twoway:WinJS.Binding.initializer(function

(source,sourceProperties,destination,

destinationProperties){

WinJS.Binding.defaultBind(source,sourceProperties,destination,

destinationProperties);

destination.onchange=function(){

vardestValue=destination[destinationProperties[0]];

source[sourceProperties[0]]=destValue;

}

})

});

Thencreateaclassthatcontainstwoproperties,namelynameanddescription:

//Definingclass

letViewModel=WinJS.Class.define(function(){

this.nameProp;

this.descProp;

},

{

name:{

get:function(){returnthis.nameProp;},

set:function(value){this.nameProp=value;}

},

description:{

get:function(){returnthis.descProp;},

set:function(value){this.descProp=value;}

}

});

//InitializingclassInstance

letviewModel=newViewModel();

viewModel.name="WinJSdatabinding";

viewModel.description="IntroductiontoWinJSdatabinding";

Page 265: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

varrootDiv=document.querySelector('#rootDiv');

letobservableViewModel=WinJS.Binding.as(viewModel);

WinJS.Binding.processAll(rootDiv,observableViewModel);

Intheabovecode,wehavefirstdefinedthebindinginitializerusingWinJS.Binding.initializer.Whendefiningthisinitializerwehavetopassfourpropertiesnamelysourceelementanditspropertiesobjectanddestinationelementanditsproperties.Soforexample,inourcasethesourceelementisatextboxandthesourcepropertyisitsvalue,whereasthedestinationelementwillbeaspanandinnerTextasitsdestinationproperty.WinJS.Binding.defaultBindcreatestheonewaybindingandthenwecanregistertheonchange()eventofthesourcepropertywhichupdatesthedestinationproperty.Thenwedefinedaclassandtheninitializedthevaluesbyinitializinganinstance.Andfinally,wehavetransformedthemodelintotheobservablemodeltoprovidetwowaybinding.

Now,intheHTMLelement,wecanaddthebindingasfollows:

<divid="rootDiv">

<div

<inputtype="text"data-win-bind="value:nameBinding.twoWayBinding"/>

</div>

<div>

CourseName:

<spanid="spanName"data-win-bind="innerText:

name">loading</span>

</div>

<div>

<inputtype="text"data-win-bind="value:descriptionBinding.twoWayBinding"/>

</div>

<div>

CourseDescription:

<spanid="spanDesc"data-win-bind="innerText:

description">loading</span>

</div>

</div>

Adatabindingworkingmodel

WhenthedatabindingisdoneinWinJS,theWinJS.processAll()methodhastobecalledifit'sdoneusingWinJS.Thismethodscansalltheelementswhichspecifythedata-win-bindattributes.Foreachelement,itchecksifthedataboundwiththeelementisobservableornot.Thisisacrucialstepwhichidentifiesthetypeofbindinganddeclareswhetherthebindingisaonewaybinding,onetimebinding,ortwowaybinding.

Page 266: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer
Page 267: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

PromisesPromisesrepresentanobjectthatcontainsavaluethatmightbeavailableatanytime.It'sapromisewhichsatisfiestheconsumerthattheresourcewillbeavailableandtheconsumercandotherestoftheworkwithoutwaitingfortheresourceinanasynchronousmanner.

Itworksasanasync/awaitfeatureofC#.Promisesallowconsumerstodootherworkratherthanwaitingforthevaluetoreturnandprovidescertainmethodstoacknowledgetheconsumeroncethepromiseisreceived.Incertaincases,thereisachanceofnothavingtheresponsereturnduetosomeerrorandthatcanalsobehandledbyimplementingspecificcallbacks.

InWinJS,promiseisanobjectwithfunctionsthenanddone.Wecaninitializepromiseasfollows:

varpromise=newWinJS.Promise(function(completed,error,progress)

//Callifweneedtoupdateconsumerthatstillinprogress

progress("progress");

//Callifanyerroroccurs

error("error");

//Callwhenthefunctioniscompleted

completed("completed");

}

);

Theprecedingcodeisthewayofdefiningafunctionthatreturnsapromise.Wecanthencallaprogressmethodifthemethodisnotcompletedandweneedtonotifytheconsumerifsomethingisinprogress.Oncethepromiseisdefined,wecanusethethenanddonemethodstoimplementcallbackmethodsthatwillbetriggeredbypromise.Thethenmethodreturnsapromiseanddenotestheintermediatestageoftheoperationwhereasdoneisthefinalstageoftheoperationanddoesnotreturnapromise:

promise.then(

function(){console.log("completed");},

function(){console.log("error")},

function(){console.log("promise")}

);

Thefollowingexampleshowsthefunctionthatdisplaysthetableinaconsolewindowandreturnscompletedoncethepromiseisprocessed:

functionexecuteTable(table,max)

{

returnnewWinJS.Promise(function(completed,error,progress){

for(i=1;i<max;i++){

console.log(table+'X'+i+'='+(table*i));

}

Page 268: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

completed("executedtable")

});

};

executeTable(2,10).then(

function(completedVal){

console.log(completedVal);

},function(errorVal){

console.log(errorVal);

},

function(onProgressVal){

console.log(onProgressVal);

}

)

Thefollowingistheoutput:

Nowlet'smodifythesameexampleandinvokeprogresstosendintermediateresultstotheconsumeroneachiteration.Theprecedingmethodissynchronousandreturningpromisedoesn'tmeanthemethodwillbeexecutedasynchronously.TomakethismethodrunasynchronouslywecanwraptheblockofcodethroughthesetImmediate()function.

setImmediate()istheJavaScriptfunctionwhichisusedtointerrupttheexecutionofthefunctionandreturnsthecallbackfunctionimmediately,thateventuallyinvokestheonProgress()functionofpromiseinourcase.HereisthemodifiedversionwiththesetImmediate()andonProgress()methods:

functionexecuteTable(table,max)

{

Page 269: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

returnnewWinJS.Promise(function(completed,error,

onProgress){

window.setImmediate(function(){

for(i=1;i<=max;i++){

varrow=table+'X'+i+'='+(table*i);

onProgress(row);

}

completed("executedtable")

},0);

});

};

executeTable(2,10).then(

function(completedVal){

console.log(completedVal);

},function(errorVal){

console.log(errorVal);

},

function(onProgressVal){

console.log(onProgressVal);

}

)

Theresultoftheprecedingcodesnippetwillbethesameasshowninthepreviousexample.However,theuseofthesetImmediate()functionallowstheonProgress()methodtowritemessagestotheconsolewindowasynchronouslyandismoreefficientintermsofperformance.

Otheroperationsofpromises

Thereareseveralothermethodsonpromisesthatcanbeusedtocancelanypromises,chainpromises,timeout,wrap,andsoon.Let'slookovereachmethodandseehowitcanbeused.

Chainingpromisesandhandlingerrors

Multiplepromisescanbechainedusingthenandbasedontheordertheyarechained,getexecutedonebyonesequentially.HereisthesimpleexamplethatloadsthewebpageusingtheWinJS.xhr()method.ThismethodisthebuiltinmethodthatreturnsapromiseandwecanusethismethodtomakeHTTPrequests:

varpromise1=function(){returnWinJS.xhr({url:"http://microsoft.com"})

};

varpromise2=function(){returnWinJS.xhr({url:

"http://google.com"})};

varpromise3=function(){returnWinJS.xhr({url:

"http://techframeworx.com"})};

varpromise4=function(){returnWinJS.xhr({url:

"http://msdn.microsoft.com"})};

promise1().then(function(dataPromise1){

console.log("gottheresponsefrompromise1");

returnpromise2();

}).then(function(dataPromise2){

Page 270: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

console.log("gottheresponsefrompromise2");

returnpromise3();

}).then(function(dataPromise3){

console.log("gottheresponsefrompromise3");

returnpromise4();

}).done(function(dataPromise4){

console.log("gottheresponsefrompromise4");

console.log("completedthepromisechain");

});

Intheprecedingcodewearereturningthenextpromiseoneverypromisechainexecutionblock.Thisisrequiredwhenchainingpromisesotherwiseitwouldnotcallthenextpromiseinthepipeline.Forthelastpromiseinthepipeline,wehaveuseddoneinsteadofthenwhichactuallytellsusthatthereisn'tapromisenextinthechainandnochainingcanbedonenow.Anotherbenefitistoperformerrorhandling.Inthedonemethod,wecangetalltheerrorsbeingthrownbyanyofthepromisesinthechain.Ifwedon'tusedonethenwewillnotbeabletoaccessanyerrorsthrowninthepromisechain.Thefollowingexampleisthemodifiedversionofthepreviousexamplewitherrorhandling:

varpromise1=function(){returnWinJS.xhr({url:

"http://microsoft.com"})};

varpromise2=function(){returnWinJS.xhr({url:

"http://google.com"})};

varpromise3=function(){returnWinJS.xhr({url:

"htt://techframeworx.com"})};

varpromise4=function(){returnWinJS.xhr({url:

"http://msdn.microsoft.com"})};

promise1().then(function(dataPromise1){

console.log("gottheresponsefrompromise1");

returnpromise2();

}).then(function(dataPromis2){

console.log("gottheresponsefrompromise2");

returnpromise3();

}).then(function(dataPromise3){

console.log("gottheresponsefrompromise3");

returnpromise4();

}).done(function(dataPromise4){

console.log("gottheresponsefrompromise4");

console.log("completedthepromisechain");

},function(error){

console.log("someerroroccurred,cause:"+error);

});

Intheprecedingexamplewehaveuseddoneinthefinalpromiseinthechain.Now,ifyouhavenoticed,thepromise2URLisnotvalidandthereisatypomistake.Nowifweexecutetheprecedingcode,promise1andpromise2willbeexecutedandwillwritethemessagesintheconsolelogwindow.Whereas,thepromisewillnotbeexecutedbuttheerrormethodwillbeinvokedanddefinedunderthedonemethodandwillwritetheerrordescriptionintheconsolelogwindow:

Page 271: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Cancelingpromises

Promisescanbecanceledbycallingthecancelmethodonthepromiseobject.Thefollowingisanexampletocancelanypromise:

varpromiseGoogle=function(){returnWinJS.xhr({url:"http://google.com"})

};

googlePromiseObj=promiseGoogle();

googlePromiseObj.cancel();

Promisescanonlybecanceledifit'snotcompletedandwentintotheerrorstateonceitwascanceled.

Joiningpromises

Multiplepromisescanbejoinedtogetherandreturnwhenallofthemarefinished.Wecanjoinpromises,asshowninthefollowingcode:

varpromise1=function(){returnWinJS.xhr({url:"http://microsoft.com"

})};

varpromise2=function(){returnWinJS.xhr({url:

"http://googe.com"})};

varpromise3=function(){returnWinJS.xhr({url:

"http://techframeworx.com"})};

WinJS.Promise.join([promise1,promise2,promise3])

.done(function(){

console.log("Allthepromisesarefinished");

});

Promise.any()canbeusedincaseswhenweneedtoknowifanyofthedefinedpromisesinsidetheanymethodhaveexecuted:

varpromise1=function(){returnWinJS.xhr({url:"http://microsoft.com"})

};

varpromise2=function(){returnWinJS.xhr({url:"http://googe.com"})};

varpromise3=function(){returnWinJS.xhr({url:"http://techframeworx.com"

})};

WinJS.Promise.any([promise1,promise2,promise3])

.done(function(){

console.log("Oneofthepromisesisfinished");

});

Checkingpromise

Page 272: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WinJS.Promise.is()isamethodthattakesavalueasaparameterandchecksifthatvalueisapromiseornot.Forexample,callingWinJS.xhrintheWinJS.Promise.is()methodwillreturntrue:

WinJS.Promise.is(WinJS.xhr({url:"http://microsoft.com"}));

Wrappingnon-promiseintopromise

AnyfunctioncanbewrappedintothepromiseusingtheWinJS.Promise.as()method.Thefollowingcodewrapsthenon-promisedisplayMessage()methodintoapromise:

functiondisplayMessage(){

console.log("Thisisanonpromisefunction")

}

varpromiseDisplayMessage=WinJS.Promise.as(displayMessage);

promiseDisplayMessage.done(function(){console.log("promiseis

executed")});

Page 273: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ExploringWinJScontrolsandstylesWindowslibraryforJavaScriptprovidesarichsetofcontrols,databindingoptions,andpromisesandinthissectionwewillexploreafewpopularcontrolsandstylingoptions.

NoneoftheWinJScontrolshaveseparatemarkup,insteadWinJSlibraryprovidesseveralattributesthatcanbeusedwiththeexistingHTMLelements.

Page 274: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AddingWinJScontrolsAswehaveseen,therearenoanymarkupsforWinJScontrolsandtheycanbeaddedthroughattributesontheHTMLelements.WinJScontrolscanbeaddedbyaddinganyHTMLelementandsettingitsdata-win-controlattributevaluetothenameoftheWinJScontrol.

Inthefollowingexample,wearechangingasimpleHTMLbuttonelementintothebackbuttonusuallyseeninstoreapps.Andthiscanbedonebyaddingthedata-win-controlattributeandsettingafullyqualifiednametoWinJS.UI.BackButton.

HereistheHTMLmarkup:

<buttondata-win-control="WinJS.UI.BackButton">WinJSbutton</button>

Whenyourunit,itwillrenderabackbuttononthepage,asshowninthefollowingfigure:

Alsoitdoesnotonlychangethelookbutalsoprovidesthebackwardnavigationfunctionalityoutofthebox.

Page 275: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SettingpropertiesofWinJScontrolsEveryHTMLelementhasseveralpropertieswhichcanbeaddressedbyspecifyingvaluesthroughattributes.Forexample,ratingcontrolallowsausertorateanyitemandwecansettheproperties,likethemaxandminrangeofstarstobedisplayed:

<divid="ratingControl"data-win-control="WinJS.UI.Rating"

data-win-options="{minRating:1,averageRating:5,maxRating:10}">

</div>

Theoutputoftheprecedingmark-upwillgeneratearatingcontrollikethefollowingfigure:

ThereareotherWindowsspecificcontrolslikeListView,FlipView,andZoomthatyoucanuseinyourpageandbringhighperformanceonlargecollectionsorobjects.YoucanlearnmoreaboutcontrolsattheWindowsDevCenterwebsiteat:https://msdn.microsoft.com/en-us/library/windows/apps/mt502392.aspx

Page 276: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UsingWindowsruntimefeaturesWinJSprovidesacompleteAPItouseWindowsruntimefeaturesanddevicespecificfeatures.WhenaccessingthedevicespecificfeaturesusingWinJS,thewebapplicationshouldrunasawindowsapplicationandaccessingitfromabrowserwillresultinanerror.Also,MicrosofthasreleasedtheconceptofHostedappswhichenableanywebapplicationtohostasawindowsapplicationwithafewconfigurationsteps.

Page 277: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

HostedappsandaccessingthecameraHostedappswereintroducedwiththelaunchofUWP.Let'screateasimpleexampletoconvertasimpleASP.NETcoreapplicationintoaWindowsapplicationusingtheHostedappconceptandaccessthecamera.

CreatingtheASP.NETcoreapplication

CreateasimpleASP.NETcoreapplicationinVisualStudio2015andaddtheWinJSpackagesthroughNPM.Hereisthecodesnippetofpackage.json:

{

"version":"1.0.0",

"name":"ASP.NET",

"private":true,

"dependencies":{

"winjs":"4.4.0"

},

"devDependencies":{

"gulp":"^3.9.1"

}

}

WecanaddWinJSunderthedependenciessectionandonsavingthepackage.jsonfile,thepackagewillbedownloadedautomatically.WehavetoaddgulpaswelltocopytherelatedlibrariesandCSSfilesinthewwwrootfolder.Afterthis,addthegulpfile.jsandaddthefollowingscript:

///<bindingClean='clean'/>

"usestrict";

vargulp=require("gulp");

varpaths={

webroot:"./wwwroot/"

};

varconfig={

libBase:'node_modules',

lib:[

require.resolve('winjs/js/base.js'),

require.resolve('winjs/js/ui.js'),

require.resolve('winjs/js/winjs.intellisense.js'),

require.resolve('winjs/js/winjs.intellisense-setup.js')

],

libCss:[require.resolve('winjs/css/ui-dark.css'),

require.resolve('winjs/css/ui-light.css')

]

};

gulp.task('build.lib',function(){

returngulp.src(config.lib,{base:config.libBase})

.pipe(gulp.dest(paths.webroot+'lib'));

});

gulp.task('build.libCss',function(){

returngulp.src(config.libCss,{base:config.libBase})

.pipe(gulp.dest(paths.webroot+"lib"));

Page 278: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

});

Whenyourunthebuild.libandbuild.LibCsstasksthroughataskrunnertabinVisualStudio2015,itwillcopytheWinJSlibrariesandCSSfilesinsidethewwwrootfolder:

Inthisapplication,wewillhaveasimpleHTMLpagethatwecandirectlyaddintothewwwrootfolder,forthisweneedtocalltheapp.UseStaticFiles()methodintheConfigure()methodandaddthepackageinproject.json:

"Microsoft.AspNet.StaticFiles":"1.0.0-rc1-final"

Let'saddtheIndex.htmlpageinsidethewwwrootfolderandaddthefollowingscriptsintheHTMLheadelement:

<scriptsrc="lib/winjs/js/base.js"></script>

<scriptsrc="lib/winjs/js/ui.js"></script>

<scriptsrc="lib/winjs/js/winjs.intellisense-setup.js"></script>

<scriptsrc="lib/winjs/js/winjs.intellisense.js"></script>

<scriptsrc="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.js"></script>

WewillbeusingthelightWindowsthemesoaddui-light.css,asfollows:

<linkrel="stylesheet"href="lib/winjs/css/ui-light.css"/>

NowaddthepagecontentwhichcontainsabuttonCapturetocapturetheimageandanimageelementtodisplaythecapturedimage:

<divid="rootDiv">

<divclass="col-md-4">

Clicktocaptureimage<inputtype="button"value="Capture"

onclick="returnCaptureCamera();"/>

</div>

<br/>

<imgid="imgPhoto"width="500"height="500"style="border:dotted;"/>

</div>

Thefollowingistheoutputofthepage:

Page 279: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Nowaddthefollowingscripttoaccessthecameraandattachthecapturedimagewiththeimageelement:

<script>

if(window.Windows){

functionCaptureCamera(){

varnotifications=Windows.UI.Notifications;

vardialog=newWindows.Media.Capture.CameraCaptureUI();

varaspectRatio={width:1,height:1};

dialog.photoSettings.croppedAspectRatio=aspectRatio;

dialog.captureFileAsync(Windows.Media.Capture.CameraCaptureUIMode.photo).done(fun

ction(capturedImage){

if(capturedImage){

varimageURL=URL.createObjectURL(capturedFile,{

oneTimeOnly:true});

document.getElementById("img").src=imageURL;

}

else{

WinJS.log&&WinJS.log("Noimagecapturedyet",

"WinJSTestApp","Status");

Page 280: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

},function(err){

WinJS.log&&WinJS.log(err,"WinJSTestApp","Error");

});

}

}else{

functionCaptureCamera(){

alert("Cannotaccesscamera,itshouldbehostedasa

windowsapplication");

}

}

</script>

ConvertinganASP.NETapplicationintoWindowsapplicationusingtheHostedappconcept

ConvertinganywebapplicationintotheWindowsapplicationisverysimple.InVisualStudio2015youcanstartcreatingasimpleJavaScriptbasedWindowsapplicationusingtheBlankApp(UniversalWindows)templateasshowninthefollowingscreenshot:

Whenyouaddaprojectitwilladdthecss,images,js,andwinjsfolders.Wehavetodeletethecss,js,andwinjsfoldersaswewillnotbeusinganyofthefilesinthisprojectand

Page 281: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

configurethewebapplicationcreatedaboveandtransformittoaWindowsapplication.

Openthepackage.appxmanifestwindow.AddtheURLintheStartPagetextboxasshowninthefollowingscreenshot.OursampleASP.NETapplicationcreatedabovewashostedonport41345:

IntheContentURIstab,addtheURIofourwebapplicationandselectAllunderWinRTAccess.YoucanspecifytheURLofanywebapplicationwhichshouldbehostedsomewhere.Intheprecedingscreenshotweareusinglocalhostwhichactuallypointstoawebapplicationhostedlocally:

ThiswindowallowsustospecifyaccessrulestoWinRTfeaturesandwecansetittoNone,All,orAllowforwebonly.

Page 282: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Buildingandrunningtheapplicationwillshowthewindowsapplicationdialoghostingourwebapplicationindex.htmlpage:

ClickingontheCapturebuttonwillprovideapopupofanotherdialogtotakeasnapshot,asshowninthefollowingscreenshot:

Page 283: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Aftertakingthedesiredshot,itwillaskyoutosaveorrejectthroughtickandcrossbuttons:

SelectingtickwillrenderthephotointheimgHTMLelement,asshowninthefollowingscreenshot:

Page 284: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer
Page 285: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryInthischapter,weexploredtheWinJSWindowslibraryforJavaScriptlibrarywhichisopensourceandunderanApachelicense.Welearnedthecoreconceptsofdefiningclasses,namespaces,derivingclasses,mixins,andpromises.WealsolookedintothedatabindingtechniquesandhowtousethewindowscontrolsorattributesinHTMLelementstochangethebehaviorandlookandfeelofthecontrol.Andfinally,weusedtheWinRTAPItoaccessthedevicecamerainourwebapplicationandlearnedtheconceptofHostedappandtransforminganywebapplicationintotheWindowsappsusingtheUniversalWindowtemplateinVisualStudio2015.Inthenextchapter,wewilllearnaboutafewgooddesignpatternsthatcanbeimplementedinJavaScripttoachievespecificrequirements.

Page 286: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter7.JavaScriptDesignPatternsIneverymid-tolarge-sizedprojects,goodarchitectureanddesignalwaysplaysanimportantroleinhandlingcomplexscenariosandincreasingthemaintainabilityoftheproduct.Designpatternsarebestpracticesdevelopedandusedbyprofessionaldeveloperstosolveaparticularproblem.Ifadesignpatternhasbeenusedintheapplicationforspecificscenarios,itevadesmanyoftheissuesonecouldfaceduringdevelopmentorwhenrunningtheapplicationinproduction.Designpatternssolvetheproblemsbyprovidingtheguidelineswhichareindustrybestpracticestohandleproblemsortoachieveorimplementanyrequirement.Asingletonpattern,forexample,isusedtocreateonlyoneinstancethatissharedamongall,whereasaprototypeisusedtoextendtheexistingfunctionalityofanobjectbyaddingmorepropertiesandmethodsandsoon.Designpatternsareclassifiedintothreecategories,namelycreational,structural,andbehavioralpatterns.Thetopicswhichwewillcoverinthischapterareasfollows:

Creationalpatterns:Thefollowingarethecreationalpatternswewilldiscussinthischapter:

SingletonpatternFactorypatternAbstractfactorypatternPrototypepattern

Structuralpatterns:Thefollowingarethelistofstructuralpatternswewilldiscussinthischapter:

AdapterpatternDecoratorpatternFacadepatternBridgepattern

Behavioralpatterns:Thefollowingarethelistofbehavioralpatternswewilldiscussinthischapter:

ChainofresponsibilityObserverpatternPub/subpatternPromises

Page 287: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CreationalpatternsCreationalpatternsareusedforobjectinstantiation.Theyareusedinsituationswherethebasicformofobjectcreationcouldresultindesignproblemsorincreasecomplexitytothedesign.Inthefollowingsection,wewilldiscussallfourcreationalpatternsmentionedpreviously,andhowtoimplementtheminJavaScript.

Page 288: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SingletondesignpatternSingletonisthemostwidelyusedpattern.Itisusedinscenarioswhereweneedtosharethesameinstanceofaclassorfunction(intermsofJavaScript)betweendifferentobjects.Itensuresthatthereisonlyoneinstanceofparticularobjectwhichcanbeaccessedgloballyatanypoint:

Inasingletonpattern,theconstructorshouldbeprivatewhichrestrictstheusertocreateobjectsusinganewkeywordandexposesonemethodthatcreatesaninstanceandverifiesthatonlyoneinstanceexists.Asimpleexamplecouldbealoggerobjectthatwritesthelogtothebrowser'sconsolewindow:

<script>

varLogger=(function(){

//privatevariable

varinstance;

//privatemethod

functioninitializeInstance(){

//closurereturnsthepublicaccesstothewriteLogfunctionthat

canbeaccessiblebythesingletonobject

return{

writeLog:function(message){

console.log(message);

}

};

};

//closurethatreturnsthepublicaccesstothegetInstancemethodthat

returnsthesingletonobject

return{

//Thisisapublicmethodthatreturnsthesingletoninstance

getInstance:function(){

if(!instance){

instance=initializeInstance();

}

returninstance;

},

};

})();

varlogger=Logger.getInstance();

Page 289: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

logger.writeLog("Helloworld");

</script>

Tip

InJavaScript(ES5standard),classesarestillrepresentedthroughfunctions.

InJavaScript,toimplementasingleton,wecanuseclosures.Closuresareinnerobjectsthathaveaccesstotheprivatemembersofthefunction,suchasaccessingvariablesandmethodsdefinedwithinaparentfunction,andareaccessiblefromclosures.

Brackets()inthelaststatementarespecifiedtoassigntheobjectreturningtotheloggervariableratherthanthefunctionitself.Thisactuallyrestrictstheobjectfrominitializingthroughanewkeyword.

Intheprecedingscript,thefunctionfirstreturnstheclosurethathasonegetInstance()method,whichactuallycheckstheprivatemembervariableinstanceandifitisnotinitializeditcallstheinitializeInstance()methodthatreturnsanotherclosurecontainingthewriteLog()method.Wecanaddmoremethodsorvariablesseparatedbycommasandtheywillbeaccessiblewiththeloggerobject.HereisthemodifiedversionoftheinitializeInstance()methodthathasonemoremethod,showAlert(),andavariable,logEnabled:

functioninitializeInstance(){

//closurereturnsthepublicaccesstothewriteLogfunctionthat

canbeaccessiblebythesingletonobject

return{

writeLog:function(message){

if(this.logEnabled)

console.log(message);

},

showAlert:function(message){

if(this.logEnabled)

alert(message);

},

logEnabled:false

};

};

Page 290: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

FactorypatternThefactorypatterndelegatesobjectinstantiationtothecentralizedclass.Insteadofinstantiatingtheobjectusinganewkeyword,wecallthefactorymethodthatreturnsthetypeoftheobjectrequested:

HereisanexampleoftheLoggerFactorythatcreatestheloggerinstancesbasedontheloggertype:

//LoggerFactorytoinstantiateobjectsbasedonloggertype

functionLoggerFactory(){

varlogger;

this.createLogger=function(loggerType){

if(loggerType==="console"){

logger=newConsoleLogger();

}

elseif(loggerType==="alert"){

logger=newAlertLogger();

}

returnlogger;

}

}

//Consoleloggerfunction

varConsoleLogger=function(){

this.logMessage=function(message){

console.log(message);

}

};

//Alertloggerfunction

varAlertLogger=function(){

this.logMessage=function(message){

Page 291: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

alert(message);

}

};

varfactory=newLoggerFactory();

//creatingConsoleloggerobjectusingLoggerFactory

varconsoleLogger=factory.createLogger("console");

consoleLogger.logMessage("Factorypattern");

//createAlertloggerobjectusingLoggerFactory

varalertLogger=factory.createLogger("alert");

alertLogger.logMessage("Factorypattern");

Inourexample,thefactoryclassisLoggerFactorythatcreatesinstancesofConsoleLoggerandAlertLoggerobjects.LoggerFactoryexposesacreateLogger()methodthattakesthetypeofloggerasaparametertodeterminewhichobjectneedstobeinstantiated.EachtypeofloggerhasitsownlogMessage()methodtoeitherlogontheconsolewindoworshowanalertmessage.

Page 292: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AbstractfactorypatternTheabstractfactorypatternencapsulatesthecollectionoffactoriestocreateinstances.Theinstanceexposesthesamemethodthatcanbeinvokedbythefactory.Thefollowingisanexampleoftwofactories,ShapeFactoryandCarFactoryandeachonereturnstwotypesofinstance.ShapeFactoryreturnsCircleandSquareinstanceswhereasCarFactoryreturnsHondaCarandNissanCarinstances.Eachoftheinstancehavethesamemethodmake()thatcanbecalledforanyinstance:

HereisthecodeforShapeFactory:

<script>

//ShapeFactorytocreateinstancesofCircleandSquare

varShapeFactory=function(){

varshape;

this.createShape=function(shapeType){

if(shapeType==="circle"){

returnnewCircleShape();

}

elseif(shapeType==="square"){

returnnewSquareShape();

}

}

}

//Circleobjecttodrawcircle

varCircleShape=function(){

Page 293: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

this.make=function(){

varc=document.getElementById("myCanvas");

varctx=c.getContext("2d");

ctx.beginPath();

ctx.arc(100,75,50,0,2*Math.PI);

ctx.stroke();

}

}

//Squareobjecttodrawsquare

varSquareShape=function(){

this.make=function(){

varc=document.getElementById("myCanvas");

varctx=c.getContext("2d");

ctx.beginPath();

ctx.rect(50,50,50,50);

ctx.stroke();

}

}

ThefollowingisthecodeforCarFactorythatcreatesinstancesofHondaandNissancars:

//Carfactorytocreatecars

varCarFactory=function(){

varcar

this.createCar=function(carType){

if(carType==="honda"){

returnnewHondaCar();

}

elseif(carType==="nissan"){

returnnewNissanCar();

}

}

}

//Hondaobject

varHondaCar=function(){

this.make=function(){

console.log("ThisisHondaAccord");

}

}

//Nissanobject

varNissanCar=function(){

this.make=function(){

console.log("ThisisNissanPatrol")

}

}

Wecalltheexecutemethodonabuttonclickeventwhichcreatestheinstancesandholdstheminanarray.Eventuallytheobjectsmake()methodwillbeexecutedthatdrawsthecircleonaHTMLcanvasandwritesmessagesontheconsole.AsinJavaScript,wecannotdefineabstractmethods;wehavetoexplicitlydefinethesamemethod,suchasmake()inourcasethatcompletesourabstractfactorypattern:

Page 294: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

functionexecute(){

//initializinganarraytoholdobjects

varobjects=[];

//CreatingShapeFactorytocreatecircleshape

varshapeFactory=newShapeFactory();

varcircleShape=shapeFactory.createShape("circle");

//CreatingCarFactorytocreatecars

varcarFactory=newCarFactory();

varhondaCar=carFactory.createCar("honda");

varnissanCar=carFactory.createCar("nissan");

//Addingalltheinstancescreatedthroughfactories

objects.push(circleShape);

objects.push(hondaCar);

objects.push(nissanCar);

//Callingmakemethodofalltheinstances.

for(vari=0;i<objects.length;i++){

alert(objects[i]);

objects[i].make();

}

}

</script>

HereistheHTMLcodecontainingacanvasandabutton:

<div>

<inputtype="button"onclick="execute()"value="Execute"/>

</div>

<div>

<canvasid="myCanvas"></canvas>

</div>

Theoutputwillbeasfollowsonabuttonclickevent.ThecirclewillbedrawnandtwomessageswillbeprintedontheconsolewindowforHondaandNissancarobjects:

Page 295: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

PrototypepatternTheprototypepatternisusedtocreateinstancesthatareclonesofexistinginstances.Itisusedinscenarioswhereweneedtoautoconfiguretheobjectwithsomespecificvaluesorpropertiesandusersdon'thavetoexplicitlydefine:

Thefollowingisthecodethatimplementstheprototypepattern:

<script>

functionCar(make,model,year,type)

{

this.make=make;

this.model=model;

this.year=year;

this.type=type;

this.displayCarDetails=function(){

}

}

functionCarPrototype(carPrototype){

varcar=newCar();

this.getPrototype=function(){

car.make=carPrototype.make;

car.model=carPrototype.model;

car.year=carPrototype.year;

car.type=carPrototype.type;

returncar;

Page 296: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

}

(function(){

varcar=newCar("Honda","Accord","2016","sedan");

varcarPrototype=newCarPrototype(car);

varclonedCar=carPrototype.getPrototype();

})();

</script>

Intheprecedingcodesnippet,thereisacarobjectthatacceptsfourparameters,make,model,yearandtype.CarPrototype()isafunctionthatacceptsthecarobjectandreturnstheclonedversionofthecarobject.Thispatternisperformanceefficientandsavesdeveloperstimecreatingaclonecopyoftheobjectbyjustcallingtheprototypeobject'sclonemethod.Theuserdoesnotneedtocareaboutpopulatingthepropertiesafterobjectinstantiation;itinitializeswhentheobjectiscreatedandgetsthesamevaluesastheoriginalobject.ItisusedinconditionswhereweneedtocloneinstancesofobjectswhentheyareinaspecificstateandcanbeeasilyclonedbycallingthegetProtoype()method.

Page 297: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

StructuralpatternsStructuralpatternsareusedtosimplifytherelationshipsbetweenobjects.Inthefollowingsections,wewilldiscussallfourstructuralpatternsmentionedpreviously,andhowtoimplementtheminJavaScript.

Page 298: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AdapterpatternTheadapterpatternisusedinsituationsinwhichourapplicationisdependentonanyobjectwhosepropertiesandmethodschangefrequentlyandwewanttoavoidmodifyingthecodetousethem.Theadapterpatternallowsustowraptheinterfaceofaspecificobjectaswhattheclientexpectsandratherthanchangingthewholeimplementationwecanjustcallthewrapperobjectwhichcontainsthecodeasperthemodifiedversion.Thiswrapperobjectiscalledanadapter.Let'shavealookatabasicexamplethatusesthePersonRepositorytosavethepersonobjectbyperforminganAjaxrequest:

ThefollowingistheoldinterfaceofthePersonRepositoryobject:

//oldinterface

functionPersonRepository(){

this.SavePerson=function(name,email,phoneNo){

//Callajaxtosaveperson

console.log("Name:"+name+",Email:"+email+",PhoneNo:"+

phoneNo);

}

}

TheprecedinginterfacehasoneSavePerson()methodthattakesthreeparameters:name,

Page 299: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

email,andphoneNo.HereistheoriginalcodeforusingtheSavePerson()method:

varexecute=function(){

varpersonRepository=newPersonRepository();

personRepository.SavePerson("John","[email protected]","1201111111");

}

SupposethisinterfacehaschangedandthenewpersonrepositoryinterfaceacceptsthepersonJSONobject,insteadofpassingvaluesasparameters.OnewayistomodifythefunctionhereitselfandencapsulatetheseparametersintheJSONobjectandsend.Alternatively,wecanimplementanadapterpatternwhichcontainsanadapterfunctionthattakesthreeparameters,callsthenewPersonRepositoryobjectandpassestheJSONobject.

ThefollowingisthenewinterfaceofPersonRepository:

functionPersonRepository(){

this.SavePerson=function(person){

//callajaxtosendJSONpersondata

console.log("Name:"+person.name+",Email:"+person.email+",

PhoneNo:"+person.phoneNo);

}

}

HereistheadapterpatternthatencapsulatestheparametersinaJSONobjectandcallsthenewPersonRepositoryinterface:

functionPersonRepositoryAdapter(){

this.SavePerson=function(name,email,phoneNo){

varperson={"name":name,"email":email,"phoneNo":phoneNo};

varpersonRepository=newPersonRepository();

//callingnewPersonRepository

personRepository.SavePerson(person);

}

}

HereisthemodifiedversionthatcallstheadapterpatternratherthancallingtheoldPersonRespositoryinterface:

varexecute=function(){

//oldinterface

//varpersonRepository=newPersonRepository();

//personRepository.SavePerson("John","[email protected]","1201111111");

//callingadapterpattern

varpersonAdapter=newPersonRepositoryAdapter();

personAdapter.SavePerson("John","[email protected]","1201111111");

}

Page 300: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DecoratorpatternThedecoratorpatternisusedtochangethebehavioroftheobjectatruntime.DecoratorsarelikeannotationattributesinC#.Likewise,wecanaddmultipledecoratorsononeobjectaswell.Thedecoratorpatterncanbeimplementedbycreatingadecoratorobjectandassociatingthatwiththetargetobjectwhosebehaviorneedstobechanged:

ThefollowingisanexampleofadecoratorthataddstheTaxandCourierchargedecoratorsontheProductobject:

<script>

varProduct=function(code,quantity,price){

this.code=code;

this.quantity=quantity;

this.price=price

this.total=function(){

this.price=price*quantity;

returnthis.price;

}

}

//DecoratorthattakesproductandpercentasparametertoapplyTax

Page 301: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

functionAddTax(product,percent){

product.total=function(){

product.price=product.price+(product.price*percent/100);

returnproduct.price;

}

}

//DecoratortoaddCourierchargesinthetotalamount.

functionAddCourierCharges(product,amount){

product.total=function(){

product.price=product.price+amount;

returnproduct.price;

}

}

varexecute=(function(){

varprod=newProduct("001",2,20);

console.log("Totalprice:"+prod.total());

AddTax(prod,15);

console.log("TotalpriceafterTax:"+prod.total());

AddCourierCharges(prod,200);

console.log("TotalpriceafterCourierCharges:"+prod.total());

})();

Theproductobjecttakesthreeparameters,code,quantity,andprice,andcalculatesthetotalpricebasedonquantityandprice.AddTax()andAddCourierCharges()aretwodecoratorobjectsproductobjectfollowedwithaparametertoapplyspecificcalculationonchangethetotalprice.TheAddTax()methodappliesthetaxbasedonthevaluesupplied,whereasAddCourierCharges()willaddthecourierchargeamounttothetotalprice.TheExecute()methodwillbecalledimmediatelywhenthepagerendersanddisplaysthefollowingoutputintheconsolewindow:

Page 302: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

FacadepatternThefaçadepatternisusedtosimplifyvariousinterfacesorsubsystemsintooneunifiedinterface.Itsimplifiesthingstotheuserandratherthanunderstandingthecomplexitiesofdifferentsubsystems,theusercancallthefaçadeinterfacetoperformaspecificoperation.

Let'sseethefollowingexample,whichhasthreemethodstoloadpermissions,theuserprofile,andtheuserchatwindowonsuccessfullogin.Ithasthreeinterfaces,andwithfaçadewecansimplifyittooneunifiedinterface.ThisallowstheusertocallUserFacadeonlyonceiftheloginissuccessfulanditwillloadthepermissions,userchat,anduserprofilefromoneinterface:

<script>

varPermission=function(){

this.loadPermission=function(userId){

//loaduserpermissionsbycallingserviceandpopulateHTMLelement

varrepo=newServiceRepository();

repo.loadUserPermissions(userId);

}

}

varProfile=function(){

this.loadUserProfile=function(userId){

//loaduserprofileandsetusernameandimageinHTMLpage

varrepo=newServiceRepository();

repo.loadUserProfile(userId);

}

}

varChat=function(){

this.loginUserChat=function(userId){

//LoginuserchatandupdateHTMLelement

varrepo=newServiceRepository();

repo.loadUserChat(userId);

}

}

varUserFacade=function(){

Page 303: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

this.loadUser=function(userId){

varuserPermission=newPermission();

varuserProfile=newProfile();

varuserChat=newChat();

userPermission.loadPermission(userId);

userProfile.loadUserProfile(userId);

userChat.loginUserChat(userId);

}

}

varloginUser=(function(username,password){

//Servicetologinuser

varrepo=newServiceRepository();

//Onsuccessfulllogin,useridisreturned

varuserId=repo.login(username,password);

varuserFacade=newUserFacade();

userFacade.loadUser(userId);

})();

<

Page 304: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

BridgepatternThebridgepatternisusedtodecoupletheabstractionfromitsimplementationandmakeconcreteimplementationindependentfromtheinterface.Thisisachievedbyprovidingabridgebetweentheinterfaceandtheconcreteimplementer:

Thefollowingcodeshowsthebridgepatternimplementation:

<script>

varInvitation=function(email){

this.email=email;

this.sendInvite=function(){

this.email.sendMessage();

}

}

varReminder=function(sms){

this.sms=sms;

this.sendReminder=function(){

Page 305: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

this.sms.sendMessage();

}

}

varSMS=function(){

//sendSMS

this.sendMessage=function(){console.log("SMSsent");}

}

varEmail=function(){

//sendemail

this.sendMessage=function(){console.log("Emailsent");}

}

varexecute=(function(){

varemail=newEmail();

varsms=newSMS();

varinvitation=newInvitation(email);

varreminder=newReminder(sms);

invitation.sendInvite();

reminder.sendReminder();

})();

</script>

Theobjectiveoftheprecedingexampleistoseparatethenotificationtypes(InvitationandReminder)fromthenotificationgateway(EmailandSMS).Soanynotificationcanbesentthroughanygatewayandcanhandleanynotificationthatseparatesthegatewaytothenotificationtypesanddisabletheboundingwiththetypeofthenotification.

Page 306: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

BehavioralpatternBehavioralpatternsareusedtodelegateresponsibilitiesbetweenobjects.Inthefollowingsection,wewilldiscussallfourbehavioralpatternsmentionedpreviously,andhowtoimplementtheminJavaScript.

Page 307: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ChainofresponsibilitypatternThechainofresponsibilitypatternprovidesachainofobjectsexecutedinorderastheyarechainedtofulfillanyrequest.AgoodexampleforASP.NETdevelopersistheOWINpipelinethatchainsthecomponentsorOWINmiddlewaretogetherandisbasedontheappropriaterequesthandlerbeingexecuted:

Let'slookintoaverybasicexamplethatexecutesthechainofobjectsanddisplaysthetablefor2,3and4:

<script>

//Maincomponent

varHandler=function(table){

this.table=table;

this.nextHandler=null;

}

//Prototypetochainobjects

Handler.prototype={

generate:function(count){

for(i=1;i<=count;i++){

console.log(this.table+"X"+i+"="+(this.table*i));

}

//Ifthenexthandlerisavailableexecuteit

if(this.nextHandler!=null)

this.nextHandler.generate(count);

},

//Usedtosetnexthandlerinthepipeline

setNextHandler:function(handler){

this.nextHandler=handler;

}

}

//functionexecutedonPageload

varexecute=(function(){

//initializingobjects

varhandler1=newHandler(2),

handler2=newHandler(3),

handler3=newHandler(4);

//chainingobjects

handler1.setNextHandler(handler2);

handler2.setNextHandler(handler3);

Page 308: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

//callingfirsthandlerorthecomponentinthepipeline

handler1.generate(10);

})();

<script>

Let'sgetintoamorepracticalexamplewhichtakestheamountandchecksthebudgetownerintheobjectschainedinthepipeline.ThefollowingcodehaveamainhandlerobjectthattakesthebudgetamountandthebudgetownertosetthebudgetamountforLineManager,HeadofDepartment,CTO,andCEO.Finally,wecansetthemainentrypointinthechainbycallingthehandler1method,whichfirstcheckswhethertheamountisunderthelinemanager'sbudget,thentheheadofdepartment's,thentheCTO's,andfinallytheCEO's:

<script>

//Maincomponent

varHandler=function(budget,budgetOwner){

this.budget=budget;

this.budgetOwner=budgetOwner;

this.nextHandler=null;

}

//Prototypetochainobjects

Handler.prototype={

checkBudget:function(amount){

varbudgetFound=false;

if(amount<=this.budget){

console.log("Amountisunder"+this.budgetOwner+"level");

budgetFound=true;

}

//Ifthenexthandlerisavailableandbudgetisnotfound

if(this.nextHandler!=null&&!budgetFound)

this.nextHandler.checkBudget(amount);

},

//Usedtosetnexthandlerinthepopeline

setNextHandler:function(handler){

this.nextHandler=handler;

}

}

//funcitonexecutedonPageload

varexecute=(function(){

//initializingobjects

varhandler1=newHandler(10000,"LineManager"),

handler2=newHandler(50000,"HeadofDepartment"),

handler3=newHandler(100000,"CTO"),

handler4=newHandler(1000000,"CEO");

//chainingobjects

handler1.setNextHandler(handler2);

handler2.setNextHandler(handler3);

Page 309: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

handler3.setNextHandler(handler4);

//callingfirsthandlerorthecomponentinthepipeline

handler1.checkBudget(20000);

})();

</script>

Andthefollowingistheoutput:

Page 310: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ObserverpatternTheobserverpatterniswidelyusedtoimplementapublisher/subscribermodelinwhichifastateofanyobjectchanges,itnotifiesalltheobserverssubscribed.Observerpatternshavethreemethods,namelytoadd,remove,andnotifyobservers:

Thefollowingisthecodesnippetthatimplementstheobserverpattern:

<script>

//SamplefunctiontoconverttexttoFrenchlanguage

functiontranslateTextToFrench(value){

//callsomeservicetoconverttexttoFrenchlanguage

returnvalue;

}

//SamplefunctiontoconverttexttoArabiclanguage

functiontranslateTextToArabic(value){

//calsomeservicetoconverttexttoArabiclanguage

returnvalue;

}

//HelperfunctionusedbytheObserverimplementors

varHelperFunction=function(type){

vartxtEntered=document.getElementById("txtEntered");

varenglishText=document.getElementById("englishText");

varfrenchText=document.getElementById("frenchText");

vararabicText=document.getElementById("arabicText");

if(type=="english"){

englishText.innerText=txtEntered.value;

Page 311: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}elseif(type=="french"){

frenchText.innerText=translateTextToFrench(txtEntered.value);

}elseif(type=="arabic"){

arabicText.innerText=translateTextToArabic(txtEntered.value);

}

}

varEnglishTranslator={

update:function(){

//CallhelperfunctiontochangetexttoEnglish

HelperFunction("english");

}

}

varFrenchTranslator={

update:function(){

//CallhelperfunctiontochangetexttoFrench

HelperFunction("french");

}

}

varArabicTranslator={

update:function(){

//CallhelperfunctiontochangetexttoArabic

HelperFunction("arabic");

}

}

//Observerfunctionthatcontainsthelistofobserverhandlers

functionObserver(){

this.observers=[];

}

//toaddobserver

Observer.prototype.addObserver=function(object){

console.log('addedobserver:'+object);

this.observers.push(object);

};

//toremoveobserver

Observer.prototype.removeObserver=function(object){

console.log("removingobserver");

for(i=0;i<this.observers.length;i++){

if(this.observers[i]==object){

this.observers.splice(object);

returntrue;

}

}

returnfalse;

};

//Tonotifyallobserversandcalltheirupdatemethod

Observer.prototype.notify=function(){

for(i=0;i<this.observers.length;i++){

this.observers[i].update();

Page 312: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

}

//Addingobjectsasobserversthatimplementstheupdatemethod

varobserver=newObserver();

observer.addObserver(EnglishTranslator);

observer.addObserver(FrenchTranslator);

observer.addObserver(ArabicTranslator);

//Executewillbecalledonbuttonclicktonotifyobservers

varexecute=function(){

observer.notify();

};

</script>

<body>

<div>

Specifysometext:<inputtype="text"id="txtEntered"/>

<inputtype="button"onclick="execute()"value="Notify"/>

</div>

<div>

<spanid="englishText"></span>

<spanid="frenchText"></span>

<spanid="arabicText"></span>

</div>

</body>

Intheaboveexample,wehavetakenascenariothattranslatesthetextforallthelanguagesaddedasobserverobjects.WeextendedtheObserverobjectanddefinedthreemethods,namelyaddObserver(),removeObserver(),andnotify()throughaprototype.Addingmethodsthroughaprototypeconsumeslessmemoryandeachmethodissharedamongallinstances.Thesemethodsarecreatedonceandtheninheritedbyeachinstance.Ontheotherhand,methodsthataredefinedinsidetheconstructorfunctionarecreatedeverytimethenewinstanceiscreatedandconsumemorememory.

TheaddObserver()methodisusedtoaddanyobjectinanobserverlist,removeObserver()isusedtoremoveaspecificobjectfromobserverlist,andnotify()executestheobserver'supdate()method.

EnglishTranslator,FrenchTranslatorandArabicTranslationareobjectsthathaveimplementedtheupdate()methodwhichiscalledwhennotify()isexecuted.Onpageloadwehaveregisteredallthetranslatorobjectsasobserversandprovidedatextboxwithabuttonthroughwhichtheusercantypeanytextonthetextboxandonabuttonclickeventitwillcalltheobserver'snotify()methodthateventuallycallstheregisteredobserver'supdate()method.

Page 313: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Pub/subpatternThepub/subpatternisanalternativepatterntotheobserverpatternwithaslightdifferenceinitsimplementation.Intheobserverpattern,theObserverobjectcaninvokethenotify()methodofalltheobservers,whereasinthepublisher/subscriberpattern,thereisacentralizedeventsystemwhichisusedtopublisheventstothesubscribers.Inthispattern,publishersandsubscribersarelooselytiedandneitherthepublishernorthesubscriberknowtowhomthemessagewassentorreceived.

Thefollowingexampleimplementsapub/subpatternthatholdsatwo-dimensionalarray.Theusercanaddeventsbasedonaneventnameandacallbackfunction.Ithasthreemethods:subscribe()tosubscribetoeventsinaneventsarray,unsubscribe()toremoveeventsfromanarray,andpublish()tocallthecallbackfunctionsforaspecificeventname:

Thefollowingisacodesnippettoimplementthepub/subpatterninJavaScript:

varPubSub=function(){

this.events=[];

this.subscribe=function(eventName,func){

this.events[eventName]=this.events[eventName]||[];

this.events[eventName].push(func);

};

this.unsubscribe=function(eventName,func){

if(this.events[eventName]){

for(i=0;i<this.events[eventName].length;i++){

if(this.events[eventName][i]===func){

this.events[eventName].splice(i,1);

break;

Page 314: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

}

}

};

this.publish=function(eventName,data){

console.log(data);

if(this.events[eventName]){

this.events[eventName].forEach(function(event){

event(data);

})

}

};

};

varexecute=(function(){

varpubSub=newPubSub();

pubSub.subscribe("myevent1",function(){

console.log("event1isoccurred");

});

pubSub.subscribe("myevent1",function(){

console.log("event1isoccurred");

});

pubSub.subscribe("myevent2",function(value){

console.log("event2isoccurred,valueis"+value);

});

pubSub.publish("myevent1",null);

pubSub.publish("myevent2","myeventtwo");

})();

Intheprecedingexample,wehaveonePubSubobjectthatprovidesthreemethodstosubscribe,unsubscribe,andpublishevents.TheSubscribe()methodisusedtosubscribeforanyeventandtakestwoparameters,theeventnameandfunction,andaddsthemtothearrayforaspecificeventname.Iftheeventnamedoesnotexistanewarraywillbeinitializedforthateventname,otherwisetheexistinginstancewillberetrievedtoaddtheitem.Theusercanregisterasmanyeventsastheywant,bypassingtheeventnameandtheanonymousfunctionbodythatwillbeexecutedwhentheeventispublished.Topublishevents,thepublish()methodcanbecalledthattakestheeventnameandthedatayouwanttopasstothecorrespondingfunction,whichhasbeenexecuted.

Page 315: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

PromisesPromisesareoneofthemostpopularpatternsextensivelyusedinJavaScriptAPIsandframeworkstomakeasynchronouscallssimpler.AnasynchronousoperationinJavaScriptneedstohaveacallbackfunctionregister,whichinvokeswhenthevalueisreturned.Withpromises,whenyoumakeanyasynchronouscall,itimmediatelyreturnsapromiseandprovidesobjectssuchasthenanddonetodefineafunctionwhentheresultantvalueisresolved.Intherealworld,promisesarejustlikeatokenorareceiptforthefoodyouorderinafastfoodrestaurant,andthatreceiptguaranteesyoutohavethefooddeliveredwhenitisready.Promisesaretokensthatconfirmyougetaresponsetoaspecificrequest:

InJavaScript,promisesarewidelyusedbyAPIsandframeworkssuchasAngularJS,Angular2,andmore.Let'shavealookatthefollowingexamplethatimplementsthepromisepattern:

//DefiningPromisethattakesafunctionasaparameter.

varPromise=function(func){

//Declaredmembervariable

varcallbackFn=null;

//Exposedonefunctionthatcanbeinvokedbytheobjectreturning

promise

//done()functiontakesacallbackfunctionwhichcanbedefinewhen

usingdonemethod.

this.done=function(callback){

callbackFn=callback;

};

functionresolve(value){

setTimeout(function(){

Page 316: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

callbackFn(value)

},3000)

}

//Hereweareactuallyexecutingthefunctiondefinedwheninitializing

thepromisebelow.

func(resolve);

}

//Objectthatisusedtoorderfoodandreturnsapromise

varorderFood=function(food){

//returnsthePromiseinstanceandpassanonymousfunctionthatcall

resolvemethodwhichactuallyservetherequestafterdelaying3seconds.

returnnewPromise(function(resolve){

resolve(food);

});

}

//InitializedorderFoodthatreturnspromise

varorder=neworderFood("GrilledBurger");

//Callingdonemethodwhichwillbeinvokedoncetheorderisready

order.done(function(value){

console.log(value);

});

Intheprecedingexample,wehavedevelopedaPromisefunctionthatcontainsdoneandresolvemethods,wheredoneisusedtoinvokethecallbackfunctionimplementedbytheconsumerobjectandresolveiscalledinternallytoexecutetheactualtask.ThesecondfunctionisorderFood,whichreturnsapromiseobjectandcallstheresolvemethodtoactuallyrunthetaskwhenorderFoodisinitializedbytheconsumer.Thefollowingsnapshotshowsthestepsofhowthiscodeisexecuted:

Page 317: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Ifyouhavenoticed,intheprecedingexamplewehaveusedthesetTimeout()functiontodelaytheresponsefor3seconds.WehavetousesetTimeout()torepresentanasynchronousscenariowheresetTimout()andtheregisteringofthedonecallbackhandlerareexecutedinparallel.

Theprecedingcodesnippetisaverybasicimplementationofapromisepattern.However,thereareotherpartsofthepromisepatternthatwecanimplementtomakeitrobust.Promiseshavestatesandthefollowingisthemodifiedversionthatnotonlymaintainsthestatesforinprogress,done,andfailedbutalsoprovidesthefailedhandlertocatchexceptions.Thefollowingisthedescriptionofthestates:

Inprogress:Whentheresolvemethodiscalledthestatewillbesettoinprogress.Thisstatewillpersistuntilweregisterthehandlersfordoneandfailedscenarios.Done:Whendoneisinvoked,thestatuswillbesettodone.

Page 318: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Failed:Whenanyexceptionoccurs,thestatuswillbesettofail.

ThefollowingisthemodifiedversionoftheorderFoodexample:

//DefiningPromisethattakesafunctionasaparameter.

varPromise=function(func){

//Defaultstatuswhenthepromiseiscreated

varstatus='inprogress';

varerror=null;

//Declaredmembervariable

vardoneCallbackFn=null;

varfailedCallbackFn=null;

//Exposedonefunctionthatcanbeinvokedbytheobjectreturning

promise

this.done=function(callback){

//Assigntheargumentvaluetolocalvariable

doneCallbackFn=callback;

if(status==="done"){

doneCallbackFn(data);

}else{

doneCallbackFn(status);

}

//returnpromisetoregisterdoneorfailedmethodsinchain

returnthis;

};

//Exposefailedfunctiontocatcherrors

this.failed=function(callback){

if(status==="failed"){

failedCallbackFn(error);

}

//returnpromiseinstancetoregisterdoneorfailedmethodsin

chain

returnthis;

};

functionprepareFood(){

setTimeout(function(){

status="done";

console.log("foodisprepared");

if(doneCallbackFn){

doneCallbackFn(data);

}

},3000);

}

functionresolve(value){

try{

//setthevalue

data=value;

//checkifdoneCallbackFnisdefined

Page 319: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

if(doneCallbackFn){

doneCallbackFn(value);

}

prepareFood();

}catch(error){

//setthestatustofailed

status="failed";

//settheexceptioninerror

error=error;

//checkiffailedCallbackFnisdefined

if(failedCallbackFn){

failedCallbackFn(value);

}

}

}

//Hereweareactuallyexecutingthefunctiondefinedwheninitializing

thepromisebelow.

func(resolve);

}

//Objectthatisusedtoorderfoodandreturnsapromise

varorderFood=function(food){

//returnsthePromiseinstanceandpassanonymousfunctionthatcall

resolvemethodwhich

//actuallyservetherequestafterdelaying3seconds.

returnnewPromise(function(resolve){

resolve(food);

});

}

//InitializedorderFoodthatreturnspromise

varorder=neworderFood("GrilledBurger").done(function(value){

console.log(value);}).failed(function(error){console.log(error);})

Page 320: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryInthischapter,wehavelearnedtheimportanceofdesignpatternsinsmall-to-largescaleapplicationsandhowwecanusethemeffectivelytoresolvespecificproblems.Wehavecoveredfourtypesofdesignpatternsforeachcategory,suchaswhencreatingobjects,structuringobjects,andaddingabehavioralchangeorstatestoobjects.Therearevariousmoredesignpatternsavailableanddocumented,whichcanbereferredtohere:http://www.dofactory.com/javascript/design-patterns.

Inthenextchapter,wewilllearnaboutNode.jsthatrunsJavaScriptontheserverside.WewillseehowwebapplicationscanbedevelopedinNode.jsusingVisualStudio2015andexploresomepopularframeworksandviewtheenginesitprovides.

Page 321: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter8.Node.jsforASP.NETDevelopersJavaScripthasbecomeoneofthemostprevalentlanguagesthatnotonlyrunsontheclientside,butalsorunsontheserversideaswell.Node.jsempowersJavaScripttorunontheserversideandprovidenon-blockingI/O,aneventdrivenmodelthatmakesitmorelightweight,scalableandefficient.Today,itismorewidelyusedinperformingreal-timeoperations,developingbusinessapplications,databaseoperations,andmore.JavaScriptonNode.jscanrelatetoASP.NETthatrunsonIISoranyotherwebserver.

Page 322: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

IntroductiontoNode.jsNode.jsisapowerfulplatformtobuildserver-sideapplicationsusingJavaScript.Node.jsitselfisnotwritteninJavaScriptbutprovidesaruntimeenvironmenttorunJavaScriptcode.ItallowsJavaScriptcodethatrunsontheserverside,providingtheruntimebuiltontheGoogleV8JavaScriptengine,whichisanopensourceJavaScriptenginewritteninC++,andusedbyGoogleChrome,tocompileJavaScriptcodeintomachinecode,atthetimeofexecutingthroughtheV8JITcompiler.

Node.jsworksonasinglethread;unlikeotherserver-sidetechnologiesthatcreateaseparatethreadforeachrequest,Node.jsusestheeventcallbacksystemthatprocessestherequestusingasinglethread.Ifmultiplerequestsarrivetheyhavetowaituntilthethreadbecomesavailableandthenacquireit.Inthecaseoferrors,Node.jsdoesnotthrowanerrorandthisisanessentialtechniquetoavoiderrorbubblingandtheabortionofthesinglethread.Ifanyerrorariseswhileservingarequest,Node.jssendstheerrorlog,inthecallbackparameters,intheresponseitself.Thisallowsthemainthreadtopropagatetheerroranddelaytheresponse.Node.jsisgoodforwritingnetworkapplications.ItconsistsofHTTPrequests,othernetworkcommunicationstasks,andreal-timeclient/servercommunicationsusingwebsockets.

Page 323: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

RequestprocessingbytheNode.jswebserverTheNode.jswebservermaintainsalimitedthreadpooltohandleclientrequests.Whentherequestgetstotheserver,theNode.jswebserverplacesthatrequestintoaneventqueue.Therequestisthenpickedupbytheeventloopcomponentthatworksinaninfiniteloopandprocessestherequestwhenitisfree.Thiseventloopcomponentissingle-threaded,andiftherequestinvolvesI/Oblockingoperationssuchasfilesystemaccess,databaseaccess,orothers,itcheckstheavailabilityofthethreadintheinternalthreadpoolandassignstherequesttotheavailablethread.Otherwise,itprocessestherequestandsendstheresponsebacktotheclientinasinglego.WhentheI/Oblockingrequestiscompletedbytheinternalthread,itsendstheresponsebacktotheeventloopfirst,whichsendstheresponsebacktotheclient.

Page 324: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ComparisonofNode.jswith.NETBothASP.NETandNode.jsareserver-sidetechnologies.ThefollowingdiagramshowsthecomparisonofNode.jswith.NET:

Page 325: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

NPMNodePackageManager(NPM)istheNode.jspackagemanagerusedtoinstallNodemodules.Node.jsprovidesawaytowritemodulesinJavaScript,andwithNPMwecanaddandreusethosemodulesinotherapplications.WithASP.NETCore,wealreadyusesomemodules,suchasGulpandGruntforminifyingtheCSSandJavaScriptfiles,anddoingcopyingandmergingoperations.Thepackage.jsonfileistheconfigurationfilethatholdsthemetadatainformationabouttheapplicationandNodemodulesusedinourproject.Hereisthesamplescreenshotofthepackage.jsonfile:

Dependenciescanbeinstalledbyexecutingthefollowingcommand:

npminstallNAME_OF_THE_PACKAGE–save

Example:

npminstallgulp–save

--saveisusedtoupdatethepackage.jsondependenciessectionandaddthepackagesdownloaded.

Page 326: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

InstallingNode.jsVisualStudioprovidesgreatsupportfordevelopingprogramsusingNode.js.ToconfiguretheNode.jsdevelopmentenvironmentontheWindowsplatform,downloadandinstallNode.jsfromhttp://nodejs.org.Therearevariousinstallersavailableaspertheplatform,asshowninthefollowingscreenshot:

ForWindows,wewilldownloadthe64-bitWindowsinstallerthatdownloadsthe.msipackageandtakeyouthroughsomesimplewizardscreens.YouwillnoticethattheNode.jsinstallercontainsaruntimetorunnodeprogramsandNPMtoreferenceotherNodemodulesinyourprogram.Thiscanbeseeninthefollowingscreenshot:

Page 327: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Commandssuchasnpmandnodearealreadyaddedintheenvironmentpathandwecanexecutethesecommandsdirectlyfromthecommandprompt.Therefore,ifweopenthecommandpromptandwritenode,itwillgiveyoutheNodeprompt,whichallowsyoutowriteJavaScriptcodeontheflyandexecute,asshowninthefollowingscreenshot:

Alternatively,wecanalsorunthe.jsfilebycallingnodejavascriptfile.js.

Page 328: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Thefollowingisthesampleexample1.jsfilethatsumsthenumbersdefinedinanarray:

console.log("NodeJsexample");

varnumbers=[100,20,29,96,55];

varsum=0;

for(i=0;i<numbers.length;i++)

{

sum+=numbers[i];

}

console.log("totalsumis"+sum);

Thefollowingistheoutput:

Page 329: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UsingNode.jswithVisualStudio2015TherearemanyIntegratedDevelopmentEnvironments(IDEs)availableinthemarketthathaveNode.jstoolingsupport.IDEssuchasVisualStudioCode,Sublime,KomodoandNodeEclipsearepopularIDEstoworkwithNode.js,butinpractice,most.NETdevelopersaremorecomfortableandfamiliarworkingwiththeVisualStudioIDE.Therefore,wewillbeusingtheVisualStudio2015Communityeditioninthischapter.

Node.jstemplatescanbeinstalledinVisualStudio2015byinstallingitsextensions.ExtensionscanbeinstalledfromtheVisualStudiomenuoptionTools|ExtensionsandUpdates:

ThisextensionofNode.jsisinstalledwithvarioustemplatestostartdevelopingapplicationsusingNode.js.ThereisatemplatetodevelopconsoleapplicationsusingtheblankNode.jsconsoleapplicationtemplate,awebapplicationusingNode.jsexpresstemplates,andsoon:

Page 330: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Thebasicadvantageofusingthesetemplatesistosavetimeinconfiguringthingsmanually,andthesetemplatesfacilitatedevelopersbyprovidingthebasicprojectstructuretokick-starttheNode.jsapplicationrightaway.

Let'sstartbycreatingabasicconsoleapplicationtemplate.Thebasicconsoleapplicationhasannpmfolder,containingnodepackages,package.jsonthatcontainsthemetadatainformationandotherconfigurationattributes,andapp.js,whichcontainsactualJavaScriptcode:

Page 331: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ThisextensionforNode.jsprovidesahandyfeatureforaddingNodemodulesbysimplyright-clickingonthenpmfolderandselectingtheInstallNewnpmPackagesoption,asshowninthefollowingscreenshot:

Onselectingthisoption,VisualStudioopensupthewindowthathelpstosearchanynodepackageandaddittoyourapplicationwithafewclicks:

Page 332: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

TheprecedingdiagramshowstheversionsofGulppackagesthatcanbeaddedthroughthisoption.

InteractiveWindowisanothernicefeatureinVisualStudio,whichopensupthecommandpromptintegratedintheVisualStudiotab,andyoucanwriteJavaScriptcodeandexecutecommandsinstantly,asshowninthefollowingscreenshot:

ThereareseveralotherbenefitsofusingVisualStudio:youcanusetheGitorTFSversionrepositories,debugyourcodeandenablebreakpointsonyourJavaScriptfiles,andsoon.TheVisualStudio-specificprojectfileforNode.jsisknownas.njsprojandresidesintherootfolderofyourproject.

Page 333: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SimpleconsoleapplicationusingNode.jsANode.jsapplicationconsistsofoneormoreJavaScriptfilesthatprovidespecificfunctionalitytotheapplication.WritingthousandsoflinesofcodeinoneJavaScriptfileisnotpracticallypossible,andalsoincreasesmaintainabilityissues.InNode.js,wecancreatemultipleJavaScriptfilesandusethemthroughrequireandexportobjects,whicharepartsoftheCommonJSmodulesystem:

export:usedtoexportvariables,functionsandobjects

//exportexample.js

module.exports.greeting="HelloWorld";

require:TousetheobjectsresidesindifferentJavaScriptfilesusingrequire

object.

//consumerexample.js–referencingthroughfile

varobj=require('./exportexample.js');

Alternativelywecanalsocallrequirewithoutspecifyingthe.jsfileextension,anditautomaticallyloadsthefilethatexistsonaparticularpath.Ifthepathcorrespondstoafolder,alltheJavaScriptfileswillbeloaded:

//consumerexample.js–referencingthroughfile

varobj=require('./exportexample');

Themainentrypointwhentheapplicationisbootstrappedisdefinedunderpackage.json.Inthefollowingscreenshot,app.jsisthemainentrypointfilethatisloadedfirstandexecutedbyNode.js:

Let'simplementabasicexamplethathastwofiles,namelyapp.js(mainentry)andcars.js,andreturnsafewpropertiesofthecarobject,suchasname,model,andengine.Tostart,createaconsoleapplicationprojectandaddonecars.jsfile.

Hereisthecodeforcars.js:

module.exports.cars=[

{name:"HondaAccord",model:"2016",engine:"V6"},

Page 334: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

{name:"BMWX6",model:"2015",engine:"V8"},

{name:"MercedezBenz",model:"2016",engine:"V12"}

];

Throughmodule.exports,wecanexportanyobject.Whetherit'savariable,afunction,oraJSONobject,itcanbeexportedthroughthis.Furthermore,theobjectsexportedcanbeusedthroughtherequireobjectinapp.js,asshowninthefollowingcode:

varcars=require('./cars.js');

console.log(cars);

Thefollowingistheoutput:

TheprecedingcodedisplaystheJSONoutputasdefinedinthecars.jsfile.Inordertoinitializethecarsobject,andloopthroughthecaritemsdefinedinthelist,weneedtoexportitasafunctionanddefineitthroughthethiskeyword.Specifyingitthroughthiswillmakethelistaccessiblefromthecarsobjectwecreateintheapp.jsfile.

Hereisthemodifiedversionofcars.js:

module.exports=function(){

this.carsList=

[

{name:"HondaAccord",model:"2016",engine:"V6"},

{name:"BMWX6",model:"2015",engine:"V8"},

{name:"MercedezBenz",model:"2016",engine:"V12"}

];

};

Andhereisthemodifiedversionoftheapp.jsfilethatinitializedthecarsobjectandloopsthroughthelist:

varcars=require('./cars.js');

varc=newcars();

varcarsList=c.carsList;

for(i=0;i<carsList.length;i++){

console.log(carsList[i].name);

}

Page 335: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WebapplicationswithNode.jsTherearevariousNode.jswebframeworksavailable.FrameworkssuchasExpressandHapi.jsarepowerfulframeworksandhavedifferentarchitecturesanddesigns.Inthissection,wewillusetheExpressframework,whichisoneofthemostwidelyusedwebframeworksforNode.js,forbothwebandmobileapplications,andalsoprovidestheapplicationframeworkmodeltodevelopwebApplicationProgrammingInterfaces(APIs).

Page 336: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CreatingblankNode.jsapplicationsAnextensionofNode.jsforVisualStudioprovidesvarioustemplatestodevelopwebapplications.WewillstartbycreatingablankNode.jswebapplication,asshowninthefollowingscreenshot:

AblankNode.jsapplicationtemplatecreatesoneserver.jsfileandsetsthemainattributeinthepackage.jsonfiletoloadserver.js.Thecontentofserver.jsisasfollows:

Page 337: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ThefirststatementaddsthedependencyofanhttpmoduleofNode.js,thesecondstatementistheportnumberatwhichtheserverwilllistenforHTTPrequests,andthethirdstatementcreatestheserverusinganhttpobject,onceitisstartedandreturnstheresponseasHelloWorld.Whentheserverstarts,arequestcanbemadebycallinghttp://localhost:1337.

Theprecedingcodesnippetchainsthelisten()methodthatactuallylistensfortheincomingrequests,andsendstheresponseusingtheres.end()method.Alternatively,wecanalsospecifythecontentwearereturningusingtheres.write()method.Hereisthemoresimplifiedversionofthesamecode,tounderstandhowthepiecesfittogether:

//Initializedhttpobject

varhttp=require('http');

//declaredport

varport=process.env.port||1337;

//Initializedhttpserverobjectanduseres.write()tosendactualresponse

content

varhttpServer=http.createServer(function(req,res){

res.writeHead(200,{'Content-Type':'text/plain'});

res.write('HelloWorld\n');

res.end();

});

//listeningforincomingrequest

httpServer.listen(port);

Page 338: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UsingtheExpressframeworkforwebapplicationsinNode.jsInanyprogramminglanguage,aframeworkhasanimportantbenefitthatminimizestheeffortrequiredtodevelopwebapplications.Theframeworkplaystheimportantroleofprocessingrequests,suchasloadingaspecificview,injectingmodelsintoaview,andmore.AswithASP.NET,wherewhavetwoweb-applicationframeworks,ASP.NETWebFormsandASP.NETMVC,Node.jsprovidesExpressEJS,Jade,andmanyotherwebapplicationframeworkstobuildrobustwebapplications.

ExtendsimpleNode.jstouseExpress

WiththeNode.jsextensionforVisualStudio,youcangetallthetemplatestostartworkingwiththeExpress3.0andExpress4.0applicationframeworks.Express4.0isthemostrecentversionandhassomenewfeaturesandimprovements.Wecanusethetemplatethatbootstrapsmostoftheconfiguration-levelstuffforyoubut,inordertogetmoreclarity,wewillextendthesimpleNode.jsexamplecreatedpreviously,andusetheExpressframeworktodevelopasimplewebapplicationontopofit.

TouseExpress,wehavetoadditspackagedependencyusingNPM,asshowninthefollowingscreenshot:

Page 339: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

OnceyouaddtheExpresspackage,youcanaddthefollowingcodesnippettokickstarttheExpressapp:

//Initializedhttpobject

varhttp=require('http');

//addingexpressdependency

varexpress=require('express');

//creatingexpressapplication

varexpressApp=express();

//Configuringrootcallwhere'/'representsrootpathoftheURL

expressApp.get("/",function(req,res){

res.send("<html><body><div>HelloWorld</div></body></html>");

});

//declaredport

varport=process.env.port||1337;

//Initializedhttpserverobjectanduseres.write()tosendactualresponse

content

varhttpServer=http.createServer(expressApp);

//listeningforincomingrequest

httpServer.listen(port);

ThisisasimpleHelloWorldexamplethatreturnstheHTMLcontent.Now,inscenarioswherewewanttoreturnaspecificviewinsteadofthestaticHTMLcontent,weachievethisbyusingExpressviewengines,whichwillbediscussednext.

Expressviewengines

Expresshasvariousviewengines,althoughJadeandEJSarethemostwidelyused.Wewillgothroughtheseonebyoneandseewhatthedifferencesare.

EJSviewengine

IntheEJSviewengine,viewsareHTMLpagesandthemodelpropertiescanbeboundusingscriptlets:<%%>.

TostartusingEJS,weneedtoaddtheEJSpackagethroughtheNPMpackagemanageroptioninVisualStudio,orbyexecutingthenpminstallejs–savecommand:

Page 340: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Oncethisisadded,wecansettheviewenginetoejs,asshowninthefollowingcodesnippet:

//Initializedhttpobject

varhttp=require('http');

//addingexpressdependency

varexpress=require('express');

//creatingexpressapplication

varexpressApp=express();

//SetjadeforNode.jsapplication

expressApp.set('viewengine','ejs')

Setthepathoftheejsviewbycallingtheresponseobjectrender()method,asshowninthefollowingcode:

//Configuringrootcallwhere'/'representsrootpathoftheURL

expressApp.get("/",function(req,res){

res.render("ejsviews/home/index");

});

Page 341: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Addtheindex.ejsfileinsidethehomefolder.AlltheviewsshouldresideundertherootViewsfolder,otherwisetheywon'tbeloadedwhentheapplicationisrun.Therefore,theejsviewsfoldershouldbedefinedundertheViewsfolderandhomeinsidetheejsviewsfolder,asshowninthefollowingscreenshot:

ThefollowingisthecontentoftheEJSviewthatwillberenderedwhentheapplicationstarts:

<html>

<body>

<div><h1>ThisisEJSView</h1></div>

</body>

</html>

Addthecodeatthebottomoftheejsserver.jsfilethatcreatestheserverwhichlistensforrequestsonportnumber1337:

//declaredport

varport=process.env.port||1337;

//Initializedhttpserverobjectanduseres.write()tosendactualresponse

content

varhttpServer=http.createServer(expressApp);

//listeningforincomingrequest

httpServer.listen(port);

Whentheapplicationruns,index.ejswillbeloadedandwillrendertheHTMLcontentasshowninthefollowingfigure:

WecanalsopassthemodelintherepresentationoftheJSONobject.Supposeweneedtopasstheapplicationnameanddescription;wecanpassthesevalueswhencallingarender()

Page 342: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

methodoftheresponseobject,asshowninthefollowingcode:

//Configuringrootcallwhere'/'representsrootpathoftheURL

expressApp.get("/",function(req,res){

res.render("ejsviews/home/index",{appName:"EJSDemo",message:"Thisisour

firstEJSviewengineexample!"});

});

Inindex.ejs,wecanuseandbindthesevalueswithHTMLcontrolsusingscriptlets:

<html>

<body>

<h1><%=appName%></h1>

<p><%=message%></p>

</body>

</html>

EJSalsosupportslayoutpagesthatcontainthestaticcontent,suchastheheaderandfooterofthewebapplication.So,adeveloperdoesn'tneedtodefinethemainlayoutcontentagainandagainoneverypage,andwecankeepitcentralized,justlikewedoinASP.NETMVCusing_layout.cshtmlandSite.masterinASP.NETwebforms.

Toworkwithmasterpages,weneedtoaddonemorepackage,knownasejs-local.ThispackagecanbeaddedusingtheNPMpackagemanagerwindowinVisualStudio,orbyrunningthenpmcommandasnpminstallejs-local--save:

Page 343: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Afteraddingthispackage,wecanaddejs-locals,asshowninthefollowingcode.Ithastobesetbeforesettingtheviewengine:

//Initializedhttpobject

varhttp=require('http');

//addingexpressdependency

varexpress=require('express');

varejsLocal=require('ejs-locals');

//creatingexpressapplication

varexpressApp=express();

//Addenginethatsupportsmasterpages

app.engine('ejs',ejsLocal);

Addthelayout.ejspageinthesameejsviewsfolderandspecifytheHTMLcontent:

<html>

<head>

<title><%=appName%></title>

Page 344: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

</head>

<body>

<%=body%>

</body>

</html>

Thecontentofthechildpagewillberenderedonthelinewherethebodyisdefinedinthelayoutpage,asshownintheprecedingcode.Hereisthecodesnippetoftheindex.ejsfile:

<%layout('../layout.ejs')-%>

<h1><%=appName%></h1>

<p><%=message%></p>

Thefollowingoutputisgenerated:

Jadeviewengine

TheJadeviewengineisanotherNode.jsviewengineandthesyntaxisquitedifferent,whendefiningviews,thanwehaveseeninEJS.TostartwiththeJadeviewengine,weneedtoinstalltheJadeviewenginenodepackageusingNPM.WecaninstallthisfromtheVisualStudioNPMpackagemanagerorbyrunningthenpminstalljade–savecommand:

Page 345: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Whenyouinstallit,itwilladdtheJadepackageinthepackage.jsondependenciessection.WewillstartbysettingtheJadeviewengineintheapp.jsfile(themainentrypointtokickstarttheNode.jsproject).

HereisthecodetosetuptheJadeviewengineinapp.js:

//addingexpressdependency

varexpress=require('express');

//creatingexpressapplication

varexpressApp=express();

//SetjadeforNode.jsapplication

expressApp.set('viewengine','jade');

YouwillnoticethatwehavenotspecifiedtheJadereferencethroughtherequireobject.ThisisbecausewhentheExpressframeworkisloaded,itwillautomaticallyregisterthedependenciesofJade.ThefollowingcodesnippetloadstheJadeview:

//Configuringrootcallwhere'/'representsrootpathoftheURL

Page 346: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

expressApp.get("/",function(req,res){

res.render("home/index",

{

appName:"JadeDemo",

message:"ThisisourfirstJadeviewengineexample!"

}

);

});

TheJadeviewsyntaxistypicallydifferentfromHTMLandalltheviewextensionsshouldbe.jade.Intheprecedingcode,wearepointingtoindex.jade,whereJadeisnotrequiredtobespecifiedexplicitly.Index.jadeshouldresideundertheviews/homefolder.Let'screateafoldercalledviewsandthenthehomefolderinsideit.AddanewJadefileandnameditindex.jade.HereisthecodethatdisplaystheappNameandmessageinHTMLelements:

doctype

html

body

h1=appName

p=message

WithJadesyntax,youdon'thavetodefinethecompleteHTMLtags,yousimplyspecifyitthroughtheirnames,followedbythevalueassignedtothem.Forexample,intheprecedingexample,wearesettingtheappNameandmessagevaluespassedasaJSONobjecttothisviewthroughtheresponserender()method.However,therearemanymoreattributesthatHTMLelementssupport,suchassettingcontrolwidth,fontcolor,fontstyle,andsoon.Inalatersection,wewillseehowwecanachievethisinJade.

Theequalto(=)operatorisonlyrequiredifyouarebindingtoanyvalueinjectingintotheview.Ifyouwanttospecifyahardcodedstaticvalue,thenitcaneasilybesetwithoutusingtheequaltooperator,asshowninthefollowingcode:

doctype

html

body

h1JadeApp

pThisisJadeView

HereareafewexamplesofusingJadesyntaxforHTML-specificscenarios:

Attributes Jade HTML

Textboxinput(type='text'

name='txtName')<inputtype='text'name='txtName'/>

Anchortaga(href='microsoft.com')

Microsoft<ahref="microsoft.com">Microsoft</a>

Page 347: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Checkboxinput(type='checkbox',

checked)

<inputtype="checkbox"

checked="checked"/>

Anchorwithstyleattributes

a(style={color:'green',

background:'black'})

<a

style="color:green;background:black">

</a>

Linkbuttoninput(type='button'

name='btn')<inputtype="button"name="btn"/>

YoucanlearnmoreabouttheJadelanguagehere:http://jade-lang.com/.

Jade'sframeworkalsosupportslayoutpages.Layoutpagesholdthestaticinformationofthewebsite,whichismostlyplacedintheheader,footer,orsidebars,andthecontentactuallychangesasperthepagerequested.InASP.Netwebforms,wedefinemasterpageswith<asp:ContentPlaceHolder>tags,whichrenderthecontentofthepagereferencetothatmasterpage.InASP.NETMVC,[email protected],wecandefinethecontentblockusingablockkeywordfollowedbythenameoftheblock.Forexample,thefollowingisthelayout.jadethatcontainstheblockcontentBlockstatement,whereblockrepresentswherethecontentofthechildpagerenders,andcontentBlockisthenameoftheblockthathastobedefinedinthechildpage.Multipleblockscanalsobedefinedinasingleview.

Thefollowingisthecontentofthelayoutpage:

doctypehtml

html

head

titleJadeApp

body

blockcontentBlock

Thelayoutpagecanbeusedwiththeextendskeywordfollowedbythelayoutpagename.TheJadeviewengineautomaticallysearchesthepagewiththatnameandifit'sfound,searchesfortheblocknameandplacesthecontentthere.Hereisthechildpageindex.jadethatusesthelayoutpagelayout.jade:

extendslayout

blockcontentBlock

h1=appName

p=message

Theoutputwillbeasfollows:

Page 348: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

RoutingintheExpressapplication

WehavenowlearnedthebasicsoftheEJSandJadeviewengines.Bothoffersimilarfeatures,butthesyntaxisdifferent.Inthepreviousexamples,wesentaresponsethatpointstoaspecificpagewhichrendersthecontentontheclientside.

TheExpressframeworkprovidesseveralmethodsthatcorrespondtoHTTPmethods,suchasget,post,put,delete,andsoon.Wecanusethegetmethodtoretrievesomething,posttocreatearecord,puttoupdate,andsoon.PagescanresideanywherewithintheViewsfolder,buttheroutingactuallydefineswhichpagehastobeloadedwhentherequestismadeonaspecificURLpath.

Let'screateanEJSpageinsidetheViews/ejsviews/homefolderandnameitabout.ejs.

RoutingcanbedefinedusingtheExpressapplicationobject,asshowninthefollowingcode:

expressApp.get("/About",function(req,res){

res.render("ejsviews/home/about");

});

Whentheuserbrowsestohttp://localhost/About,itshowstheAboutpage.

Page 349: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

MiddlewareNode.jsExpressalsoprovidesaspecialroutingmethod,all(),whichisnotmappedtoanyHTTPmethod.ButitisusedtoloadMiddlewareatapath,irrespectiveoftheHTTPmethodbeingrequested.Forexample,makingHTTPGETandPOSTrequestsathttp://localhost/middlewareexamplewillexecutethesameall()methodshowninthefollowingcode:

expressApp.all('/middlewareexample',function(req,res){

console.log('Accessingthesecret1section...');

});

Justlikein.NET,wehaveOWINmiddlewarethatcanbechainedintherequestpipeline.Inthesameway,Node.jsExpressmiddlewarecanalsobechainedandcanbeinvokedbycallingthenextmiddlewarewithalittlechangeinthefunctionsignature.Hereisthemodifiedversionthattakesthenextparameteraftertheresponseobjectwhichprovidesahandlertothenextmiddlewareinthepipeline,definedinasequenceforaparticularrequestpath:

expressApp.all('/middlewareexample',function(req,res,next){

console.log('Accessingthesecret1section...');

next();

});

Forexample,supposewehavetwomiddlewaresandthefirstmiddlewarejustlogstheinformationtotheconsolewindow,whereasthesecondreturnstheHTMLcontentbacktotheclient.Hereistheserver.jsfilethatcontainsthetwomiddlewaresintheEJSviewengine:

//Initializedhttpobject

varhttp=require('http');

//addingexpressdependency

varexpress=require('express');

//creatingexpressapplication

varexpressApp=express();

expressApp.all('/middlewareexample',function(req,res,next){

console.log('Middlewareexecutednowcallingnextmiddlewareinthe

pipeline');

next();//passcontroltothenexthandler

});

expressApp.all('/middlewareexample',function(req,res){

res.send("<html><body><div>Middlewareexecuted</div></body></html>");

});

//declaredport

varport=process.env.port||1337;

//Initializedhttpserverobjectanduseres.write()tosendactualresponse

content

varhttpServer=http.createServer(expressApp);

Page 350: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

//listeningforincomingrequest

httpServer.listen(port);

NowwhenweaccesstheURLpathhttp://localhost/middlewareexample,themessagewillbeprintedontheconsoleandrenderstheHTMLcontentinthebrowser:

HereistheHTMLcontentthatwillrenderinthebrowser:

Page 351: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

MVCwiththeExpressframeworkAlmosteveryapplicationconsistsofnumerouspages,anddefiningallthelogicandroutingonthemainserver.jsisnotpracticalormaintainable.Inthissection,wewillseehowtheModelViewController(MVC)patterncanbeimplementedwiththeExpressframework.Wewilldevelopasimpleapplicationtoseehowcontrollersanddataservicescanbedeveloped,andhowthecontrollerloadstheviewandinjectsthemodelusingtheExpressframework.

Page 352: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

MVCpatternMVCisasoftwarearchitecturalpatternusedtoseparateanapplication'sconcerns.Themodelrepresentstheentitythatcontainspropertiestoholdinformation,whereasthecontrollerisusedtoinjectthemodelintotheviewandloadtheview.Thecontrollerisalsousedtostorethemodelinthedatabase,whereastheviewisthepagethatrendersthemodelinjectedbythecontrollerandusesitwhereverneeded.

Creatingacontroller

WewillstartbycreatingasimplehomeControllertorenderahomepage.Let'sextendtheEJSviewengineexampledevelopedabove,andcreateaControllersfolderattherootofyourproject.InsidetheControllersfolder,createaHomeController.jsfileandplacethefollowingcodesnippetthere:

(function(homeController){

homeController.load=function(expressApp){

expressApp.get('/',function(req,res){

res.render("ejsviews/home/index",{appName:"EJSApplication",

message:"EJSMVCImplementation"})

});

};

})(module.exports);

Intheprecedingcode,thereisananonymousJavaScriptfunctionthattakesthemodule.exportobjectandbindsittothehomeControllerwhenitisexecuted.ThebasicadvantageofimplementingitinthiswayisthateverymethodorpropertydefinedwiththehomeControllerobjectwillbeexportableandaccessiblebythecallingobject.Intheprecedingexample,wehavedefinedaload()methodthatdefinestheroutingattherootpath(/)andreturnstheIndexpagetotheclient.

Inthemainejsserver.jsfile,wecanusethecontrollerbyusingtherequireobjectasshowninthefollowingcode:

//Initializedhttpobject

varhttp=require('http');

//addingexpressdependency

varexpress=require('express');

//addingejslocals

varejsLocal=require('ejs-locals');

//creatingexpressapplication

varexpressApp=express();

//Addenginethatsupportsmasterpages

expressApp.engine('ejs',ejsLocal);

//SetjadeforNode.jsapplication

expressApp.set('viewengine','ejs');

Page 353: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

//InitializingHomeController

varhomeController=require('./Controllers/HomeContoller.js');

homeController.load(expressApp);

//declaredport

varport=process.env.port||1337;

//Initializedhttpserverobjectanduseres.write()tosendactualresponse

content

varhttpServer=http.createServer(expressApp);

//listeningforincomingrequest

httpServer.listen(port);

Intheprecedingcode,wehaveaddedtheHomeControllerobjectusingtherequireobjectandcalledtheload()methodtodefinetheroutingthatnavigatestotheindexpagewhenthewebsiteruns.

Creatingdataservices

EverybusinessapplicationinvolveslotsofCRUD(create,read,update,anddelete)operations.Forabetterdesign,theseoperationscanbeseparatelyimplementedindataserviceobjects,soifmultiplecontrollerswantedtousethesameservice,theycanusethemwithoutwritingthesamecoderepeatedly.Inthissection,wewillcreateadataserviceJavaScriptfilethatreadsthedataandpassesitintheroutingfunction.Tostartwith,let'screateafoldernameDataServicesattherootoftheapplicationandcreateProductService.jsinsideit.HereisthecodeforProductService.js,whichreturnstheproductsarray:

(function(data){

data.getProducts=function(){

return[{

name:'Product1',

price:200,

},

{

name:'Product2',

price:500

},

{

name:'Product3',

price:1000

}

];

};

})(module.exports);

WecanusethisProductServiceinsideHomeControllerthroughtherequireobject:

(function(homeController){

varproductService=require('../DataServices/ProductService');

homeController.load=function(expressApp){

Page 354: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

expressApp.get('/',function(req,res){

varproducts=productService.getProducts();

res.render("ejsviews/home/index",{appName:"EJSApplication",

message:"EJSMVCImplementation",data:products});

});

};

})(module.exports);

Andhereistheindex.ejsfile,whichloopsthroughtheproductsanddisplaystheproductnameandprice:

<%layout('../layout.ejs')-%>

<h1><%=appName%></h1>

<p><%=message%></p>

<div>

<%data.forEach(function(product){%>

<li><%=product.name%>-<%=product.price%></li>

<%});%>

</div>

Finally,theoutputlookslikethefollowing:

Page 355: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AccessingtheMicrosoftSQLserverinNode.jsNode.jsprovidesdifferentdatabasedriversthatcanbeaddedasnodepackages.TherearepackagesfortheMongoDBdriver,theMicrosoftSQLServerdriver,andmore.WewillusetheMSSQLdriverforNode.jstoconnectwithMicrosoftSQLserverdatabases.Toinstallmssqlyoucanrunthenpminstallmssql–savecommand,oradditfromtheNPMpackagemanagerwindow,asshowninthefollowingscreenshot:

Tip

WiththeMSSQLdriver,TCP/IPshouldbeenabledforacorrespondingSQLserverinstance.

Page 356: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ReadingarecordfromtheMicrosoftSQLserverdatabaseIntheDataService.jsfile,wewilladdthegetProducts()method,whichloadsthelistofproductsfromtheSQLServerdatabase.

ThefollowingisthegetProducts()method,whichacceptsthecallbackfunction,soassoontheproductslistisfetchedfromthedatabase,itwillbepassedinthecallbackfunctiononthecallerside:

(function(data){

data.getRecords=function(callbackFn){

//loadedSQLobject

varsql=require('mssql');

//databaseconfigurationattributestoconnect

varconfig={

user:'sa',

password:'123',

server:'ovais-pc',//Youcanuse'localhost\\instance'toconnect

tonamedinstance

database:'products'

}

varproducts=null;

//ConnecttoSQLServerreturnsapromiseandonsuccessfullconnection

executingaqueryusingRequestobject

sql.connect(config).then(function(){

newsql.Request().query('select*fromproducts',function(err,

recordset){

callbackFn(recordset);

});

});

};

})(module.exports);

Intheprecedingcode,weinitializedthesqlobjectusingtherequireobject.TheConfigvariablecontainstheconnectionattributes,suchasusername,password,server,anddatabase.Thisispassedwhilecallingthesqlconnect()method.TheConnect()methodreturnsathen()promise,throughwhichwecaninitiatetheSQLqueryrequestusingthesql.Request()method.Iftherequestissuccessful,wewillgettheresultsetintherecordsetobjectthatwillbereturnedtothecallerthroughitscallbackfunction.

HereisthemodifiedversionofHomeController.jsthatcallstheDataServicegetRecords()methodandpassestheproductslistretrievedasamodeltotheindexview:

(function(homeController){

varproductService=require('../DataServices/ProductService');

homeController.load=function(expressApp){

expressApp.get('/',function(req,res){

Page 357: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

varproducts=productService.getRecords(function(products){

console.dir(products);

res.render("ejsviews/home/index",{appName:"EJSApplication",

message:"EJSMVCImplementation",data:products});

});

});

};

})(module.exports);

Thefollowingistheindex.jsfile,whichloopsthroughthelistofproductsanddisplaystheproductnameandprice:

<%layout('../layout.ejs')-%>

<h1><%=appName%></h1>

<p><%=message%></p>

<table>

<th>

<td>ProductName</td>

<td>Description</td>

<td>Price</td>

</th>

<%data.forEach(function(product){%>

<tr><td><%=product.Name%></td><td><%=product.Description%></td><td>

<%=product.Price%></td></tr>

<%});%>

</table>

Page 358: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CreatingarecordintheMicrosoftSQLserverdatabaseTocreatearecordinthedatabase,wecandefinetheHTMLinputelementswrappedwithintheHTMLformtag,andonsubmissionoftheform,wecanmakeapostrequestbydefiningapostmethodinourHomeController.jsfile.Whentheformissubmitted,thevaluescanberetrievedusingtherequest.bodyobject.ThisistheparserthatparsestheDOMandmakesalistofelementswrappedundertheformtag.Wecanaccessitlikereq.body.txtName,wheretxtNameistheHTMLinputelementandreqistherequestobject.

Express4.0unbundledthebody-parserobjectintoaseparatepackageandcanbedownloadedseparatelyusingthenpminstallbody-parser–savecommandorthroughtheNPMpackagemanagerwindow,asshowninthefollowingscreenshot:

Inyourmainejsserver.jsfile,addthebody-parserusingtherequireobjectandpassitintheexpressAppobjectbycallingtheexpressApp,use()method:

varbodyParser=require('body-parser');

Page 359: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

expressApp.use(newbodyParser());

Oncethisisadded,wecanmodifyHomeController.jsanddefineaPOSTmethodthatwillbecalledoncetheformissubmitted:

expressApp.post('/',function(req,res){

console.log(req.body.txtName);

productService.saveProduct(req.body.txtName,req.body.txtDescription,

req.body.txtPrice,function(result){

res.send("Recordsavedsuccessfully");

});

});

TheprecedingmethodcallsthedataservicesaveProduct()methodandpassesthevaluesfilledbytheuserasparameters.Thelastparameteristhecallbackfunction,whichwillbeexecutediftherecordsavedsuccessfully.HereisthesaveProductcodesnippetoftheDataService.jsfile:

data.saveProduct=function(name,description,price,callbackFn){

//loadedSQLobject

varsql=require('mssql');

//databaseconfigurationattributestoconnect

varconfig={

user:'sa',

password:'123',

server:'ovais-pc',//Youcanuse'localhost\\instance'toconnect

tonamedinstance

database:'products'

}

//ConnecttoSQLServerreturnsapromiseandonsuccessfullconnection

executingaqueryusingRequestobject

sql.connect(config).then(function(){

newsql.Request().query("INSERTintoproducts(Name,Description,

Price)values('"+name+"','"+description+"',"+price+")",function(err,

recordset){

callbackFn(recordset);

});

});

};

Andfinally,hereistheIndex.ejsviewthatcontainsaformwiththeName,Description,andPricefields:

<formmethod="post">

<table>

<tr>

<td>ProductName:</td>

<td><inputtype='text'name='txtName'/></td>

</tr>

<tr>

Page 360: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

<td>Description:</td>

<td><inputtype='text'name='txtDescription'/></td>

</tr>

<tr>

<td>Price:</td>

<td><inputtype='number'name='txtPrice'/></td>

</tr>

<tr>

<td>&nbsp;</td>

<td><inputtype="submit"value="Save"/></td>

</tr>

</table>

</form>

Tolearnmoreaboutthemssqlnodepackage,pleaseusethislink:https://www.npmjs.com/package/mssql.

Page 361: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryThischapterfocusedonthebasicsofNode.jsandhowtousethemindevelopingserver-sideapplicationsusingJavaScript.Wehavelearnedabouttwoviewengines,EJSandJade,andhowtousethem.WehavealsolearnedtheusageofcontrollersandservicestoimplementanMVCpattern.Andfinally,wefinishedbylookingatexamplesofaccessingtheMicrosoftSQLserverdatabasetoperform,create,andretrieveoperationsonadatabase.Inthenextchapter,wewillfocusonbestpracticesforusingJavaScriptinlarge-scaleapplications.

Page 362: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter9.UsingJavaScriptforLarge-ScaleProjectsLarge-scalewebapplicationprojectscompriseofseveralmodules.WithcontinuousimprovementsandadvancementsinthedevelopmentofvariousJavaScriptframeworks,developersuseJavaScriptfrequentlyinanapplication'spresentationorfrontendlayer,andserver-sideoperationsareonlyperformedwhenrequired.Forexample,whensavingorreadingthedatafromserverordoingsomeotherdatabaseorbackendoperations,anHTTPrequestismadetotheserverthatreturnstheplainJSONobjectandupdatestheDOMelements.Withthesedevelopmentsinplace,mostoftheapplicationfrontendcoderesidesontheclientside.However,whenJavaScriptwasfirstdeveloped,itwastargetedtobeusedfordoingsomebasicoperations,suchasupdatingtheDOMelementsorshowingconfirmdialogsandotherrelativeoperations.TheJavaScriptcodemostlyexistsonthepageitselfwithinthe<script>scriptingtag.However,large-scaleapplicationsconsistofmanylinesofcodeandneedproperattentionwhendesigningandarchitectingthefrontend.Inthischapter,wewilldiscussafewconceptsandbestpracticesthathelptomaketheapplicationfrontendmorescalableandmaintainable.

Page 363: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ThinkbeforeproceedingLarge-scaleapplicationsconsistofmanyJavaScriptfilesandproperstructuringofthesefilesbringsgreatervisibility.JavaScriptframeworkssuchasAngularJS,EmberJS,andothersalreadyprovideproperstructuringandguidelinestodefinecontrollers,factories,andotherobjects,aswellasprovidebestpracticesofusingthem.Theseframeworksareverypopularandalreadyadheretotheproblemofhigherscalabilityandmaintainability.However,therearecertainscenarioswherewewanttostrictlyrelyonplainJavaScriptfilesandmaydevelopourowncustomframeworktoremedyparticularrequirements.Toacknowledgethese,therearecertainbestindustry-widepracticesbeingused,whichmakeourJavaScript-basedfrontendmoremaintainableandscalable.

Whenworkingonlargescaleapplications,weneedtothinkaheadofwhatthescopeoftheapplicationisallabout.Weneedtothinkhoweasilyourapplicationcanbeextendedandhowquicklytheincorporationofothermodulesorfunctionalitycanbeachieved.Ifanymodulefails,woulditaffectthebehavioroftheapplicationorcrashothermodules?Forexample,ifweareusinganythird-partyJavaScriptlibrarythatmodifysomeoftheirmethod'ssignatures.Inthiscase,ifanythird-partylibraryisusedfrequentlyeverywhereinourapplication,wehavetomodifythemethodateachpoint,anditmaybeacumbersomeprocesstonotonlychange,butalsotest.Ontheotherhand,ifsomeFacadeorwrapperhasbeenimplemented,itwouldonlyrequireustochangeatoneplaceinsteadofupdatingiteverywhere.Therefore,designinganapplicationarchitectureorframeworkisathoughtfulprocess,butitmakestheapplicationmorerobustandhealthy.

Page 364: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DevelopinghighlyscalableandmaintainableapplicationsThefollowingarethefactorsthatweshouldconsidertomakehighlyscalableandmaintainablewebapplicationsthatrelyheavilyonJavaScript.

Page 365: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ModularizationWithbigapplications,writingeverythinginasingleJavaScriptfileisnotagoodpractice.Nonetheless,evenifyouhaveseparateJavaScriptfilesfordifferentmodulesandreferencingthemthroughthescripting<script>tagbloatstheglobalnamespace.AproperstructuringshouldbedonetokeepJavaScriptfilesintoseparatemodule-wisefolders.Forexample,anERPapplicationconsistsofseveralmodules.WecancreateseparatefoldersforeachmoduleandusespecificJavaScriptfilestoprovidecertainfunctionalityforspecificviewsorpages.However,thecommonfilescanresideinthecommonfolder.

HereisthesampleprojectstructuringtoarrangeJavaScriptfilesbasedonanERPmodule.Eachmodulehasaservicefolderthatcontainssomefilestodosomereadorwriteoperationsontheserverside,andtheViewsfoldertomanipulateDOMelementsofspecificviewsoncethedataisloadedoranycontroleventisinvoked.Thecommonfoldermaycontainallthehelperutilitiesandfunctionsthatareusedbyalltheothermodules.Forexample,tologmessagesonconsole,ormakeanHTTPrequestontheserverside,functionscanbedefinedinthecommonJavaScriptfilesandtheycanbeusedbytheservicesorviewJavaScriptfiles:

Intheprecedingstructure,theServicesfoldercanhavethefunctionsrelatedtoperformcreate,retrieve,update,anddelete(CRUD)operationsonthedatabasebycallingsomeWebAPIorwebservices,whereasaviewfilesuchasFIMain.jscontainspage-specific

Page 366: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

function.

TomakeanHTMLpageclean,itisabetterapproachtokeepJavaScriptfilesseparatefromtheHTMLpage.Sointheprecedingscreenshot,FIMain.jscontainstheJavaScriptfunctioncorrespondingtothemainpage,whereasFIDashboard.jscontainstheJavaScriptfunctioncorrespondingtothedashboardpage,andsoon.

Thesefilescansimplybeaddedthroughthe<script>scriptingtag,butinJavaScriptworld,addingJavaScriptfilesdirectlyonthepageitselfisnotgoodpractice.ModulescanbedefinedinJavaScriptbyimplementingamodulepattern.However,mostlydeveloperspreferusingRequireJSAPItodefinemodulestomakemoduleloadingsimplerandprovideabetterscopingofvariablesandfunctionsdefinedinthismodule.ItisequivalenttotheCommonJSsystem,butitisrecommendedbecauseofanasynchronousbehavior.ItloadstheJavaScriptmodulesinanasynchronouswayandmakethepage-loadcyclefaster.

Implementingthemodulepattern

Amodulepatternisthemostprevailingdesignpatternusedforcreatingloose-coupledarchitectureandkeepingthepiecesofJavaScriptcodeindependentofothermodules.

Modulesarejustlike.NETclassesthatcanhaveprivate,protected,andpublicpropertiesandmethodsandprovidecontroltothedevelopertoexposeonlythosemethodsorpropertiesthatareneededbyotherclasses.

InJavaScript,amodulepatterncanbeimplementedusingimmediatelyinvokedfunctionexpression(IIFE)thatexecutesimmediatelyandreturnsaclosure.Closureactuallyhidesprivatevariablesandmethodsandreturnsanobjectthatcontainsonlythosemethodsorvariablesthatarepublicandareaccessiblebyothermodules.

HereistheLoggermodulethatexposedalogMessage()method,whichcallsoneprivateformatMessage()methodtoappenddateandreturnstheformattedmessagethatisthenprintedoutonabrowser'sConsolewindow:

<script>

varLogger=(function(){

//privatemethod

varformatMessage=function(message){

returnmessage+"loggedat:"+newDate();

}

return{

//publicmethod

logMessage:function(message){

console.log(formatMessage(message));

}

};

})();

Page 367: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Logger.logMessage("helloworld");

</script>

Intheprecedingcode,thelogMessage()methodreturnsanobjectthatisinvokedthroughaLoggernamespace.

Amodulecancontainmultiplemethodsandproperties,andtoimplementthisscenario,let'smodifytheprecedingexampleandaddonemoremethodtoshowalertmessageandapropertytoaccesstheloggernameandexposethemthroughanobjectliteralsyntax.Objectliteralisanotherrepresentationofbindingmethodsandpropertiesasnamevaluepairsseparatedbycommasandoffersacleanerrepresentation.Hereisthemodifiedcode:

<script>

varLogger=(function(){

//privatevariable

varloggerName="AppLogger";

//privatemethod

varformatMessage=function(message){

returnmessage+"loggedat:"+newDate();

}

//privatemethod

varlogMessage=function(message){

console.log(formatMessage(message));

}

//privatemethod

varshowAlert=function(message){

alert(formatMessage(message));

}

return{

//publicmethodsandvariable

logConsoleMessage:logMessage,

showAlertMessage:showAlert,

loggerName:loggerName

};

})();

Logger.logConsoleMessage("HelloWorld");

Logger.showAlertMessage("HelloWorld");

console.log(Logger.loggerName);

</script>

Intheprecedingcode,logMessage()andshowAlert()willbeaccessiblethroughlogConsoleMessage()andshowAlertMessage()methods.

ModularizingJavaScriptcodethroughRequireJS

Page 368: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ModulesinRequireJSareanextensionofthemodulepatternwiththebenefitofnotneedingglobalstorefertoothermodules.RequireJSisaJavaScriptAPItodefinemodulesandloadthemasynchronouslywhentheyarerequired.ItdownloadstheJavaScriptfilesasynchronouslyandreducesthetimetoloadthewholepage.

CreatingmodulesusingtheRequireJSAPI

AmoduleinRequireJScanbecreatedusingthedefine()methodandloadedusingtherequire()method.RequireJSprovidestwosyntaxstylestodefinemodulesthatareasfollows:

DefiningmoduleinCommonJSstyle:HereisthecodesnippettodefinethemoduleintheCommonJSstyle:

define(function(require,exports,module){

//requiretouseanyexistingmodule

varutility=require('utility');

//exportstoexportvalues

exports.example="CommonJS";

//moduletoexportvalues

module.exports.name="Largescaleapplications";

module.exports.showMessage=function(message){

alert(utility.formatMessage(message));

}

});

TheprecedingCommonJSstylesyntaxusesthedefine()methodofRequireJSAPIthattakesafunction.Thisfunctiontakesthreeparameters:require,exports,andmodule.Thelasttwoparameters,exportsandmodule,areoptional.However,theyhavetobedefinedinthesamesequence.Ifyouarenotusingrequire,andonlywantedtoexportsomefunctionalityusingtheexportsobject,therequireparameterneedstobeprovided.Therequireparameterisusedtoimportmodulesthatwereexportedusingexportsormodule.exportsinothermodules.Intheprecedingcode,wehaveaddedthedependencyoftheutilitymodulebyspecifyingthepathoftheutility.jsfileincallingtherequiremethod.Whenaddinganydependency,wejustneedtospecifythepathfollowedwiththefilenameoftheJavaScriptfileandnotthe.jsfileextension.ThefileisautomaticallypickedbytheRequireJSAPI.Exportinganyfunctionorvariablethatweneedtobeusedbyothermodulescanbedonethroughexportsormodule.exportsappropriately.DefiningmoduleinAMDstyle:HereisthecodesnippettodefinethemoduleinanAMD-stylesyntax:

define(['utility'],function(utility){

return{

example:"AMD",

name:"Largescaleapplications",

showMessage:function(){

Page 369: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

alert(utility.formatMessage(message));

}

}

});

TheAMD-stylesyntaxtakesthedependenciesarrayasthefirstparameter.ToloadthemoduledependenciesinanAMD-stylesyntaxyouhavetodefinetheminanarray.Thesecondparametertakesthefunctionparameter,takingthemodulenamethatmapstothemoduledefinedinthedependenciesarraysothatitcanbeusedinthefunctionbody.Toexportthevariablesormethods,wecanexportthemthroughtheobjectliteralsyntax.

BootstrappingRequireJS

Let'sgothroughasimpleexampletounderstandtheconceptsofusingRequireJSinanASP.NETapplication.TousetheRequireJSAPIintheASP.NETCoreapplication,youhavetodownloadandplacetheRequire.jsfileinthewwwroot/jsfolder.Inthefollowingexample,wewillwritealoggingmodulethatcontainsafewmethodssuchaswritingtoconsole,showinganalert,andwritingontheserver.

Let'screatetheLogging.jsfileinthewwwroot/js/commonfolderandwritethefollowingcode:

define(function(){

return{

showMessage:function(message){

alert(message);

},

writeToConsole:function(message){

console.log(message);

},

writeToServer:function(message){

//writetoserverbydoingsomeAjaxrequest

varxhr=newXMLHttpRequest();

xhttp.open("POST","http://localhost:8081/Logging?message="+message,true);

xhttp.send();

}

}

});

ThefollowingisthecodefortheIndex.cshtmlpagethatdisplaysanalertmessagewhenthepageisloaded:

<scriptsrc="~/js/require.js"></script>

<script>

(function(){

require(["js/common/logging"],function(logging){

logging.showMessage("demo");

});

})();

</script>

Wecanalsowraptheprecedingfunctioninthemain.jsfileandbootstrapitthroughthe

Page 370: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

scripting<script>tag.Thereisonespecialattributeknownasdata-main,whichisusedbyRequireJSastheentrypointoftheapplication.

Thefollowingisthecodeformain.jsthatresidesunderthewwwroot/JSfolder.Asmain.jsresidesunderthewwwroot/jsfolder,thepathwillbecommon/logging:

//Main.js

require(["common/logging"],function(logging){

logging.showMessage("demo");

});

Finally,wecanbootstrapmain.jsusingscriptingtag,asshowninthefollowingcode:

<scriptdata-main="~/js/main.js"src="~/js/require.js"></script>

ThefollowingisthesampleprojectstructurecontainingtheCommonfoldertohavecommonJavaScriptfiles;whereas,FIandHRfoldersformodule-specificJavaScriptfiles:

Supposewewanttomodifytheprecedingexampleandpassthemessagefromaninputcontrolonabutton'sclickevent.Thiscanbedonebydevelopingaviewmoduleforaparticularpageandinjectingtheloggingmoduleinsideit.

ThefollowingistheHTMLmarkupcontaininginputandbuttonelements:

<divid="myCarousel"class="carouselslide"data-ride="carousel"data-

interval="6000">

<inputtype="text"id="txtMessage"/>

<buttonid="btnSendMessage">SendMessage</button>

</div>

Thefollowingistheview.jsfilethattakestheloggingmoduleandcallitssendMessage()methodbyreadingthetxtMessageelementvalue:

define(['common/logging'],function(logging){

$('#btnSendMessage').on('click',function(e){

sendMessage();

Page 371: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

e.preventDefault();

});

functionsendMessage(){

varmessage=document.getElementById('txtMessage').value;

logging.showMessage(message);

}

return{

sendMessage:sendMessage

};

});

Whenthebuttonisclicked,analertmessagewillbedisplayed.

Page 372: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Event-drivenmessagingIntheprecedingsection,weenabledthemodularizationsupportforJavaScriptfilesandconvertedthemintomodules.Inlargeapplications,wecannotjustrelyoninjectingthemodulesinothermodules,wemayneedsomeflexibilitytoinvokeeventsofcertainmodulesthroughsomethePub/Subpattern.WehavealreadyseenthePub/SubpatterninChapter7,JavaScriptDesignPatterns,whichmaintainsacentralizedlisttoregistereventsthatpointtosomecallbackfunctionsandareinvokedthroughapublisherobject.Thispatternisveryusefulwhenenablingevent-drivenmessagingbetweenmodules,butthereisanotherbetterpatternknownasamediatorpattern,whichisasupersetofthePub/Subpattern.Themediatorpatternisbetterasitallowspublishersormediatorstoaccessotherevents/methodsofthesubscribedobjectandallowsthemediatortodecidethemethodoreventthatisneededtobecalled.

Implementingmediatorpatternforcommunicationbetweenmodules

Mediatorencapsulatesobjectsinacentralizedlistandusesthembyinvokingtheirmethods.Thislistkeepsalltheobjects(ormodules)atcentrallocation,thusallowingimprovedcommunicationbetweenthem.

Let'sgothroughapracticalexampleofimplementingthemediatorpattern.Themediatoractsasacentralizedcontrollingobjectwheremodulescansubscribeorunsubscribe.Itprovidesabstractmethodsthatcanbeinvokedbyanyofthesourcesubscribermoduletocommunicatewiththetargetsubscribermodule.Themediatorholdsacentralizeddictionaryobjecttoholdsubscriberobjectsbasedonsomekey,ormostlyname,andinvokestargetmodulemethodbasedonthemodulenamepassedbythesubscriber.Inthefollowingexample,wehaveMediatorCore(mediator),EmployeeRepository(subscriber),andHRModule(subscriber)objects.WewillusetheRequireJSAPItoconvertJavaScriptfilesintomodules.

ThefollowingistheMediatorCoreJavaScriptfile:

//MediatorCore.js

define(function(){

return{

mediator:function(){

this.modules=[];

//Tosubscribemodule

this.subscribe=function(module){

//Checkifmoduleexistorinitializearray

this.modules[module.moduleName]=this.modules[module.moduleName]||[];

//Addthemoduleobjectbasedonitsmodulename

this.modules[module.moduleName].push(module);

module.mediator=this;

},

this.unsubscribe=function(module){

Page 373: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

//Loopthroughthearrayandremovethemodule

if(this.modules[module.moduleName]){

for(i=0;i<this.modules[module.moduleName].length;i++){

if(this.modules[module.moduleName][i]===module){

this.modules[module.moduleName].splice(i,1);

break;

}

}

}

},

/*TocallthegetRecordsmethodofspecificmodulebasedonmodulename

*/

this.getRecords=function(moduleName){

if(this.modules[moduleName]){

//getthemodulebasedonmodulename

varfromModule=this.modules[moduleName][0];

returnfromModule.getRecords();

}

},

/*TocalltheinsertRecordmethodofspecificmodulebasedonmodulename

*/

this.insertRecord=function(record,moduleName){

if(this.modules[moduleName]){

//getthemodulebasedonmodulename

varfromModule=this.modules[moduleName][0];

fromModule.insertRecord(record);

}

},

/*TocallthedeleteRecordmethodofspecificmodulebasedonmodulename

*/

this.deleteRecord=function(record,moduleName){

if(this.modules[moduleName]){

//getthemodulebasedonmodulename

varfromModule=this.modules[moduleName][0];

fromModule.deleteRecord(record);

}

},

/*TocalltheupdateRecordmethodofspecificmodulebasedonmodulename

*/

this.updateRecord=function(record,moduleName){

if(this.modules[moduleName]){

//getthemodulebasedonmodulename

varfromModule=this.modules[moduleName][0];

fromModule.updateRecord(record);

}

}

}

}

});

Page 374: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ThismediatorexposesfourmethodstoperformCRUDoperations.ThisexampleshowcasesasimpleHRmodulethatusescertainrepositoriestodocertainoperations.Forexample,theHRmodulecanhavetheEmployeeRepositorymoduletosaverecordinemployee-specifictables,DepartmentRepositorytodooperationsspecifictodepartment,andsoon.

HereisthecodesnippetforEmployeeRepositorythatcontainstheconcreteimplementationoftheabstractmethodsdefinedinthemediator:

//EmployeeRepository.js

define(function(){

return{

//ConcreteImplementationofMediatorInterface

EmployeeRepository:function(uniqueName){

this.moduleName=uniqueName;

//thisreferencewillbeusedjustincasetocallsomeothermodule

methods

this.mediator=null;

//ConcreteImplementationofgetRecordsmethod

this.getRecords=function(){

//Callsomeservicetogetrecords

//SampletexttoreturndatawhengetRecordsmethodwillbeinvoked

return"Thisaretestrecords";

},

//ConcreteImplementationofinsertRecordmethod

this.insertRecord=function(record){

console.log("savingrecord");

//Callsomeservicetosaverecord.

},

//ConcreteImplementationofdeleteRecordmethod

this.deleteRecord=function(record){

console.log("deletingrecord");

//Callsomeservicetodeleterecord

}

//ConcreteImplementationofupdateRecordmethod

this.updateRecord=function(record){

console.log("updatingrecord");

//Callsomeservicetodeleterecord

}

}

}

});

EmployeeRepositorytakesanameparameteratinitializationanddefinesthemediatorvariablethatcanbesetwhenitisregisteredatmediator.ThisisprovidedincaseEmployeeRepositorywantstocallsomeothermoduleorrepositoryofasubscribermodule.Wecancreatemultiplerepositories,forexample,RecruitmentRepositoryand

Page 375: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

AppraisalRepositoryforHRModuleandusethemwhenneeded.

HereisthecodeforHRModulethatcallsEmployeeRepositorythroughamediator:

//HRModule.js

define(function(){

return{

HRModule:function(uniqueName){

this.moduleName=uniqueName;

this.mediator=null;

this.repository="EmployeeRepository";

this.getRecords=function(){

returnthis.mediator.getRecords(this.repository);

},

this.insertRecord=function(record){

this.mediator.insertRecord(record,this.repository);

},

this.deleteRecord=function(record){

this.mediator.deleteRecord(record,this.repository);

}

this.updateRecord=function(record){

this.mediator.updateRecord(record,this.repository);

}

}

}

});

Now,wewillregisterHRModuleandEmployeeRepositorywiththemediatorandcalltheHRModulemethodstoperformCRUDoperations.

ThefollowingisthecodeforHRView.jsthatisusedtocapturethebutton'sclickeventontheformandcallsthegetRecords()methodwhenthebuttonisclicked:

//HRView.js

define(['hr/mediatorcore','hr/employeerepository','hr/hrmodule'],function

(mediatorCore,employeeRepository,hrModule){

$('#btnGetRecords').on('click',function(e){

getRecords();

e.preventDefault();

});

functiongetRecords(){

varmediator=newmediatorCore.mediator();

varempModule=newhrModule.HRModule("EmployeeModule");

mediator.subscribe(empModule);

varempRepo=new

employeeRepository.EmployeeRepository("EmployeeRepository");

mediator.subscribe(empRepo);

alert("Records:"+empModule.getRecords());

Page 376: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

return{

getRecords:getRecords

};

});

Thefollowingisthemain.jsfilethatisusedtobootstrapstheHRView.jsfilethroughtheRequireJSAPI:

//main.js

require(["./hrview"],function(hr){

});

Finally,wecanusetheprecedingMain.jsmoduleontheIndex.cshtmlpageinASP.NET,asfollows:

//Index.cshtml

@{

ViewData["Title"]="HomePage";

}

<scriptdata-main="js/main.js"src="~/js/require.js"></script>

<divid="myCarousel"class="carouselslide"data-ride="carousel"data-

interval="6000">

<inputtype="text"id="txtMessage"/>

<buttonid="btnGetRecords">SendMessage</button>

</div>

Thefollowingisthelogicaldiagramthatshowshowthemodulescommunicatewitheachother:

Page 377: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer
Page 378: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

EncapsulatingcomplexcodeAnothercoreprincipleofdevelopinghighlyscalableandmaintainableapplicationistousewrappersandencapsulatecomplexcodeintoasimplerinterface.ThiscanbeachievedbyimplementingaFacadepattern.

TheFacadepatternisusedtosimplifythecomplexcodebyexposingamethodandhidingallthecomplexcodeinsidetheFacadeobject.Forexample,therearemanywaysandAPIsavailabletoperformAjaxifiedoperations.AjaxrequestscanbemadeusingaplainXmlHttpRequestobject,orwithjQuery,itisquiteeasytouse$.post()and$.get()methods.InAngularJS,itcanbeachievedusingitsownhttpobjecttoinvokeservicesandsoon.ThesetypeofoperationscanbeencapsulatedandbenefitedinscenarioswhentheinternalAPIismodified,orwhenyoudecidedtousesomeotherbetterAPI;modificationneedstobedone,whichisfarlesserthanchangingitatalltheplaceswhereithasbeenused.WiththeFacadepattern,youcanonlymodifyitintheFacadeobjectandsavetimeonupdatingiteverywherewhereithasbeenused.

AnotheradvantageofusingFacadeisthatitreducesthedevelopmenteffortbyencapsulatingabunchofcodetoasimplemethodandmakeiteasyfortheconsumertouse.Facadereducesthedevelopmenteffortbyminimizingthelinesofcoderequiredtocallacertainfunctionality.TolearnmoreaboutFacade,refertoChapter7,JavaScriptDesignPatterns.

Page 379: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

GeneratingdocumentationProperdocumentationincreasesthemaintainabilityofyourapplicationandmakesiteasierfordeveloperstoreferenceitwhenneededorcustomizingapplications.Therearemanydocumentationgeneratorsavailableinthemarket.JSDocandYUIDocareverypopularJavaScriptdocumentationgenerators,butinthissection,wewilluseJSDoc3thatnotonlygeneratesdocumentation,butalsoenablesintellisenseforyourcustomJavaScriptmodulestofacilitateduringdevelopment.

JSDocisanAPIsimilartoJavaDocandPHPDoc.CommentscanbeaddeddirectlytotheJavaScriptcode.ItalsoprovidesaJSDoctoolthroughwhichthedocumentationwebsitecanbecreated.

InstallingJSDoc3inASP.NETCore

JSDoc3canbeaddedasaNodepackageandwecanuseitwiththeGulptaskrunnertogeneratedocuments.ToaddJSDoc3toyourASP.NETCoreproject,youcanstartbyaddinganentrytothepackage.jsonfileusedbyNode.Thisentryhastobedoneinthedevelopmentdependencies:

ThefirstdevelopmentdependencydefinedinthepreviousscreenshotisGulpwhichisrequiredtocreatetasks,andgulp-jsdoc3istheactualdocumentationgeneratorthatgeneratestheHTMLwebsitewhenyourunthattask.

Thetaskcanbedefinedasfollows:

///<bindingClean='clean'/>

"usestrict";

vargulp=require("gulp"),

jsdoc=require("gulp-jsdoc3");

varpaths={

webroot:"./wwwroot/"

};

paths.appJs=paths.webroot+"app/**/*.js";

Page 380: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

gulp.task("generatedoc",function(cb){

gulp.src(['Readme.md',paths.appJs],{read:false})

.pipe(jsdoc(cb));

});

Intheprecedingcodesnippet,wehaveonetasknamedgeneratedoc,inwhichwearereadingthefilesplacedatwwwroot/app/**/*.jsandgeneratingdocumentation.Thejsdocobjecttakestheconfigurationdefaultstogeneratedocumentation.Topassthedefaultconfigurationattributes,wecanjustspecifythecbparameterinjectedinthefunctionlevelbyGulp.WhenyourunthisgeneratedoctaskfromthetaskrunnerinVisualStudio,itwilladdadocsfolderattherootpathofyourwebapplicationproject.AsinASP.NETCore,wealreadyknowthatallstaticcontentshouldresideinthewwwrootfolder,andtoaccessitfrombrowser,simplydraganddropthisfolderinthewwwrootfolderandaccessitbyrunningyourwebsite.

Addingcomments

Togeneratedocumentation,weneedtoannotateourcodewithcomments.Themorethecommentsareprovided,thebetterthedocumentationwillbegenerated.Commentscanbeaddedthrough/**asthestartingtagand*/astheendingtag:

/**ThismethodisusedtosendHTTPGetRequest**/

functionGetData(path){

$.get(path,function(data){

returndata;

})

}

Ifthefunctionisaconstructor,youcanspecify@constructorinthecommentstogivemoremeaningtothereaders:

/**ThismethodisusedtosendHTTPGetRequest

@constructor

*/

functionGetData(path){

$.get(path,function(data){

returndata;

})

}

Afunctiontakesparametersaswell,andthiscanbeindicatedbyusing@paraminyourcomments.Hereisthesamefunctionthattakestheactualpathofsomeserviceasaparametertoretrieverecords:

/**ThismethodisusedtosendHTTPGetRequest

@constructor

@parampath–SpecifyURIoftheresourcethatreturnsdata

*/

functionGetData(path){

$.get(path,function(data){

returndata;

})

Page 381: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

}

Whenyourunyourapplication,itwillshowthedocumentationasfollows:

WehaveseenhoweasyitiswithJSDoc3togeneratedocumentation.Thisnotonlyhelpstounderstandthecode,butalsohelpsthedeveloperduringdevelopmentbyprovidingintellisense.TolearnmoreaboutJSDoc3,refertohttp://usejsdoc.org/.

Page 382: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DeploymentoptimizationLarge-scaleapplicationconsistsoflargenumberofJavaScriptfiles.Whenthepageisdownloaded,itisparsedanditdownloadsalltheJavaScriptfilesdefinedwiththe<script>tag.OncetheJavaScriptfilesaredownloaded,theyareparsedandexecuted.So,itdependsonthenumberofJavaScriptfilesyouhavereferencedonthepage,followedbythelinesofcodeeachJavaScriptfilecontains.Tooptimizethepage-loadingcycle,itisrecommendedtocompressthemthroughaminificationprocess.ThismakestheJavaScriptfilesmallerinsizeandthepage-loadingcyclebecomesfaster.

InASP.NET,wecancompresstheJavaScriptfilesusingGruntandGulpmodules.TheseareNodemodulesandarehighlyintegratedwithASP.NETCore.InASP.NETCore,wecanaddthesemodulesbyaddingaNodepackagereferenceinthepackage.jsonfile,andeachmodulehasitsseparateconfigurationfileknownasGulpFile.jsorGruntFile.js.

Inthisexample,wewillusetheGulpmoduletominifyandcompressourJavaScriptfiles.InASP.NETCore,wecanenableGulpbyaddingtheGulpmoduletothepackage.jsonfile:

Theprecedingcodesnippetusesgulp,gulp-concat,gulp-cssmin,andgulp-uglify.Thefollowingisthedescriptionofeachmodule:

Module Description

Gulp Thisisusedtodefinetasksthatcanberunthroughtaskrunners

gulp-concat ThisisusedtoconcatenateJavaScriptfilesintoasinglefile

gulp-cssmin ThisisusedtocompressCSSfiles

Page 383: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

gulp-uglify ThisisusedtocompressJavaScriptfiles

Thefollowingisthesamplegulpfile.jsthatcanbeusedtocompressJavaScriptandCSSfiles:

///<bindingClean='clean'/>

"usestrict";

//Addingreferencesofgulpmodules

vargulp=require("gulp"),

rimraf=require("rimraf"),

concat=require("gulp-concat"),

cssmin=require("gulp-cssmin"),

uglify=require("gulp-uglify");

//definerootpathwhereallJavaScriptandCSSfilesreside

varpaths={

webroot:"./wwwroot/"

};

/*Pathwhereallthenon-minifiedJavaScriptfileresides.JSisthefolderand

**isusedtohandleforsubfolders*/

paths.js=paths.webroot+"js/**/*.js";

/*PathwherealltheminifiedJavaScriptfileresides.JSisthefolderand**

isusedtohandleforsubfolders*/

paths.minJs=paths.webroot+"js/**/*.min.js";

/*Pathwhereallthenon-minifiedCSSfileresides.Cssisthemainfolderand

**isusedtohandleforsubfolder*/

paths.css=paths.webroot+"css/**/*.css";

/*PathwherealltheminifiedCSSfileresides.Cssisthemainfolderand**

isusedtohandleforsubfolder*/

paths.minCss=paths.webroot+"css/**/*.min.css";

/*NewJavaScriptfilesite.min.jsthatcontainsallthecompressedandmerged

JavaScriptfiles*/

paths.concatJsDest=paths.webroot+"js/site.min.js";

/*NewCSSfilesite.min.cssthatwillcontainallthecompressedandmergedCSS

files*/

paths.concatCssDest=paths.webroot+"css/site.min.css";

//todeletesite.min.jsfile

gulp.task("clean:js",function(cb){

rimraf(paths.concatJsDest,cb);

});

//todeletesite.min.cssfile

gulp.task("clean:css",function(cb){

rimraf(paths.concatCssDest,cb);

});

/*Tomerge,compressandplacetheJavaScriptfilesintoonesinglefile

Page 384: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

site.min.js*/

gulp.task("min:js",function(){

returngulp.src([paths.js,"!"+paths.minJs],{base:"."})

.pipe(concat(paths.concatJsDest))

.pipe(uglify())

.pipe(gulp.dest("."));

});

/*tomerge,compressandplacetheCSSfilesintoonesinglefilesite.min.css

*/

gulp.task("min:css",function(){

returngulp.src([paths.css,"!"+paths.minCss])

.pipe(concat(paths.concatCssDest))

.pipe(cssmin())

.pipe(gulp.dest("."));

});

Intheprecedingcodesnippet,therearefourtasksandthefollowingistheirdescription:

clean:js:Thisremovesthesite.min.jsfileclean:css:Thisremovesthesite.min.cssfilemin:js:Thismergesallthefilesspecifiedinpaths.jsandpaths.minJs,minifiesthemusinguglify(),andfinallycreatesthesite.main.jsfilemin:css:Thismergesallthefilesspecifiedinpaths.cssandpaths.minCss,minifiesthemusingcssmin(),andfinallycreatesthesite.main.cssfile

InVisualStudio2015,youcanrunthesetasksusingTaskRunnerExplorer,andalsobindthemwiththebuildevents:

Thefollowingaretheoptionsthatyoucanhavetoassociatethemwithspecificbuildevents:

Page 385: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Theprecedingscreenshotshowsthestepstobindtheclean:jstaskwithaCleanbuildevent.So,wheneveryourcleanyourproject,itwillrunclean:jsandremovethesite.min.jsfile.

Page 386: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryInthischapter,wediscussedafewconceptsofstructuringJavaScript-basedprojectsandsplittingthemintomodulestoincreasethescalabilityandmaintainability.Wealsosawhoweffectivelywecanusethemediatorpatterntoprovidecommunicationbetweenmodules.Documentationalsoplaysanimportantroleandincreasesthemaintainability,andweusedJSDoc3,whichisoneofthemostpopularJavaScriptdocumentationAPIsandhelpeddeveloperstoreferenceandunderstandthefunctionsofJavaScriptduringdevelopment.Lastly,wediscussedhowtooptimizetheloadtimeofyourapplicationbycompressingandmergingyourJavaScriptfilesintooneminifiedJavaScriptfiletoincreasetheperformance.Inthenextchapter,wewilldiscusstestinganddebuggingJavaScriptapplicationsandthetoolsthatareavailabletotroubleshootefficiently.

Page 387: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Chapter10.TestingandDebuggingJavaScriptIneverysoftwarelifecycle,testinganddebuggingplayanimportantrole.Thoroughtestingmakessoftwareflawlessandgooddebuggingtechniquesmakesiteasytonotonlytroubleshootproblems,butalsohelpstoidentifyandfixanyproblemsbyreachingouttotheexactpoint.

Testingisthecoreessenceofcreatinganyrobustapplication.However,therearedifferentpracticesandframeworksusedbytheapplicationtoserveparticularobjective,andthearchitecturevariesasperthenatureoftheapplication.Therefore,sometimesitbecomesdifficultforadevelopertotestclient-sidecode,forexample,ifanapplicationcontainssomeJavaScriptcodeonapageitself,suchasinlineeventhandlers,makeittightlycoupledwiththepage.Ontheotherhand,evenwhenmodularizingtheJavaScriptcodeintodifferentmodulesbringsometestsuitelimitationsandbecomehardertoexecutethetestingprocessofanapplication.

Debuggingistheprocessoffindingandfixingerrorsinanapplication.Itisoneofthemostimportantandcoreskillsetinsoftwaredevelopment.Ifdevelopershaveasolidgrasponthedebuggingtoolsandknowtheinsandoutsofdebugging,theycanquicklyidentifytherootcauseandstartfixingtheerrors.Debuggingisabasicprocessinanysoftwaredevelopmentlifecycle.Whetherapplicationisacomplexoneorasimpleone,totraceandrectifyerrorsdebuggingplaysanimportantrole.Ithelpsthedevelopertobreaktheprogramexecutionthroughbreakpointsandidentifytheprogramflowbysteppingintothechainofprogramexecution.Moreover,thereisotherusefulinformationalmostalldebuggingtoolsprovide,suchaswatchingthecurrentstateofthevariablesorobjectsbeingusedwithintheprogramandwatchingthemoneverystageofthedebugginglifecycle.

Page 388: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

TestingtheJavaScriptcodeNormally,webapplicationsgothroughdifferenttypesoftesting,suchasuserinterface(UI)testing,whichchecksthefunctionalityoftheUIbymakingcertaininputstotheformandverifiesthebehaviorofanapplication.Thistypeoftestingismostlydonemanuallyorthroughautomatedtestingtools.Theothertypeoftestingisloadtesting,whichisusedmostlytochecktheperformanceofanapplicationandbyputtingupsomeloadontheapplication.Insimpleterms,itcanbeanexampleofsigningintoanapplicationwithmanynumberofusersordoingsomeoperationsthroughautomatedroutinestotesthowtheapplicationbehaves.Thereareafewmoretestingtypes,butthemostessentialtypeoftestingthatensuresthefunctionalityoftheapplicationandcertifieswhethertheapplicationcomplieswiththerequirementsisunittesting.Inthissection,wewilldiscussaboutunittestingJavaScriptcodeusingJasmine(apopularJavaScriptunittestframework)anduseitwithKarmaandGrunttoexecutetestcasesinanASP.NETapplicationusingVisualStudio2015IDE.

Page 389: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

UnittestingUnittestingisamethodtotestindividualunitsofmodulestogetherwithassociateddataandprocedurestoverifytheapplication'sfunctionalitycompliancetotherequirements.Unittestingisdonebydevelopers,anditallowsdeveloperstotesteachusecaseoftheapplicationtoguaranteethatitmeetstherequirementandworksasexpected.

Thebasicadvantageofunittestingisthatitseparateseachpartoftheapplicationintoasmallerunitandhelpsdeveloperstofocusandidentifythebuginitiallyduringthedevelopmentcycle.Unittestingisthefirsttestinganyapplicationenduresandallowtestersanddeveloperstoreleasetheapplicationforuseracceptancetesting(UAT).

Writingunittests

TotestJavaScriptcode,therearemanytestingsuitesavailable.ThemostpopularonesareJasmine,Mocha,andQUnit.Inthischapter,wewilluseJasminewithKarmaandGrunt.

Jasmine

Jasmineisabehavior-drivendevelopmentframeworkfortestingJavaScriptcode.Thisprovidescertainfunctionssuchasit(),describe(),expect(),andsoontowritetestscriptsfortheJavaScriptcode.ThebasicadvantageofthisframeworkisthatitisveryeasytounderstandandhelpstowritethetestJavaScriptcodewithverysimplelinesofcode.

Forexample,considerthefollowingJavaScriptcodethatsumsuptwonumberspassedasparameters:

(function(){

varaddTwoNumbers=function(x,y){

returnx+y;

};

})();

Thetestcasefortheprecedingfunctionwilllooksimilartothefollowing:

describe('Calculator',function(){

it('Resultswillbe20for10+10',function(){

expect(addTwoNumbers(10,10)).toBe(20);

});

});

Karma

KarmaisatestrunnerforJavaScriptthatcanbeintegratedwithothertestingframeworkssuchasJasmine,Mocha,andsoon.ItexecutestestcasesdefinedthroughJasmineorothertestframeworksbyprovidingamocktestenvironmentandloadbrowsersthatexecutesthetestJavaScriptcodeaccordingtotheconfiguration.TheKarmaconfigurationfileisknownasKarma.config.js.Oncethetestsareexecuted,theresultsaredisplayedintheconsolewindow.

Page 390: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Grunt

GruntisequivalenttoGulp.ItisusedtoexecutetaskssuchasminificationofCSSfileorJavaScriptfiles,concatenationandmergingofmultipleJavaScriptfile,andsoon.Grunthashundredsofpluginsthatcanbeusedtoautomatespecifictasks.Unlikethepreviouschapters,whereweusedGulp,wewilluseGruntandseewhatitprovideswithKarma(testrunner)andJasmine(testingsuite).GruntandGulparebothrenownedtaskrunnersfordevelopment.ThereasonforusingGrunthereistogetanunderstandingofanothertaskrunnerofJavaScriptthatisequallyrenownedandsupportedbyVisualStudio2015anddiscussthepackagesthatitprovidestoperformtestingusingKarmaandJasmine.

DevelopingunittestusingJasmine,Karma,andGrunt

Inthissection,wewilldevelopasimpleunittesttoshowhowunittestingcanbedoneinanASP.NETCoreapplicationusingJasmine,Karma,andGruntframeworks.Tostartwith,createanASP.NETCoreapplicationfromVisualStudio2015.

Addingpackages

Openthepackage.jsonfileinyourASP.NETCoreapplicationandaddpackagessuchasgrunt,grunt-karma,karma,karma-phantomjs-launcher,karma-jasmine,karma-spec-reporter,andkarma-cli,asshowninthefollowing:

Thefollowingtableshowsthedescriptionofeachpackage:

PackageName Description

grunt Thisconfiguresandrunstasks

Page 391: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

grunt-karma ThisistheGruntpluginfortheKarmatestrunner

karma ThisisthetestrunnerforJavaScript

karma-phantomjs-launcher ThisistheKarmaplugintolaunchthePhantomJSbrowser

karma-jasmine ThisistheKarmapluginfortheJasminetestsuite

karma-spec-reporter ThisistheKarmaplugintoreporttestresultstotheconsole

karma-cli ThisistheKarmacommand-lineinterface

AddingtheGruntfile

AddGruntfile.jsinyourASP.NETapplicationtodefineGrunttasks.Gruntfile.jsisthemainfilewhereallthetasksareconfigured.ConfiguredtaskscanbeseeninVisualStudiofromtheTaskRunnerExplorerwindow.AddingKarmaspecifications

TheGruntfile.jsfileprovidesthemaininitConfig()methodthatiscalledwhentheGruntisloaded.ThisisthestartingpointwherewedefinetheKarmaspecifications.

ThefollowingistheKarmaspecificationsdefinedwithintheinitConfig()method:

grunt.initConfig({

karma:{

unit:{

options:{

frameworks:['jasmine'],

singleRun:true,

browsers:['PhantomJS'],

files:[

'./wwwroot/js/**/*.js',

'./wwwroot/tests/**/*.test.js'

]

}

}

}

});

Intheprecedingscript,wefirststartedbyspecifyingthetargetplatformforKarma.Insidekarma,wewillspecifytheunitthatisusedtorununittests.Insideunit,wecandefinecertainconfigurationattributessuchasframeworks,singleRun,browsers,andfiles:

frameworks:Thisisanarrayoftestframeworksthatwewanttouse.Inthisexercise,we

Page 392: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

usedJasmine.However,otherframeworkssuchasMochaandQUnitcanalsobeused.

Tip

PleasenotethatwhenusinganyframeworkinKarma,anadditionalplugin/libraryofthatframeworkhastobeseparatelyinstalledusingNodePackageManager(NPM).

singleRun:Ifthisissettotrue,Karmastartcapturingtheconfiguredbrowser(s)andexecutestestsonthem.Oncethetestsarecompleted,itexitssmoothly.browsers:Thisisanarraytodefinemultiplebrowsersinacomma-separatedvalue.WehaveusedPhantomJSinourexample,whichisaheadlessbrowserandrunsthetestinbackground.KarmasupportsotherbrowserssuchasChrome,Firefox,IE,andSafari,andthesecanbeconfiguredthroughthisproperty.files:Thiscontainsallthetestfiles,sourcefiles,anddependencies.Forexample,ifweareusingjQueryinourtestscripts,ororiginalsourcecode,wecanaddthepathtothislibraryaswell.Intheprecedingconfiguration,weusedwildcardcharacterstoloadallthesourcefilesdefinedunderthejsfolder,andtestsfilesunderthetestsfolderwithatest.jssuffix.

TherearemanymoreattributesthatcanbeusedintheKarmaconfigurationanditcanbereferredhere:

http://karma-runner.github.io/0.13/config/configuration-file.htmlLoadnpmtask

ToloadtheKarmatestrunnertool,weneedtospecifyitinGruntfile.jsaftertheKarmaconfiguration,asshowninthefollowing:

grunt.loadNpmTasks('grunt-karma');

Registertask

Finally,wewilladdtheGrunttasktoregistertasks.Thefirstparameteristhetaskname,whichwillbeavailableintheTaskRunnerExplorerinVisualStudio,andthesecondparametertakesanarraytoexecutemultipletasks:

grunt.registerTask('test',['karma']);

SourceJavaScriptfile

Inthisexample,wehaveaproduct.jsfilethatcontainsasaveProduct()method,whichwillbeinvokedontheSavebutton'sclickevent.

Addthisfiletothewwwroot/jsfolderpath:

window.product=window.product||{};

(function(){

varsaveProduct=function(){

varprodCode=document.getElementById('txtProdCode').value;

Page 393: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

varprodUnitPrice=document.getElementById('txtProdUnitPrice').value;

varprodExpiry=document.getElementById('txtProdExpiry').value;

varprodQuantity=document.getElementById('txtProdQuantity').value;

vartotalPrice=prodUnitPrice*prodQuantity;

document.getElementById('totalAmount').innerHTML=totalPrice;

};

window.product.init=function(){

document.getElementById('save').addEventListener('click',saveProduct);

};

})();

Intheprecedingcodesnippet,wehaveasaveProduct()methodthatreadstheHTMLelementsandcalculatesthetotalpricebasedonthequantityandunitpriceentered.Onthepageinitialization,wewillregistertheSavebutton'sclickeventhandlerthatcallsthesaveProduct()methodandcalculatethetotalprice.

Tip

ItisarecommendedapproachtokeepyourJavaScriptcodeseparatefromyourHTMLmarkup.

Addingunittestscriptfile

Here,wewilladdanotherJavaScriptfileunderthewwwroot/testsfolderandnameditproduct.test.js.Whenwritingtests,youcanaddthe*.test.jssuffixtomakeituniquelyidentified,andseparatesitfromthesourceJavaScriptfiles.

Hereisthecodeforproduct.test.js:

describe('Product',function(){

//injecttheHTMLfixtureforthetests

beforeEach(function(){

varfixture='<divid="fixture">'+

'<inputid="txtProdCode"type="text">'+

'<inputid="txtProdExpiry"type="text">'+

'<inputid="txtProdUnitPrice"type="text">'+

'<inputid="txtProdQuantity"type="text">'+

'<inputid="save"type="button"value="Save">'+

'TotalAmount:<spanid="totalAmount"/></div>';

document.body.insertAdjacentHTML(

'afterbegin',

fixture);

});

//removethehtmlfixturefromtheDOM

afterEach(function(){

document.body.removeChild(document.getElementById('fixture'));

});

Page 394: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

//calltheinitfunctionofcalculatortoregisterDOMelements

beforeEach(function(){

window.product.init();

});

it('Expectedresultshouldbe0iftheUnitpriceisnotvalid',function()

{

document.getElementById('txtProdUnitPrice').value='a';

document.getElementById('txtProdQuantity').value=2;

document.getElementById('save').click();

expect(document.getElementById('totalAmount').innerHTML).toBe('0');

});

it('Expectedresultshouldbe0iftheProductQuantityisnotvalid',

function(){

document.getElementById('txtProdUnitPrice').value=30;

document.getElementById('txtProdQuantity').value='zero';

document.getElementById('save').click();

expect(document.getElementById('totalAmount').innerHTML).toBe('0');

});

});

TheJasmineframeworkprovidescertainkeywordstodefinespecificblocksthatrunonspecificconditions,whichareasfollows:

describe():ThisisaglobalJasminefunctionthatcontainstwoparameters:astringandafunction.Thestringisthenameofthefunctionalitythatisgoingtobetested.ThefunctioncontainsthecodethatactuallyimplementstheJasminesuiteandcontainslogicofunittests.it():Here,specsaredefinedbycallingtheglobalJasminefunctionit().Thisalsotakesthestringandfunction,whereitcontainstheactualunittestnameandthefunctionblockcontainstheactuallogicofthecodetobeexecutedfollowedwiththeexpectedresults.expect():Theexpectedresultscanbespecifiedbyusingtheexpect()functionthattakessomevaluedefinedwithintheit()function.Thisisalsochainedwithamatcherfunction,suchastoBe()ornot.toBe(),tomatchorunmatchtheexpectedvalue.

In.NET,itisequivalenttotheArrange,Act,andAssertpattern.Here,Arrangeisusedtoinitializeobjectsandsetvaluesofthedatathatispassedtothemethodundertest.TheActpatternactuallyinvokesthemethodundertest,andAssertverifiesthatthemethodundertestbehavesasexpected.

Runningtesttask

Runningthesetasksisstraightforward,itcansimplyberunthroughtheTaskRunnerExplorerwindowinVisualStudio2015.HereisthescreenshotoftheTaskRunnerExplorerwindowthatshowsthetasksdefinedinGruntfile.js:

Page 395: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Whenwerunthetesttask,itwillshowsomethingsimilartothefollowingoutput:

Inourproduct.test.jstestscript,wehavetwotasks.OneistocheckwhetherpassingthestringvaluestooneofthetwoelementssuchastxtProdUnitPriceandtxtProdQuantitywillreturn0.Asourproduct.jsfiledoesnothandlethiscondition,itwillgiveanerror.

Tofixthis,wewillmodifyourproduct.jsandaddthesetwolinestohandlethislogictocheckwhetherthevalueisanumberornot:

prodUnitPrice=isNaN(prodUnitPrice)?0:prodUnitPrice;

prodQuantity=isNaN(prodQuantity)?0:prodQuantity;

Now,whenwerunourtestagain,wewillgetthefollowingoutput:

Page 396: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Intheprecedingexample,wedefinedtheHTMLmarkupwithinthebeforeEach()functionintheproduct.test.jsfile.Withsimpleapplications,thismaynotbeacumbersomeprocesstoredefinetheHTMLmarkupasfixturesandusethemtoexecutetests.However,mostwebapplicationsareusingsomeclient-sideframeworkssuchasKnockout,AngularJS,andsoon,thatseparatesthebindingofcontrolsspecifiedinanHTMLviewtoaViewModel,andthisViewModelisresponsibletoreadorwritecontrolvalues.

Inthefollowingexample,wewillusetheKnockoutJavaScriptlibrarythatimplementsanModel-View-ViewModelpatternandseehowunittestscanbewritteninthisway.

ImplementingModel-View-ViewModelusingKnockoutandRuntest

Model-View-ViewModel(MVVM)isadesignpatternforbuildinguserinterfaces.Itisdividedintothreeparts,asshowinthefollowingdiagram:

Thesethreepartsaredescribedasfollows:

Model:Thiscontainsthebackendlogictoinvokebackendservicesandsaveorretirevedatabycommunicatingwiththepersistantstorage.ViewModel:Thiscontainstheview-specificoperationsanddata.Itrepresentsthemodeloftheviewtowhichtheviewelementsbindsto.Forexample,aformthatcontainssomeHTMLelementswillhaveaViewModel,whichisanobjectcontainingsomepropertiestobindthesecontrolswiththedata.

Page 397: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

View:Thisistheuserinterfacetowhichtheuserinteracts.ItdisplaysinformationfromtheViewModel,raiseseventsattheViewModel,andupdatesitwhentheViewModelchanges.

Let'simplementtheMVVMpatternusingtheKnockoutJavaScriptlibraryusingthefollowingsteps.

AddingtheKnockoutpackage

Tostartwith,let'saddKnockout.jsinyourASP.NETCoreapplicationthroughbower.json.Itcanbeaddedbymakinganentryinthedependenciessectionofthebower.jsonfile,andVisualStudioautomaticallydownloadsthepackageandplacesitinthewwwroot/lib/knockoutfolder.

Thefollowingstatementcanbeaddedinthebower.jsonfile:

"knockout":"3.4.0",

AddingProductViewModel

ProductViewModelcontainspropertiessuchastheproductcode,unitprice,quantity,expiry,andtotalamount.HereisthecodesnippetofProductViewModel.js:

varProductViewModel=function(){

this.prodCode=ko.observable('');

this.prodUnitPrice=ko.observable(0);

this.prodQuantity=ko.observable(0);

this.prodExpiry=ko.observable('');

this.prodTotalAmount=0;

ko.applyBindings(this);

this.saveProduct=function(){

varunitPrice=this.prodUnitPrice();

varquantity=this.prodQuantity();

vartotal=unitPrice*quantity;

this.prodTotalAmount=total;

//callsomeservicetosaveproduct

}

};

Intheprecedingcodesnippet,wehaveaProductViewModelclassthatcontainsafewproperties,eachpropertyisassignedtoko.observable().

koisbasicallytheKnockoutobjectthatprovidesacomplimentarywayoflinkinganobjectmodeltotheView,whereko.observable()isaKnockoutfunctionthatmakestheModelpropertiesobservableandsyncwiththeViewdata.ThismeansthatwhentheViewModelproperty'svaluechanges,Viewisupdated;andwhenthecontrolvalueismodified,the

Page 398: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

ViewModelpropertyisupdated.

Valuesarealsopre-populatedasshowninthefollowingcodesnippet.Passing0inthefollowingstatementwillsetthecontrolvalue0whenthecontrolbindingisdone:

this.prodUnitPrice=ko.observable(0)

ko.applyBindings()actuallyactivatesKnockouttoperformthebindingoftheModelpropertieswiththeViewelements.

AddtheProductview

KnockoutprovidesaverydecentwayofbindingViewModelpropertiestothecontrolelements.Bindingconsistoftwoitems,nameandvalue,separatedbyacolon.TobindtheViewModelwiththeinputelements,wecanusethedata-bindattributeandspecifythevaluenamefollowedwith:andViewModel'spropertyname.Eachcontrolhasaspecificsetofpropertiesanditcanbeusedtobindelementsaccordingly.

Forexample,thespanelementcanbindtotheviewmodelpropertyusingthetextnameasshowninthefollowing:

Productcodeis:<spandata-bind="text:prodCode"></span>

HereisthemodifiedversionoftheProductview:

<body>

<div>

<label>ProductCode:</label>

<inputtype="text"data-bind="value:prodCode"/>

</div>

<div>

<label>ProductUnitPrice:</label>

<inputtype="text"data-bind="value:prodUnitPrice"/>

</div>

<div>

<label>ProductExpiry:</label>

<inputtype="text"data-bind="value:prodExpiry"/>

</div>

<div>

<label>ProductQuantity:</label>

<inputtype="text"data-bind="value:prodQuantity"/>

</div>

<div>

<inputid="btnSaveProduct"type="button"value="SaveProduct"/>

</div>

<scriptsrc="lib/knockout/dist/knockout.js"></script>

<scriptsrc="Js/ProductViewModel.js"></script>

<script>

(function(){

varprod=newProductViewModel();

document.getElementById("btnSaveProduct").onclick=function(){

prod.saveProduct();};

})();

Page 399: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

</script>

</body>

ThisisallwhatweneedtoconfigureKnockoutintheProductview.WhenthebtnSaveProductbuttonisclicked,itwillcalculatethetotalamountandcalltheproductservicetosavetherecord.

Modifyingtestconfiguration

HereisthemodifiedversionofGruntfile.jscreatedearlier.WeaddedtheProductViewModel.jsandtheKnockoutdependencyinthefilesarray:

/*

Thisfileinthemainentrypointfordefininggrunttasksandusinggrunt

plugins.

*/

module.exports=function(grunt){

grunt.initConfig({

karma:{

unit:{

options:{

frameworks:['jasmine'],

singleRun:true,

browsers:['PhantomJS'],

files:[

'./wwwroot/lib/knockout/dist/knockout.js',

'./wwwroot/js/ProductViewModel.js',

'./wwwroot/test/**/product.test.js'

]

}

}

}

});

grunt.loadNpmTasks('grunt-karma');

grunt.registerTask('test',['karma']);

};

Modifyingtheproduct-testingscript

AswearenotdependentontheHTMLviewdirectly,wecantestourunittestcasesthroughtheProductviewmodel.Hereisthemodifiedversionofproduct.test.jsthatdoesnothaveanyofthefixturesdefined:

describe('Product',function(){

it('ExpectedTotalAmountshouldbe600',function(){

varproduct=newProductViewModel();

product.prodQuantity(3);

product.prodUnitPrice(200);

product.saveProduct();

expect(product.prodTotalAmount).toBe(600);

});

});

Page 400: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Thefollowingoutputwillbegeneratedwhenthetestisrun:

Page 401: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DebuggingJavaScriptJavaScriptrunsonclientbrowsers,andalmostallbrowsers,suchasInternetExplorer,MicrosoftEdge,Chrome,andFirefox,providetheintegratedJavaScriptdebuggerandDeveloperToolswindow.WithVisualStudio,wecanalsodebugtheJavaScriptcodebysettingInternetExplorerasthedefaultbrowser.Chromeisnotsupportedoutofthebox,butwithcertainsteps,itscanbeachieved.

Page 402: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DebuggingoptionsinVisualStudio2015VisualStudioprovidescertaindecentfeaturestodebugJavaScriptandtroubleshooterrors.JavaScriptdebugginginVisualStudioonlyworkswithInternetExplorer.DebuggingcanbestartedbystartingtheapplicationinadebugmodeandthenplacingsomebreakpointsintheJavaScriptcode.Whenthebreakpointishit,wecanuseallsortsofdebuggingoptionsinVisualStudiothatwealreadyknowofandusedindebuggingtheC#andVB.NETcode.OptionssuchasStepinto(F11),Stepover(F10),Stepout(Shift+F11),conditionalbreakpoints,andwatches,allworkwiththeJavaScriptcode.

DebuggingfromVisualStudiowithInternetExplorer

ThedefaultbrowserinVisualStudioforaparticularwebapplicationprojectcanbesetfromtheWebBrowser(InternetExplorer)|InternetExploreroption,asshowninthefollowingscreenshot:

Page 403: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DebuggingfromVisualStudiowithGoogleChromeVisualStudio2015doesnotprovideout-of-the-boxsupporttodebugJavaScriptapplications,exceptwithInternetExplorer.Alternatively,withNode.js,debuggingworksperfectlyfineinVisualStudio,andastechnically,bothNode.jsandGoogleChromearebasedontheV8engine,thereisnodrawback.

TostartdebuggingwithChromeinVisualStudio,wehavetoruntheGooglechrome.exefilewitharemote-debuggerargument.ThefollowingcommandrunsGoogleChromewithremotedebugging,andfromVisualStudio,itcanbeattachedbypointingtothesameChromeinstance:

chrome.exe–remote-debugging-port=9222

9222isthedefaultportwhereVisualStudioconnectsonattachingtoitsprocess.

FromtheVisualStudio,youcanattachtheprocessbyhittingCtrl+Alt+P,orbygoingtoDebug|AttachtoProcessinmenubarandselectingtheChromeinstance.

Page 404: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DeveloperToolsAlmostallthebrowserssupportbuilt-indevelopertoolsthathelpstodebugandtroubleshootJavaScripterrors.ThesetoolsarecommonlyknownasF12toolsandopensuptheDeveloperToolswindowbyhittingtheF12key.

DebuggingoptionsinMicrosoftEdge

MicrosoftEdgeisoneofthemostlightweightwebbrowserwiththelayoutenginebuiltaroundwebstandards.ItcontainssomenewfeaturessuchasCortana,annotationtools,andreadingmodethatgivesitanedgeoverotherbrowsers.

TheDeveloperToolswindowinMicrosoftEdgelooksimilartothefollowingimage:

Thefirstpaneinthetopleft-handcorneristheScriptpanethatshowsthecontentoftheJavaScriptcontainingthepage.

Thesecondpaneinthethetopright-handcornerisaWatchespanewherethevariablevaluesaredisplayed.

Thethirdpaneinthethebottomleft-handcorneristheconsolewindowwheremessagesaredisplayed,allthemessagesloggedusingconsole.log();callsareprintedontheconsolewindow.MicrosoftEdgeprovideserrors,warnings,andmessagesinthreedifferenttabsthat

Page 405: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

giveaglimpseattheerrors,warnings,andmessages,anditalsohelpsthedevelopertodirectlyjumpintotheexactcodesnippetbyclickingontheerrorlinelink.

ThefourthpaneistheCallstackandBreakpoints.Callstackshowsthechainoffunctioncallsthatareexecutedanditishelpfultounderstandthecode-executionflow.Forexample,ifanA()methodcallsaB()method,andtheB()methodcallsaC()method,itshowsthecompleteflowofexecutionfromtheA()methodtotheC()method.

TheBreakpointstabshowsthelistofallthebreakpointsbeingusedinthescript,andtheuserscanmanagethesebreakpointsbyenablingordisablinganddeletingoraddingnewevents:

DebuggingcanonlystartiftheF12DevelopersToolswindowisopenedandthiscanbeopenedthroughthe…|F12DeveloperToolswindowoptionfrommenubarorbyhittingtheF12key.Oncethewindowisopened,youcansetbreakpointsontheJavaScriptcodeandtakespecificactionsonthepage.

Thefollowingtableshowssomeimportantoptionsavailableinthedebuggertoolbar:

Icon Option ShortcutKey Description

Continue F5orF8 Thisreleasesthebreakmodeandcontinuestillthenextbreakpoint.

Break Ctrl+Shift+B Thisbreaksonthenextstatement.

StepInto F11 Thisstepsintothefunctionbeingcalledorthenextstatement.

Page 406: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

StepOver F10 Thisstepsoverthefunctionbeingcalledorthenextstatement.

StepOut Shift+F11

Thisstepsoutofthecurrentfunctionandintothecallingfunction.

Breakonnewworker

Ctrl+Shift+W Thisbreaksonthecreationofanewwebworker.

ExceptionControl

Ctrl+Shift+E

Thiscanbeusedtobreakonallexceptionsorunhandledexceptions.Bydefault,itissettoignoreexceptions.

DisconnectDebugger

Thisdisconnectsthedebuggerandnobreakpointsrun.

Debugjustmycode Ctrl+J Thisignoresthethird-partylibrariesfromdebugging.

Prettyprint Ctrl+Shift+P

ThissearchestheminifiedversionoftheJavaScriptblockandmakesitreadible.

Wordwrap Alt+W Thiswrapsthesentencetoadjustitasperthecontentpanesize.

MicrosoftEdgeprovidesthefollowingfivetypesofbreakpoints:

StandardConditionalTracepointsXHREvents

Standardbreakpoints

Thesebreakpointscanbesetbysimplyselectingthestatementfromthescriptcode:

Page 407: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Conditionalbreakpoints

Thesetypeofbreakpointsarehitwhenspecificconditionsaremetorwhenthevalueofthevariablereachesaspecificstate.Forexample,wecanusethiswithastatementinsidealoopandbreaktheexecutionwhenthecounterreachesavalueof10.

ItcanbesetbyclickingontheexistingbreakpointandselectingCondition...fromthecontextmenu:

ThisoptionopensuptheConditionalbreakpointwindowandtheconditioncanbesetasshowninthefollowingscreenshot:

Page 408: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Oncetheconditionisset,theiconchangesto

Tracepoints

Tracepointsareusedtowritethemessageontheconsolewhenitpassedthroughthestatementwherethetracepointisconfigured.ItcanbesetbyclickingontheInserttracepointoptionfromthecontextmenushowninthegutterbyright-clicking:

Oncethetracepointisset,theiconchanges,asfollows:

Whenthestatementisexecuted,itwillprintthemessageonaconsolewindowasshowninthefollowingscreenshot:

Event

MicrosoftEdgeprovidestheoptionofregisteringeventtracepointsandbreakpointsfromtheBreakpointspane.Aneventcouldbeamouseevent,keyboardevent,ortimerevent.Thisfeatureisheavilyusedinlargeorcomplexwebapplicationswheretheexactlocationof

Page 409: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

specifyingthebreakpointisnotknown.Itisalsomoreusefulincaseswheretheeventhandlersarespecifiedatmultipleplaces.Forexample,ifapagecontainsfivebuttoncontrols,andweneedtobreaktheexecutionwheneveranybuttonraisestheclickevent,wecansimplyspecifythemouse-clickeventthroughthebreakpointevent;andwheneveranybuttoneventisraised,thebreakpointwillbeexecutedandwillfocusonthestatement.

Addeventtracepoint

Ausercanaddeventtracepointswiththehelpofthefollowingoption:

Thefollowingwindowshowstheregistrationofaneventtracepointwhenthemouseisclicked:

Addeventbreakpoints

Usercanaddeventbreakpointswiththehelpofthefollowingoption:

Thefollowingwindowshowstheregistrationofaneventbreakpointwhenthemouseisclicked:

Page 410: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

XHR

Justlikeevents,XHReventscanalsoberegisteredfromtheBreakpointpaneofbrowser.TheseeventsareinvokedwhenanyoftheAjaxrequestisbeingmadefromtheJavaScriptcode.AusercanregistertheXHReventfromtheiconshowninthefollowingscreenshot:

Onceweclickonthisevent,itwillbeaddedintheBreakpointswindow,asshowninthefollowingscreenshot:

Page 411: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DebuggingTypeScriptInChapter5,DevelopinganASP.NETApplicationUsingAngular2andWebAPI,wealreadydiscussedTypeScriptandhowittranspilesintotheJavaScriptcodethateventuallyrunsonthebrowser.ThedeveloperswritecodeinTypeScript,butonthebrowser,ageneratedJavaScriptfileisrun.WhentheTypeScriptfileistranspiledtoaJavaScriptfile,amappingfileisgeneratedwitha*.map.jsextension.ThisfilecontainstheinformationabouttheactualTypeScriptfileandthegeneratedJavaScriptfile.Notonlythis,butthegeneratedJavaScriptfilealsocontainsoneentryaboutthemappingfilethatactuallytellsthebrowserstoloadthecorrespondingsourceTypeScriptfilebyreadingthemappingfile.

HereistheentrythateverygeneratedJavaScriptfilecontainswhenitistranspiledfromTypeScript:

//#

sourceMappingURL=http://localhost:12144/todosapp/apps/createTodo.component.js.map

ThiscanbeconfiguredfromtheTSConfig.jsonfilethroughthesourceMapproperty.IfthesourceMappropertyistrue,itgeneratesthemappingfileandmakesanentryinthegeneratedJavaScriptfile.Also,whenworkinginanASP.NETCoreapplication,allthestaticfileshavetobeinthewwwrootfolder.So,todebugthetypescripts,allthecorrespondingtypescript(.ts)fileshavetobemovedtoanyfolderunderthewwwrootfoldersothatitcanbeaccessiblefromthebrowser.

Hereisthedebuggerwindow,showingthelistofTypeScriptfilesontheleft-handsideandtheiconintheupper-rightcornertotogglebetweenthesourcefileandcompiledJavaScriptversion:

Page 412: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DebuggerkeywordsupportedbyallbrowsersWecanalsoexplicitlyforcetobreakthecontrolatsomepointthroughthedebuggerkeyword.Ifthebreakpointisnotset,butthedebuggerkeywordisspecified,thedebuggingwillbeenabledandbreaktheexecution.Itcanbesetfromcodeasshowninthefollowingscreenshot:

Page 413: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

SummaryInthischapter,wediscussedhowJavaScriptapplicationscanbetestedanddebugged.FortestingJavaScriptapplications,wediscussedtheJasminetestingsuitethatcanbeeasilypluggedinwithKarma,whichisatestrunnerandcanbeusedwithGrunttobeexecutedfromVisualStudioTaskRunnerExplorerwindow.WealsodiscussedthebasicsoftheMVVMpatternandhowtoimplementitusingtheKnockoutJavaScriptlibrary.WethenmodifiedthetestcasetoworkwiththeViewmodel.Fordebugging,wediscussedsometipsandtechniquesofdebuggingJavaScriptwithVisualStudioandwhatMicrosoftEdgeoffersthroughtheDeveloperToolswindowtomakedebuggingeasy.Intheend,wealsolearnedaboutthebasictopicssuchashowMicrosoftEdgeenablesdebuggingforTypeScriptfilesandwhatconfigurationsarerequiredtoachieveit.

Page 414: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

IndexA

abstractfactorypatternabout/Abstractfactorypattern

AbstractSyntaxTree(AST)/CompilationarchitectureofTypeScriptaccesscontrolkeys

Access-Control-Allow-Origin/CallingWCFservicesfromJavaScriptAccess-Control-Allow-Headers/CallingWCFservicesfromJavaScriptAccess-Control-Allow-Method/CallingWCFservicesfromJavaScriptAccess-Control-Max-Age/CallingWCFservicesfromJavaScript

adapterpatternabout/Adapterpattern

AJAXeventsabout/Ajaxevents

Ajaxeventslocalevents/Localeventsglobalevents/Globalevents

AJAXpropertiesaccepts/Ajaxpropertiesasync/Ajaxpropertiescache/Ajaxpropertiescontents/AjaxpropertiescontentType/AjaxpropertiescrossDomain/Ajaxpropertiesdata/AjaxpropertiesdataType/Ajaxproperties

AJAXrequestoptions,URL/Pre-filteringAjaxrequestsdefaultvalues,setting/SettingdefaultvaluesforallfutureAjaxrequests

AjaxrequestXHRobject,using/AjaxrequestsusingtheclassicXHRobjectcreating,jQueryused/MakinganAjaxrequestusingjQuery

AJAXrequest,objectsoptions/Pre-filteringAjaxrequestsoriginalOptions/Pre-filteringAjaxrequestsjqXHR/Pre-filteringAjaxrequests

Angular2about/IntroductiontoAngular2architecture/Angular2architecturecomponentlifecycleevents/Eventsofcomponentlifecyclemodules/Modulescomponents/Components

Page 415: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

dependencyinjection/DependencyinjectioninAngularrouting/RoutinginAngular

ApplicationProgrammingInterfaces(APIs)/WebapplicationswithNode.jsarithmeticoperators

about/Arithmeticoperatorsarray

about/ArrayinJavaScriptASP.NETapplication

WinJSlibrary,adding/AddingtheWinJSlibraryintheASP.NETapplicationWinJS,using/UsingWinJSintheASP.NETapplication

ASP.NETCoreto-doapplication,developing/Developingato-doapplicationinASP.NETCoreJSDoc3,installing/InstallingJSDoc3inASP.NETCore

ASP.NETcoreapplicationcreating/CreatingtheASP.NETcoreapplication

assignmentoperatorsabout/Assignmentoperators

AsynchronousJavaScriptandXML(Ajax)about/IntroducingAjaxworking/HowAjaxworksproperties/AjaxpropertiesAJAXrequest,pre-filtering/Pre-filteringAjaxrequestsdataloading,throughgetfunctions/LoadingdatathroughthegetfunctionsinjQuerypostfunction,usedfordataposting/Postingdatatoserverusingthepostfunction

Page 416: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Bbehavioralpatterns

about/Behavioralpatternchainofresponsibility/Chainofresponsibilitypatternobserver/Observerpatternpub/sub/Pub/subpatternpromises/Promises

bitwiseoperatorsabout/BitwiseoperatorsbitwiseAND/BitwiseANDbitwiseOR/BitwiseORbitwiseNOT/BitwiseNOTbitwiseXOR/BitwiseXOR

bitwiseshiftoperatorsabout/Bitwiseshiftoperatorsbitwiseleftshift/Bitwiseleftshiftbitwiserightshift/Bitwiserightshift

blankNode.jsapplicationscreating/CreatingblankNode.jsapplications

BODMASrule/Groupingoperatorbridgepattern

about/Bridgepatternbrowserobjects

about/BrowserObjectModelsinJavaScriptwindow/Windowdocument/Documentnavigator/Navigatorscreen/Screenhistory/Historylocation/Location

built-indisplaymethods,JavaScriptabout/Built-indisplaymethodsinJavaScriptmessages,displaying/Displayingmessageswindow.alert()/Alertboxwindow.confirm()/Confirmboxdocument.write()method,forwritingonpage/Writingonapageconsole.log()method,forwritingintobrowser'sconsolewindow/Writingintothebrowser'sconsolewindow

Page 417: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CCDNlibrary/CDNchainofresponsibilitypattern

about/ChainofresponsibilitypatternCommonLanguageRuntime(CLR)/Comparingruntimescomparisonoperators

about/Comparisonoperatorsstrictequaloperator/Strictequaloperatorstrictnotequaloperator/Strictnotequaloperator

complextypesabout/Datatypes

componentlifecycleevents,Angular2ngOnInit()/EventsofcomponentlifecyclengOnDestroy()/EventsofcomponentlifecyclengDoCheck()/EventsofcomponentlifecyclengOnChanges(changes)/EventsofcomponentlifecyclengAfterContentInit()/EventsofcomponentlifecyclengAfterContentChecked()/EventsofcomponentlifecyclengAfterViewInit()/EventsofcomponentlifecyclengAfterViewChecked()/Eventsofcomponentlifecycle

conditionalbreakpointsabout/Conditionalbreakpoints

configurationattributes,unittestsframeworks/AddingKarmaspecificationssingleRun/AddingKarmaspecificationsbrowsers/AddingKarmaspecificationsfiles/AddingKarmaspecifications

containsselectorabout/ThecontainsselectorinjQuery

contentdeliverynetwork(CDN)using/Usingacontentdeliverynetwork,TheuseofCDNabout/Usingacontentdeliverynetwork

corebenefits,TypeScriptabout/AdvantagesofTypeScriptsupersetofJavaScript/SupersetofJavaScriptclassesandmodules,supportfor/Supportforclassesandmodulesstatictypechecking/StatictypecheckingECMAScript6featuresupport/ECMAScript6featuresupportoptionaltyping/Optionaltypingtypes,declaring/DeclaringtypesinTypeScript

coreelements,TypeScriptabout/CoreelementsofTypeScriptvariabledeclaration/Declaringvariables

Page 418: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

types/Typesinterfaces/Classesandinterfacesclasses/Classesandinterfacesinterfaces,defining/Defininginterfacesclassesandinterfaces,deriving/Derivingclassesandinterfacesgenericclasses/Genericclassesfunctions/Functionsgenericfunctions/Genericfunctionsiterators/Iteratorsmodules/Modulesandnamespacesnamespaces/Modulesandnamespaces

corefundamentals,ofJavaScriptabout/CorefundamentalsofJavaScriptJavaScript,addingtoHTMLpage/AddingJavaScripttoanHTMLpagestatements/StatementsinJavaScriptliterals/Literalsandvariablesvariables/Literalsandvariablesdatatypes/DatatypesJavaScriptObjectNotation(JSON)/WhatisJSON?

coreproperties,Angular2componentsabout/CorepropertiesofAngular2componentstemplates/Templatesandselectorsselectors/Templatesandselectorsinputs/Inputsandoutputsoutputs/Inputsandoutputsinputs,using/Usinginputsoutputs,using/Usingoutputsdirectives/Directivesproviders/Providers

CORSabout/CORSpolicy,specifyingatserviceslevel/SpecifyingtheCORSpolicyatserviceslevelenabling,atConfiguremethod/EnableCORSattheConfiguremethod

Create,Read,UpdateandDelete(CRUD)operations/CreatingaTodoServiceAppprojectcreationalpatterns

about/Creationalpatternssingleton/Singletondesignpatternfactory/Factorypatternabstractfactory/Abstractfactorypatternprototype/Prototypepattern

cross-originrequestsabout/Cross-originrequestsJavaScriptObjectNotationPadding(JSON-P)/JSON-P

Page 419: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CORS/CORSCRUD(create,retrieve,update,anddelete)operations

about/Modularization

Page 420: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Ddata

posting,postfunctionused/Postingdatatoserverusingthepostfunctiondatabinding

about/Databindingonetimedatabinding/Onetimedatabindingonewaydatabinding/Onewaydatabindingtwowaydatabinding/Twowaydatabindingworkingmodel/Adatabindingworkingmodel

dataloadingthroughgetfunctions,injQuery/LoadingdatathroughthegetfunctionsinjQuery

datatypesabout/Datatypesprimitivetypes/Datatypescomplextypes/Datatypesconversions/Conversionsindatatypes

debuggerkeywordabout/Debuggerkeywordsupportedbyallbrowsers

debuggingJavaScript/DebuggingJavaScriptinVisualStudio2015/DebuggingoptionsinVisualStudio2015fromVisualStudio,withInternetExplorer/DebuggingfromVisualStudiowithInternetExplorerfromVisualStudio,withGoogleChrome/DebuggingfromVisualStudiowithGoogleChromewithDevelopersTools/DeveloperToolsinMicrosoftEdge/DebuggingoptionsinMicrosoftEdgewithTypeScript/DebuggingTypeScript

decoratorpatternabout/Decoratorpattern

deleteoperatorabout/Thedeleteoperator

dependencies,TodoWebAppprojectabout/Dependenciesangular2/Dependenciessystemjs/Dependenciesreflect-metadata/Dependenciesrxjs/Dependencieszone.js/Dependenciesdevelopmentdependencies/Developmentdependencies,ConfiguringTypeScriptGulp,configuring/ConfiguringGulp

dependencyinjection,inAngularabout/DependencyinjectioninAngular

Page 421: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DevelopersToolsabout/DeveloperToolsdebuggingoptions,inMicrosoftEdge/DebuggingoptionsinMicrosoftEdge

directivesabout/Directivescomponents/Directivesstructuraldirective/Directives,Structuraldirectivesattributedirective/Directives,AttributedirectivesimpleHelloWorlddirective,creating/CreatingasimpleHelloWorlddirective

documentationgenerating/GeneratingdocumentationJSDoc3,installinginASP.NETCore/InstallingJSDoc3inASP.NETCore

documentobjectabout/Document

DocumentObjectModel(DOM)about/ImportanceofJavaScript

documentobjectmodel(DOM)/UsingWinJSintheASP.NETapplicationdocumentreadyevent

about/ThedocumentreadyeventDOMelements

selecting,IDused/SelectingtheDOMelementsusingtheIDselecting,TagNameused/SelectingtheDOMelementsusingTagNameselecting,byattributevalue/Selectingbytheattributevaluemanipulating/ManipulatingDOMproperties,modifying/Modifyinganelement'spropertiesURL,formethods/Modifyinganelement'spropertiesgetmethod/Modifyinganelement'spropertiessetmethod/Modifyinganelement'spropertiescreating/Creatingnewelementsattributes,removing/Removingelementsandattributesremoving/Removingelementsandattributes

DOMelements,methodsappend()/CreatingnewelementsappendTo()/Creatingnewelementsbefore()/Creatingnewelementsafter()/CreatingnewelementsinsertAfter()/CreatingnewelementsinsertBefore()/Creatingnewelementsprepend()/Creatingnewelementsdetach()/Removingelementsandattributesremove()/RemovingelementsandattributesremoveAttr()/RemovingelementsandattributesremoveClass()/RemovingelementsandattributesremoveProp()/Removingelementsandattributes

Page 422: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

DOMelements,methodsempty()/Removingelementsandattributes

Page 423: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

EEJSviewengine

about/EJSviewengineelements,ofJavaScript

about/ElementsofJavaScriptconstants/ConstantsinJavaScriptcomments/Commentscasesensitivity/Casesensitivitycharacterset/Characterset

entity-relationshipmodel(ERD)about/Inheritance

environmentsettingup/Settingupyourenvironment

event,MicrosoftEdgeeventtracepoint,adding/Addeventtracepointeventbreakpoints,adding/Addeventbreakpoints

event-drivenmessagingabout/Event-drivenmessagingmediatorpattern,implementing/Implementingmediatorpatternforcommunicationbetweenmodulescomplexcode,encapsulating/Encapsulatingcomplexcode

eventsabout/EventsinJavaScripthandling,injQuery/EventhandlinginjQueryregistering,injQuery/RegisteringeventsinjQueryclick()/RegisteringeventsinjQuerydblclick()/RegisteringeventsinjQuerymousedown()/RegisteringeventsinjQuerymouseup()/RegisteringeventsinjQuerymouseenter()/RegisteringeventsinjQuerymouseleave()/RegisteringeventsinjQuerykeydown()/RegisteringeventsinjQuerykeyup()/RegisteringeventsinjQueryfocus()/RegisteringeventsinjQueryblur()/RegisteringeventsinjQuerychange()/RegisteringeventsinjQueryURL/RegisteringeventsinjQuerybinding,onandoffused/Bindingeventsusingonandoffhoverevents,using/Usingthehoverevents

/EventsinWinJSexceptionhandling,OOP

about/ExceptionhandlingError/Error

Page 424: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

RangeError/RangeErrorReferenceError/ReferenceErrorTypeError/TypeErrorURIError/URIError

Expressframeworkforwebapplications,inNode.jsusing/UsingtheExpressframeworkforwebapplicationsinNode.jssimpleNode.js,extending/ExtendsimpleNode.jstouseExpressExpressviewengines/Expressviewengines

expressionsabout/Expressionsthiskeyword/Thethiskeywordsequence,ofcodeexecution/SequenceofcodeexecutioninJavaScriptthiskeyword,usingoncallingmethod/Usingthethiskeywordonacallingmethodfunctionstatement/Thefunctionstatementandexpressionfunctionexpression/Thefunctionstatementandexpressionclassstatement/Classstatementandexpressionclassexpression/Classstatementandexpressiongroupingoperator/Groupingoperatornewkeyword/newsuperkeyword/super

Expressviewenginesabout/ExpressviewenginesEJSviewengine/EJSviewengineJadeviewengine/Jadeviewenginerouting,inExpressapplication/RoutingintheExpressapplication

Page 425: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Ffactorypattern

about/Factorypatternfaçadepattern

about/Facadepatternfunctionarguments

about/Functionarguments

Page 426: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Ggetfunctions

used,fordataloading/LoadingdatathroughthegetfunctionsinjQueryjQuery.get(),using/UsingjQuery.get()jQuery.getJSON(),using/UsingjQuery.getJSON()jQuery.getScript(),using/UsingjQuery.getScript()

globalevents,AJAXajaxStart/GlobaleventsajaxSend/GlobaleventsajaxSuccess/GlobaleventsajaxError/GlobaleventsajaxComplete/Globalevents

GoogleChromeused,fordebuggingfromVisualStudio/DebuggingfromVisualStudiowithGoogleChrome

Gruntused,forwritingunittests/Grunt

Gruntfileadding/AddingtheGruntfileKarmaspecifications,adding/AddingKarmaspecificationsnpmtask,loading/Loadnpmtasktask,registering/Registertask

GulpmoduleGulp/Deploymentoptimizationgulp-concat/Deploymentoptimizationgulp-cssmin/Deploymentoptimizationgulp-uglify/Deploymentoptimization

Page 427: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Hhistoryobject

about/Historymethods/Methods

hovereventsusing/Usingthehoverevents

Page 428: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

IID

used,forselectingDOMelements/SelectingtheDOMelementsusingtheIDIIFE(immediatelyinvokedfunctionexpression)

about/ImplementingthemodulepatternindexOf()method

about/ArrayinJavaScriptinheritance

about/Inheritanceconstructors,chaininginJavaScript/ChainingconstructorsinJavaScriptObject.create()used/InheritanceusingObject.create()defining,classused/Defininginheritanceusingclass

inputelementsselecting/Selectinginputelements

IntegratedDevelopmentEnvironment(IDE)/UsingNode.jswithVisualStudio2015IntermediateLanguage(IL)code/ComparingruntimesInternetExplorer

used,fordebuggingfromVisualStudio/DebuggingfromVisualStudiowithInternetExplorer

Page 429: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

JJadelanguage

URL/JadeviewengineJadeviewengine

about/JadeviewengineJasmine

used,forwritingunittests/Jasminedescribe()function/Addingunittestscriptfileit()function/Addingunittestscriptfileexpect()function/Addingunittestscriptfile

JavaScriptimportance/ImportanceofJavaScriptabout/WhatisJavaScript?runtimes,comparing/Comparingruntimesprogramming/ProgramminginJavaScriptWCFservices,calling/CallingWCFservicesfromJavaScriptdebugging/DebuggingJavaScript

JavaScriptcodemodularizing,throughRequireJS/ModularizingJavaScriptcodethroughRequireJStesting/TestingtheJavaScriptcode

JavaScriptdesignpatternscreational/Creationalpatternsstructural/Structuralpatternsbehavioral/Behavioralpattern

JavaScriptObjectNotationPadding(JSON-P)about/JSON-Pusing/UsingJSON-P

JavaScriptpropertydescriptorsabout/JavaScriptpropertydescriptorswritable/JavaScriptpropertydescriptorsenumerable/JavaScriptpropertydescriptorsconfigurable/JavaScriptpropertydescriptorsdisplaying/Displaypropertydescriptorsmanaging/Managingpropertydescriptorsgettersandsetters,using/Usinggettersandsetters

JavaScripttypedarraysabout/JavaScripttypedarraysarchitecture/Typedarrayarchitecturearraybuffer/Thearraybufferbuffer,creating/Creatingabuffer

jQueryURL/GettingstartedwithjQuery

Page 430: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

about/GettingstartedwithjQuerycontentdeliverynetwork(CDN),using/Usingacontentdeliverynetworkdocumentreadyevent/Thedocumentreadyeventselectors/ThejQueryselectorsevents,handling/EventhandlinginjQueryevents,registering/RegisteringeventsinjQueryused,forcreatingAjaxrequest/MakinganAjaxrequestusingjQuery.ajax()/jQuery.ajax()dataloading,throughgetfunctions/LoadingdatathroughthegetfunctionsinjQuery

jQuery.get()functionusing/UsingjQuery.get()

jQuery.getJSON()functionusing/UsingjQuery.getJSON()

jQuery.getScript()functionusing/UsingjQuery.getScript()

jQueryselectorsabout/ThejQueryselectorsDOMelements,selectingIDused/SelectingtheDOMelementsusingtheIDDOMelements,selectingTagNameused/SelectingtheDOMelementsusingTagNamenodes,selectingbyclassname/SelectingnodesbytheclassnameDOMelements,selectingbyattributevalue/Selectingbytheattributevalueinputelements,selecting/Selectinginputelementselements,selecting/Selectingalltheelementsfirstchildelements,selecting/Selectingthefirstandlastchildelementslastchildelements,selecting/Selectingthefirstandlastchildelementscontainsselector/ThecontainsselectorinjQueryoddrowsselector,selecting/Selectingtheevenandoddrowsselectorsevenrowsselector,selecting/Selectingtheevenandoddrowsselectors

JSDoc3installing,inASP.NETCore/InstallingJSDoc3inASP.NETCorecomments,adding/AddingcommentsURL/Addingcomments

JSONabout/WhatisJSON?simpleobjects/SimpleobjectsinJSONarrays,declaring/DeclaringarraysinJSONdata,nesting/NestingdatainJSON

just-in-time(JIT)compilation/Comparingruntimes

Page 431: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

KKarma

used,forwritingunittests/KarmaURL,forconfigurationfile/AddingKarmaspecifications

Knockoutused,forimplementingModel-View-ViewModel(MVVM)/ImplementingModel-View-ViewModelusingKnockoutandRuntestpackage,adding/AddingtheKnockoutpackageProductViewModel,adding/AddingProductViewModelProductview,adding/AddtheProductviewtestconfiguration,modifying/Modifyingtestconfigurationproduct-testingscript,modifying/Modifyingtheproduct-testingscript

Page 432: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Llargescaleapplication

designing/ThinkbeforeproceedinglastIndexOf()method

about/ArrayinJavaScriptlet

used,fordeclaring/Declaringletconditions/Conditionswhereletisefficienttousefunctionsinloops/Functionsinloops

loadtestingabout/TestingtheJavaScriptcode

localevents,AJAXbeforeSend/Localeventssuccess/Localeventserror/Localeventscomplete/Localevents

locationobjectabout/Locationproperties/Propertiesmethods/Methods

logicaloperatorsabout/LogicaloperatorsLogicalAND/LogicalANDLogicalOR/LogicalORLogicalNOT/LogicalNOT

Page 433: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Mmainto-dopage,TodoWebAppproject

creating/Creatingthemainto-dopagecustomto-dotaghelper,creating/Creatingacustomto-dotaghelper-doMVCcontroller,adding/Addingato-doMVCcontrollerviews,generatingforTodoControlleractionmethods/GeneratingviewsfortheTodoControlleractionmethodsCreateTodocomponent,developing/DevelopingtheCreateTodocomponent

mediatorpatternimplementing,forcommunicationbetweenmodules/Implementingmediatorpatternforcommunicationbetweenmodules

messages,displayingalertbox/Alertboxconfirmbox/Confirmboxpromptbox/Promptbox

methods,OOPabout/Methodsdefining,objectliteralnotationused/Definingmethodsthroughobjectliteralnotationapproachdefining,constructorfunctionused/Definingobjectsusingtheconstructorfunctionapproachextending/Extendingpropertiesandmethods

MicrosoftEdgedebuggingoptions/DebuggingoptionsinMicrosoftEdgestandardbreakpoints/Standardbreakpointsconditionalbreakpoints/Conditionalbreakpointstracepoints/Tracepointsevent/EventXHR/XHR

MicrosoftSQLserver,accessinginNode.jsabout/AccessingtheMicrosoftSQLserverinNode.jsrecord,reading/ReadingarecordfromtheMicrosoftSQLserverdatabaserecord,creating/CreatingarecordintheMicrosoftSQLserverdatabase

Middlewareabout/Middleware

miscellaneousoperatorsconditionaloperators/Conditionaloperatorsspreadoperator/Spreadoperator

mixin/MixinModel-View-ViewModel(MVVM)

implementing,Knockoutused/ImplementingModel-View-ViewModelusingKnockoutandRuntest

modularization

Page 434: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

about/Modularizationmodulepattern,implementing/ImplementingthemodulepatternJavaScriptcode,modularizingthroughRequireJS/ModularizingJavaScriptcodethroughRequireJS

modulescreating,RequireJSAPIused/CreatingmodulesusingtheRequireJSAPIdefining,inCommonJSstyle/CreatingmodulesusingtheRequireJSAPIdefining,inAMDstyle/CreatingmodulesusingtheRequireJSAPI

mssqlnodepackagereference/CreatingarecordintheMicrosoftSQLserverdatabase

MVC,withExpressframeworkabout/MVCwiththeExpressframeworkMVCpattern/MVCpatterncontroller,creating/Creatingacontrollerdataservices,creating/Creatingdataservices

Page 435: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Nnamespace/NamespacesinWinJSnavigatorobject

about/Navigatorproperties/Properties

Node.jsabout/IntroductiontoNode.jsversus.NET/ComparisonofNode.jswith.NETNodePackageManager(NPM)/NPMinstalling/InstallingNode.jsURL/InstallingNode.jsusing,withVisualStudio2015/UsingNode.jswithVisualStudio2015forsimpleconsoleapplication/SimpleconsoleapplicationusingNode.jsblankNode.jsapplications,creating/CreatingblankNode.jsapplicationsExpressframework,usingforwebapplications/UsingtheExpressframeworkforwebapplicationsinNode.jsMicrosoftSQLserver,accessing/AccessingtheMicrosoftSQLserverinNode.js

Node.jswebserverrequest,processingby/RequestprocessingbytheNode.jswebserver

nodepackagemanager(npm)about/AddingKarmaspecifications

NodePackageManager(NPM)/AddingtheWinJSlibraryintheASP.NETapplicationnodes

selecting,byclassname/SelectingnodesbytheclassnameNPM/NPMNuGet/NuGet

Page 436: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Oobject

about/Datatypesobject-orientedprogramming(OOP)

about/Object-orientedprogramminginJavaScriptobjects,creating/Creatingobjectsprivateandpublicmembers/Privateandpublicmembersinheritance/Inheritanceencapsulation/Encapsulationabstraction/Abstractionnew.targetproperty/new.targetnamespace/Namespaceexceptionhandling/Exceptionhandlingclosures/Closuresclosures,practicaluse/PracticaluseJavaScripttypedarrays/JavaScripttypedarraysmaps/Maps,sets,weakmaps,andweaksetsmapsandweakmaps/Mapsandweakmapssetsandweaksets/Setsandweaksetsstrictmode/Thestrictmode

Object.create()used,forinheritance/InheritanceusingObject.create()predefinedproperties/PredefinedpropertiesofObject.create()

objects,OOPcreating/Creatingobjectsdefining,objectliteralnotationused/Definingobjectsusingobjectliteralnotationdefining,constructorpatternused/Definingobjectsusingaconstructorpatternclasskeyword,using/Usingtheclasskeyword

observerpatternabout/Observerpattern

onetimedatabinding/Onetimedatabindingonewaydatabinding/Onewaydatabindingopenauthentication(OAuth)/Mapsandweakmapsoperators

about/Operatorsassignmentoperators/Assignmentoperatorsarithmeticoperators/Arithmeticoperatorsunaryoperators/Unaryoperatorscomparisonoperators/Comparisonoperatorslogicaloperators/Logicaloperatorsbitwiseoperators/Bitwiseoperatorsbitwiseshiftoperators/Bitwiseshiftoperatorstypeofoperator/Thetypeofoperator

Page 437: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

voidoperator/Thevoidoperatordeleteoperator/Thedeleteoperatormiscellaneousoperators/Miscellaneousoperators

Page 438: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Ppop()method

about/ArrayinJavaScriptpostfunction

used,fordataposting/Postingdatatoserverusingthepostfunctionprimitivetypes

Boolean/Datatypesnull/Datatypesundefined/Datatypesnumber/Datatypesstring/Datatypes

programming,inJavaScriptabout/ProgramminginJavaScriptcorefundamentals/CorefundamentalsofJavaScriptelements/ElementsofJavaScriptexpressions/Expressionsoperators/Operatorsbuilt-indisplaymethods/Built-indisplaymethodsinJavaScriptBrowserObjectModels/BrowserObjectModelsinJavaScript

promisesabout/Promises,Promisesoperations/Otheroperationsofpromiseschaining/Chainingpromisesandhandlingerrorserrors,handling/Chainingpromisesandhandlingerrorscancelling/Cancelingpromisesjoining/Joiningpromiseschecking/Checkingpromisenon-promise,wrappingintopromise/Wrappingnon-promiseintopromise

properties,OOPabout/Propertiesdefining,objectliteralnotationused/Definingpropertiesusingobjectliteralnotationdefining,constructorpatternused/Definingpropertiesusingaconstructorpatterndefining,setters/gettersused/Definingpropertiesusingsetters/gettersinECMAScript6JavaScriptpropertydescriptors/JavaScriptpropertydescriptorsextending/Extendingpropertiesandmethods

prototypepatternabout/Prototypepattern

pub/subpatternabout/Pub/subpattern

push()methodabout/ArrayinJavaScript

Page 439: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

RRequireJS

JavaScriptcode,modularizing/ModularizingJavaScriptcodethroughRequireJSAPI,usedforcreatingmodules/CreatingmodulesusingtheRequireJSAPIbootstrapping/BootstrappingRequireJS

reverse()methodabout/ArrayinJavaScript

routing,inAngularabout/RoutinginAngular

Page 440: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Sscalableandmaintainableapplications

developing/Developinghighlyscalableandmaintainableapplicationsmodularization/Modularizationevent-drivenmessaging/Event-drivenmessagingdocumentation,generating/Generatingdocumentationdeploymentoptimization/Deploymentoptimization

screenobjectabout/Screenproperties/Properties

shift()methodabout/ArrayinJavaScript

simpleconsoleapplicationNode.jsused/SimpleconsoleapplicationusingNode.js

singletondesignpatternabout/Singletondesignpattern

splice()methodabout/ArrayinJavaScript

standardbreakpointsabout/Standardbreakpoints

structuralpatternsabout/Structuralpatternsadapter/Adapterpatterndecorator/Decoratorpatternfaçade/Facadepatternbridge/Bridgepattern

Page 441: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

TTagName

used,forselectingDOMelements/SelectingtheDOMelementsusingTagNametesting

unittesting/Unittestingto-doapplication,developinginASP.NETCore

about/Developingato-doapplicationinASP.NETCoreCommonproject,creating/CreatingaCommonprojectTodoServiceAppproject,creating/CreatingaTodoServiceAppprojectTodoWebAppproject,creating/CreatingaTodoWebAppproject

TodoServiceAppprojectcreating/CreatingaTodoServiceAppprojectMVC,enabling/EnablingMVCinaWebAPIprojectEntityFramework,installing/InstallingEntityFrameworkAppSettings,addingforstoringconnectionstring/AddingAppSettingstostoreaconnectionstringAppSettings,configuringinStartupclass/ConfiguringAppSettingsintheStartupclassdataaccess,addinginWebAPI/AddingdataaccessinWebAPICORS,enablinginASP.NETWebAPI/EnablingCORSintheASP.NETWebAPIdatabasemigration,running/Runningdatabasemigrationcontroller,creating/Creatingacontroller

TodoWebAppprojectcreating/CreatingaTodoWebAppprojectAngular2,configuring/ConfiguringAngular2intheTodoWebAppprojectdependencies/DependenciesAngularcomponents,adding/AddingAngularcomponents-doservicecomponent,adding/Addingtheto-doservicecomponentto-doviewcomponent,adding/Addingato-doviewcomponentmainto-dopage,creating/Creatingthemainto-dopage

toString()methodabout/ArrayinJavaScript

tracepointsabout/Tracepoints

twowaydatabinding/Twowaydatabindingtypeofoperator

about/Thetypeofoperatorvalues/Thetypeofoperator

TypeScriptabout/TypeScriptcompilationarchitecture/CompilationarchitectureofTypeScriptbenefits/AdvantagesofTypeScriptcoreelements/CoreelementsofTypeScript

Page 442: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

reference/Modulesandnamespacesdebugging/DebuggingTypeScript

Page 443: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Uunaryoperators

about/Unaryoperatorsdecrement/Unaryoperatorsincrement/Unaryoperatorslogicalcomplementoperator/Unaryoperators

unittestingabout/Unittesting

unittestswriting/Writingunittestswriting,withJasmine/Jasminewriting,withKarma/Karmawriting,withGrunt/Gruntdeveloping/DevelopingunittestusingJasmine,Karma,andGruntpackages,adding/AddingpackagesGruntfile,adding/AddingtheGruntfilesourceJavaScriptfile,using/SourceJavaScriptfilescriptfile,adding/Addingunittestscriptfiletesttask,executing/RunningtesttaskModel-View-ViewModel(MVVM),implementing/ImplementingModel-View-ViewModelusingKnockoutandRuntestexecuting/ImplementingModel-View-ViewModelusingKnockoutandRuntest

UniversalAppPlatform(UAP)/UsageofWinJSUniversalWindowsPlatform(UWP)/UsageofWinJSunshift()method

about/ArrayinJavaScriptuseracceptancetesting(UAT)

about/Unittestinguserinterface(UI)/ImportanceofJavaScript,IntroductiontoWinJSuserinterface(UI)testing/TestingtheJavaScriptcode

Page 444: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

Vvariables

about/Variables–scopeandhoistinghoisting/Variables–scopeandhoistinglet,fordeclaring/Declaringlet

variablesscope/Variables–scopeandhoistingVisualStudio

existingWindowsapptemplate/ExistingWindowsapptemplateinVisualStudiodebuggingfrom,withInternetExplorer/DebuggingfromVisualStudiowithInternetExplorerdebugging,withGoogleChrome/DebuggingfromVisualStudiowithGoogleChrome

VisualStudio2015debuggingoptions/DebuggingoptionsinVisualStudio2015

VisualStudio2015communityeditionURL/Settingupyourenvironment

VisualStudio2015IDEneweditingexperience,ofJavaScript/NeweditingexperienceofJavaScriptinVisualStudio2015IDEimprovements/NeweditingexperienceofJavaScriptinVisualStudio2015IDE

voidoperatorabout/Thevoidoperator

Page 445: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

WWCFservices

calling,fromJavaScript/CallingWCFservicesfromJavaScriptwindowobject

about/WindowWindowsruntimefeatures

using/UsingWindowsruntimefeatureshostedapps/Hostedappsandaccessingthecameracamera,accessing/HostedappsandaccessingthecameraASP.NETcoreapplication,creating/CreatingtheASP.NETcoreapplicationASP.NETapplicationconvertingintowindowsapplication,Hostedappconceptused/ConvertinganASP.NETapplicationintoWindowsapplicationusingtheHostedappconcept

WinJSabout/IntroductiontoWinJSuses/UsageofWinJSstarting/GettingstartedwithWinJSusing,inASP.NETapplication/UsingWinJSintheASP.NETapplicationexistingWindowsapptemplate,inVisualStudio/ExistingWindowsapptemplateinVisualStudiocontrols,adding/AddingWinJScontrolscontrols,propertiessetting/SettingpropertiesofWinJScontrols

WinJS,corefundamentalsexploring/ExploringWinJScorefundamentalsclasses/Classesandnamespacesnamespaces/Classesandnamespaces,NamespacesinWinJSclasses,defininginWinJS/DefiningclassesinWinJSclasses,derivinginWinJS/DerivingclassesinWinJSmixin/Mixinevents/EventsinWinJSDatabinding/Databinding

WinJS,featuresabout/WinJSfeaturesJavaScriptcodingandlanguagepatterns/JavaScriptcodingandlanguagepatternsstylesheets/StylesheetsWindowsruntimeaccess/Windowsruntimeaccesssecurity/SecurityAppmodel/AppmodelDatabinding/Databindingcontrols/Controlsutilities/Utilities

WinJSlibrary,addinginASP.NETapplicationabout/AddingtheWinJSlibraryintheASP.NETapplication

Page 446: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

CDNlibrary/CDNNPM/NPMNuGet/NuGet

Page 447: JavaScript for .NET Developers - programmer-books.com · He wrote a book in 2013 on web development called Visual Studio 2013, Concevoir et développer des projets Web, les gérer

XXHR

about/XHRXHRobject

used,forAJAXrequest/AjaxrequestsusingtheclassicXHRobjectmethods/XHRmethodsevents/XHReventsproperties/XHRproperties

XHRobject,headersCookie/XHRmethodsHost/XHRmethodsConnection/XHRmethodsAccept/XHRmethodsAccept-charset/XHRmethodsAccept-encoding/XHRmethodsAccept-language/XHRmethodsUser-Agent/XHRmethodsReferer/XHRmethods

XHRobject,methodsrequest,sending/XHRmethodsvoidsend()/XHRmethodsvoidsend(DOMString?Data)/XHRmethodsvoidsend(Documentdata)/XHRmethodsvoidsend(Blobdata)/XHRmethodsvoidsend(FormDatadata)/XHRmethodsrequest,aborting/XHRmethodsrequestheaders,setting/XHRmethodsresponseheaders,obtaining/XHRmethods

XHRobject,propertiesrequeststate,obtaining/XHRpropertiesresponsestate,obtaining/XHRpropertiesresponsestatus,obtaining/XHRproperties

XMLHttpRequest(XHR)about/HowAjaxworks