\documentclass[10pt,a4paper]{article} % Packages \usepackage{fancyhdr} % For header and footer \usepackage{multicol} % Allows multicols in tables \usepackage{tabularx} % Intelligent column widths \usepackage{tabulary} % Used in header and footer \usepackage{hhline} % Border under tables \usepackage{graphicx} % For images \usepackage{xcolor} % For hex colours %\usepackage[utf8x]{inputenc} % For unicode character support \usepackage[T1]{fontenc} % Without this we get weird character replacements \usepackage{colortbl} % For coloured tables \usepackage{setspace} % For line height \usepackage{lastpage} % Needed for total page number \usepackage{seqsplit} % Splits long words. %\usepackage{opensans} % Can't make this work so far. Shame. Would be lovely. \usepackage[normalem]{ulem} % For underlining links % Most of the following are not required for the majority % of cheat sheets but are needed for some symbol support. \usepackage{amsmath} % Symbols \usepackage{MnSymbol} % Symbols \usepackage{wasysym} % Symbols %\usepackage[english,german,french,spanish,italian]{babel} % Languages % Document Info \author{rajanvora} \pdfinfo{ /Title (angular-cheat-sheet.pdf) /Creator (Cheatography) /Author (rajanvora) /Subject (Angular Cheat Sheet) } % Lengths and widths \addtolength{\textwidth}{6cm} \addtolength{\textheight}{-1cm} \addtolength{\hoffset}{-3cm} \addtolength{\voffset}{-2cm} \setlength{\tabcolsep}{0.2cm} % Space between columns \setlength{\headsep}{-12pt} % Reduce space between header and content \setlength{\headheight}{85pt} % If less, LaTeX automatically increases it \renewcommand{\footrulewidth}{0pt} % Remove footer line \renewcommand{\headrulewidth}{0pt} % Remove header line \renewcommand{\seqinsert}{\ifmmode\allowbreak\else\-\fi} % Hyphens in seqsplit % This two commands together give roughly % the right line height in the tables \renewcommand{\arraystretch}{1.3} \onehalfspacing % Commands \newcommand{\SetRowColor}[1]{\noalign{\gdef\RowColorName{#1}}\rowcolor{\RowColorName}} % Shortcut for row colour \newcommand{\mymulticolumn}[3]{\multicolumn{#1}{>{\columncolor{\RowColorName}}#2}{#3}} % For coloured multi-cols \newcolumntype{x}[1]{>{\raggedright}p{#1}} % New column types for ragged-right paragraph columns \newcommand{\tn}{\tabularnewline} % Required as custom column type in use % Font and Colours \definecolor{HeadBackground}{HTML}{333333} \definecolor{FootBackground}{HTML}{666666} \definecolor{TextColor}{HTML}{333333} \definecolor{DarkBackground}{HTML}{A3070C} \definecolor{LightBackground}{HTML}{FCF7F7} \renewcommand{\familydefault}{\sfdefault} \color{TextColor} % Header and Footer \pagestyle{fancy} \fancyhead{} % Set header to blank \fancyfoot{} % Set footer to blank \fancyhead[L]{ \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{C} \SetRowColor{DarkBackground} \vspace{-7pt} {\parbox{\dimexpr\textwidth-2\fboxsep\relax}{\noindent \hspace*{-6pt}\includegraphics[width=5.8cm]{/web/www.cheatography.com/public/images/cheatography_logo.pdf}} } \end{tabulary} \columnbreak \begin{tabulary}{11cm}{L} \vspace{-2pt}\large{\bf{\textcolor{DarkBackground}{\textrm{Angular Cheat Sheet}}}} \\ \normalsize{by \textcolor{DarkBackground}{rajanvora} via \textcolor{DarkBackground}{\uline{cheatography.com/141179/cs/30219/}}} \end{tabulary} \end{multicols}} \fancyfoot[L]{ \footnotesize \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{LL} \SetRowColor{FootBackground} \mymulticolumn{2}{p{5.377cm}}{\bf\textcolor{white}{Cheatographer}} \\ \vspace{-2pt}rajanvora \\ \uline{cheatography.com/rajanvora} \\ \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Cheat Sheet}} \\ \vspace{-2pt}Published 15th December, 2021.\\ Updated 15th December, 2021.\\ Page {\thepage} of \pageref{LastPage}. \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Sponsor}} \\ \SetRowColor{white} \vspace{-5pt} %\includegraphics[width=48px,height=48px]{dave.jpeg} Measure your website readability!\\ www.readability-score.com \end{tabulary} \end{multicols}} \begin{document} \raggedright \raggedcolumns % Set font size to small. Switch to any value % from this page to resize cheat sheet text: % www.emerson.emory.edu/services/latex/latex_169.html \footnotesize % Small font. \begin{multicols*}{2} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{ng commands}} \tn % Row 0 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{ng new {\emph{app-name}}} \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{~~{\emph{(-{}-routing) add routing}}} \tn % Row Count 2 (+ 1) % Row 2 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{ng add {\emph{@angular/material}}} \tn % Row Count 3 (+ 1) % Row 3 \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{~~{\emph{(install and configure the Angular Material library)}}} \tn % Row Count 5 (+ 2) % Row 4 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{ng build} \tn % Row Count 6 (+ 1) % Row 5 \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{~~{\emph{(build your application and places directory called "dist")}}} \tn % Row Count 8 (+ 2) % Row 6 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{ng serve {\emph{(build and serve on 4200)}}} \tn % Row Count 9 (+ 1) % Row 7 \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{ng serve -o {\emph{(automatically open the browser)}}} \tn % Row Count 10 (+ 1) % Row 8 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{ng serve -p 666 -o {\emph{(use port 666)}}} \tn % Row Count 11 (+ 1) % Row 9 \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{ng generate component {\emph{csr}}} \tn % Row Count 12 (+ 1) % Row 10 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{~~or ng g c {\emph{csr}}} \tn % Row Count 13 (+ 1) % Row 11 \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{ng g c {\emph{csr}} -{}-flat {\emph{(generate component without folder)}}} \tn % Row Count 15 (+ 2) % Row 12 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{ng g s {\emph{csr-data (generate service objects)}}} \tn % Row Count 16 (+ 1) % Row 13 \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{ng g cl {\emph{models/csr}}} \tn % Row Count 17 (+ 1) % Row 14 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{~~{\emph{ (generates the csr class inside of the models folder)}}} \tn % Row Count 19 (+ 2) % Row 15 \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{ng g i {\emph{models/csr}}} \tn % Row Count 20 (+ 1) % Row 16 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{~~{\emph{(generates the csr interface inside the models folder)}}} \tn % Row Count 22 (+ 2) % Row 17 \SetRowColor{white} \mymulticolumn{1}{x{8.4cm}}{ng g p {\emph{shared/init-caps}}} \tn % Row Count 23 (+ 1) % Row 18 \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{~~{\emph{(generates the init-caps pipes)}}} \tn % Row Count 24 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Filters}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{{\bf{amount | currency{\emph{{[}:symbol{]}}}}} \newline {\emph{\{\{ currency\_expression | currency : symbol : fractionSize\}\}}} \newline e.g.\{\{nl\}\}\textless{}span id="currency-no-fractions"\textgreater{}\{\{nl\}\}~~\{\{amount | currency:"USD\$":0\}\}\{\{nl\}\}\textless{}/span\textgreater{} \newline Formats a number as a currency (ie \$1,234.56). \newline \newline {\bf{date | date{\emph{{[}:format{]}}}}} \newline {\emph{\{\{ date\_expression | date : format : timezone\}\}}} \newline e.g.\{\{nl\}\}\textless{}span ng-non-bindable\textgreater{}\{\{nl\}\}~~\{\{1288323623006 | date:'MM/dd/yyyy @ h:mma'\}\}\{\{nl\}\}\textless{}/span\textgreater{}\{\{nl\}\}\textless{}span\textgreater{}\{\{nl\}\}~~\{\{'1288323623006' | date:'MM/dd/yyyy @ h:mma'\}\}\{\{nl\}\}\textless{}/span\textgreater{}\{\{nl\}\}output:\{\{nl\}\}\{\{1288323623006 | date:'MM/dd/yyyy @ h:mma'\}\}: \newline 12/15/2021@11:40PM \newline \newline {\bf{array | filter:expression}} \newline Selects a subset of items from array. \{\{nl\}\}Expression takes string|Object|function() \newline {\emph{\{\{ filter\_expression | filter : expression : \{\{nl\}\}comparator : anyPropertyKey\}\}}} \newline e.g. \newline ng-repeat="friend in friends | filter:searchText" \newline \newline {\bf{data | json}} \newline Convert a JavaScript object into JSON string. \newline {\emph{\{\{ json\_expression | json : spacing\}\}}} \newline e.g. \newline \textless{}pre id="default-spacing"\textgreater{} \newline \{\{ \{'name':'value'\} | json:4 \}\} \newline \textless{}/pre\textgreater{} \newline output: \newline \{ \newline "name": "value" \newline \} \newline \newline {\bf{array | limitTo:limit}} \newline Creates a new array containing only a \newline specified number of elements in an array. \newline {\emph{\{\{ limitTo\_expression | limitTo : limit : begin\}\}}} \newline \newline {\bf{text | linky 1}} \newline Finds links in text input and turns them into html links. \newline {\emph{ Requires ngSanitize Module \newline }}\textless{}span \seqsplit{ng-bind-html="linky\_expression} | linky"\textgreater{}\textless{}/span\textgreater{}{\emph{ \newline e,g, \newline \textless{}div ng-bind-html="snippet | linky"\textgreater{} \newline \textless{}/div\textgreater{} \newline \textless{}div \seqsplit{ng-bind-html="snippetWithSingleURL} | linky:'\_blank'"\textgreater{} \newline \textless{}/div\textgreater{} \newline \textless{}div \seqsplit{ng-bind-html="snippetWithSingleURL} | linky:'\_self': \newline \{rel: 'nofollow'\}"\textgreater{} \newline \textless{}/div\textgreater{} \newline \newline {\bf{string | lowercase}} \newline Converts string to lowercase. \newline }}\{\{ lowercase\_expression | lowercase\}\}{\emph{ \newline \newline {\bf{number | number}}{[}:fractionSize{]}}}{\emph{ \newline Formats a number as text. \newline If the input is not a number an empty string is returned. \newline }}\{\{ number\_expression | number : fractionSize\}\}{\emph{ \newline e.g. \newline Default formatting: \newline \textless{}span id='number-default'\textgreater{} \newline \{\{val | number\}\} \newline \textless{}/span\textgreater{} \newline No fractions: \newline \textless{}span\textgreater{} \newline \{\{val | number:0\}\} \newline \textless{}/span\textgreater{} \newline Negative number: \newline \textless{}span\textgreater{} \newline \{\{-val | number:4\}\} \newline \textless{}/span\textgreater{} \newline \newline {\bf{array | orderBy:predicate}}{[}:reverse{]}}}{\emph{ \newline Predicate is function(}})|string|Array. Reverse is boolean \newline {\emph{\{\{ orderBy\_expression | orderBy : \newline expression : reverse : comparator\}\}}} \newline e.g. \newline ng-repeat="friend in friends | orderBy:'-age'" \newline \newline {\bf{string | uppercase}} \newline Converts string to uppercase. \newline {\emph{\{\{ uppercase\_expression | uppercase\}\}}} \newline \textless{}h1\textgreater{}\{\{title | uppercase\}\}\textless{}/h1\textgreater{}} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Forms}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{In Angular, there are 2 types: template-driven(easier to use) \newline and reactive(recommended for large forms) \newline {\bf{Template-driven:}} \newline Import FormsModule in app.module.ts \newline Sample: \newline {\bf{.ts}} \newline import \{ Component, OnInit \} from '@angular/core'; \newline @Component(\{ \newline selector: 'app-newuser', \newline templateUrl: \seqsplit{'./newuser.component.html'}, \newline styleUrls: {[}'./newuser.component.scss'{]} \newline \}) \newline export class NewuserComponent implements OnInit \{ \newline // Data \newline user = \{username: '', email: '', password: ''\}; \newline constructor() \{ \} \newline ngOnInit(): void \{ \} \newline /{\bf{ \newline {\emph{ Called when the user clicks in the "Register" \newline }} button. \newline {\emph{/ \newline onSubmit() \{ \newline console.log('User: ', this.user.username); \newline console.log('Email: ', this.user.email); \newline console.log('Password: ', this.user.password); \newline \} \newline \} \newline }}.html{\bf{ \newline \textless{}div\textgreater{} \newline \textless{}form novalidate \#registerForm="ngForm" \newline (ngSubmit)="onSubmit()"\textgreater{} \newline \textless{}!-{}- User -{}-\textgreater{} \newline \textless{}p\textgreater{} \newline \textless{}mat-form-field\textgreater{} \newline \textless{}input \newline matInput \newline placeholder="Username" \newline type="text" \newline {[}(ngModel){]}="user.username" \newline name="username" \newline \#username="ngModel" \newline required\textgreater{} \newline \textless{}mat-error \newline }}ngIf= \newline "username.errors?.required"\textgreater{} \newline Username is required \newline \textless{}/mat-error\textgreater{} \newline \textless{}/mat-form-field\textgreater{} \newline \textless{}/p\textgreater{} \newline \textless{}!-{}- Email -{}-\textgreater{} \newline \textless{}p\textgreater{} \newline \textless{}mat-form-field\textgreater{} \newline \textless{}input matInput \newline placeholder="Email" \newline type="email" \newline {[}(ngModel){]}="user.email" \newline name="email" \newline \#email="ngModel" \newline required\textgreater{} \newline \textless{}mat-error \newline {\emph{ngIf="email.errors?.required"\textgreater{} \newline Email is required \newline \textless{}/mat-error\textgreater{} \newline \textless{}/mat-form-field\textgreater{} \newline \textless{}/p\textgreater{} \newline \textless{}!-{}- Password -{}-\textgreater{} \newline \textless{}p\textgreater{} \newline \textless{}mat-form-field\textgreater{} \newline \textless{}input \newline matInput \newline placeholder="Password" \newline type="password" {[} \newline (ngModel){]}="user.password" \newline name="password" \newline \#password="ngModel" \newline required\textgreater{} \newline \textless{}mat-error \newline }}ngIf="password.errors?.required"\textgreater{} \newline Password is required \newline \textless{}/mat-error\textgreater{} \newline \textless{}/mat-form-field\textgreater{} \newline \textless{}/p\textgreater{} \newline \textless{}p\textgreater{} \newline \textless{}button type="submit" \newline mat-button \newline {[}disabled{]}="registerForm.form.invalid"\textgreater{} \newline Register user \newline \textless{}/button\textgreater{} \newline \textless{}/p\textgreater{} \newline \textless{}/form\textgreater{} \newline \textless{}/div\textgreater{} \newline this example uses two way binding and templateRef \newline (for registerForm) \newline \newline }}Reactive Forms:{\bf{ \newline import ReactiveFormsModule in app.module.ts \newline all the form logic and validation are done controller \newline create a model \newline }}.ts{\bf{ \newline export class User \{ \newline username: string; \newline email: string; \newline password: string; \newline \} \newline }}.ts{\bf{ \newline import \{ Component, OnInit \} from '@angular/core'; \newline import \{ User \} from '../shared/user'; \newline @Component(\{ \newline selector: 'app-newuser', \newline templateUrl: \seqsplit{'./newuser.component.html'}, \newline styleUrls: {[}'./newuser.component.scss'{]} \newline \}) \newline export class NewuserComponent implements OnInit \{ \newline // Register form \newline registerForm: FormGroup; \newline // form for submitting the new user \newline myUser: User; \newline // the user generated from the form \newline \seqsplit{@ViewChild('newuserForm')} userFormDirective: \newline FormGroupDirective; \newline // reference to the form in the HTML template, \newline // in order to perform validation \newline /{\emph{ \newline }} The errors being shown for each field. \newline {\emph{ The form will automatically update with \newline }} the errors stored here. \newline {\emph{/ \newline formErrors = \{ \newline 'username': '', \newline 'email': '', \newline 'password': '' \newline \} \newline /}} \newline {\emph{ Messages that will be shown in the \newline }} mat-error elements for each type of validation error. \newline {\emph{/ \newline validationMessages = \{ \newline 'username': \{ \newline 'required': \newline 'Username is required.', \newline 'minlength': \newline 'Username must be at \newline least 3 characters long.', \newline 'maxlength': \newline 'Username cannot be \newline more than 20 characters long.' \newline \}, \newline 'password': \{ \newline 'required': \newline 'Password is required.', \newline 'minlength': \newline 'Password must be at \newline least 8 characters long.' \newline \}, \newline 'email': \{ \newline 'required': \newline 'Email is required.', \newline 'email': \newline 'Email not in valid format.' \newline \} \newline \}; \newline \newline /}} \newline }} Inject a FormBuilder for creating a FormGroup. \newline {\emph{/ \newline constructor(private fb: FormBuilder) \{ \newline this.createForm(); \newline \} \newline \newline /{\bf{ \newline }} Create the comment form with the injected FormBuilder. \newline {\emph{/ \newline createForm()\{ \newline this.registerForm = this.fb.group(\{ \newline username: {[}'', \newline {[}Validators.required, \newline Validators.minLength(3), \newline Validators.maxLength(20){]} {]}, \newline password: {[}'', \newline {[}Validators.required, \newline Validators.minLength(8){]} {]}, \newline email: {[}'', \newline {[}Validators.required, \newline Validators.email{]} {]}, \newline \}); \newline this.registerForm.valueChanges.subscribe( \newline data =\textgreater{} this.onValueChanged()); \newline // every time a value changes inside the form, the \newline // onValueChanged() method will be triggered \newline this.onValueChanged(); \newline // reset validation messages \newline \} \newline \newline /}} \newline }} Validate the form after a value change. \newline {\emph{/ \newline onValueChanged() \{ \newline if(!this.registerForm) \{ return; \} \newline // in case the form hasn't been created yet \newline const form = this.registerForm; \newline // the form values are constantly changing, \newline // that's why we have to take a snapshot \newline \newline // Validate the form \newline for (const field in this.formErrors) \{ \newline // Iterate the form field by field \newline if \seqsplit{(this.formErrors.hasOwnProperty(field))} \{ \newline this.formErrors{[}field{]} = ''; \newline // clear previous error message (if any) \newline const control = form.get(field); \newline if (control \&\& control.dirty \newline \&\& !control.valid) \{ \newline // If this form field has been \newline // touched an it's not valid \newline const messages = \newline this.validationMessages{[}field{]}; \newline for (const key in control.errors) \{ \newline if \seqsplit{(control.errors.hasOwnProperty(key))} \{ \newline // Add the corresponding error messages \newline // to the array of form errors. \newline // The form mat-error elements will update \newline // immediatly with the new form errors. \newline this.formErrors{[}field{]} += \newline messages{[}key{]} + ' '; \newline \} \newline \} \newline \} \newline \} \newline \} \newline \} \newline /{\bf{ \newline }} Called when the user clicks the "Submit" button in the form \newline {\emph{/ \newline onSubmit()\{ \newline // Create a User object from the form data \newline this.myUser = this.registerForm.value; \newline // TODO: send the form data to somewhere else \newline // Reset the form \newline this.registerForm.reset(\{ \newline username: '', \newline email: '', \newline password: '' \newline \}); \newline this.userFormDirective.resetForm(); \newline \} \newline \} \newline }}.html}}{\emph{ \newline \textless{}div\textgreater{} \newline \textless{}form \newline novalidate \newline {[}formGroup{]}="registerForm" \newline \#newuserForm="ngForm" \newline (ngSubmit)="onSubmit()"\textgreater{} \newline \textless{}p\textgreater{} \newline \textless{}mat-form-field\textgreater{} \newline \textless{}input \newline matInput \newline \seqsplit{formControlName="username"} \newline placeholder="Username" \newline type="text" \newline required\textgreater{} \newline \textless{}mat-error \newline }}ngIf="formErrors.username"\textgreater{} \newline \{\{formErrors.username\}\} \newline \textless{}/mat-error\textgreater{} \newline \textless{}/mat-form-field\textgreater{} \newline \textless{}/p\textgreater{} \newline \textless{}p\textgreater{} \newline \textless{}mat-form-field\textgreater{} \newline \textless{}input \newline matInput \newline formControlName="password" \newline placeholder="Password" \newline type="password" \newline required\textgreater{} \newline \textless{}mat-error \newline {\emph{ngIf="formErrors.password"\textgreater{} \newline \{\{formErrors.password\}\} \newline \textless{}/mat-error\textgreater{} \newline \textless{}/mat-form-field\textgreater{} \newline \textless{}/p\textgreater{} \newline \textless{}p\textgreater{} \newline \textless{}mat-form-field\textgreater{} \newline \textless{}input \newline matInput \newline formControlName="email" \newline placeholder="Email" \newline type="email" \newline required\textgreater{} \newline \textless{}mat-error \newline }}ngIf="formErrors.email"\textgreater{} \newline \{\{formErrors.email\}\} \newline \textless{}/mat-error\textgreater{} \newline \textless{}/mat-form-field\textgreater{} \newline \textless{}/p\textgreater{} \newline \textless{}button type="submit" \newline {[}disabled{]}="registerForm.invalid" \newline mat-raised-button \newline color="primary"\textgreater{} \newline Submit \newline \textless{}/button\textgreater{} \newline \textless{}/form\textgreater{} \newline \textless{}/div\textgreater{}} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Directives}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{{\bf{ng-app=}}"plaintext" \newline {\bf{ng-bind{[}-html-unsafe{]}=}}"expression" \newline {\bf{ng-bind-template=}}"string\{\{expression\}\}string\{\{expression\}\}" \newline {\bf{ng-change=}}"expression" \newline {\bf{ng-checked=}}"boolean" \newline {\bf{ng-class{[}-even|-odd{]}=}}"string|object" \newline {\bf{ng-{[}dbl{]}click=}}"expression" \newline {\bf{ng-cloak=}}"boolean" \newline {\bf{ng-controller=}}"plaintext" \newline {\bf{ng-disabled=}}"boolean" \newline {\bf{\textless{}form|ng-form}} name="plaintext"\textgreater{} | {\bf{ng-form=}}"plaintext" \newline {\bf{ng-hide|show=}}"boolean" \newline {\bf{ng-href=}}"plaintext\{\{string\}\}" \newline {\bf{ng-include=}}"string"|{\bf{\textless{}ng-include}} src="string" \{\{nl\}\}~~onload="expression" autoscroll="expression"\textgreater{} \newline {\bf{ng-init=}}"expression" \newline \textless{}input {\bf{ng-pattern=}}"/regex/" \{\{nl\}\}~~{\bf{ng-minlength ng-maxlength ng-required}} \newline \textless{}input {\bf{ng-list=}}"delimiter|regex"\textgreater{} \newline \textless{}input type="checkbox" {\bf{ng-true-value=}}"plaintext" \{\{nl\}\}~~{\bf{ng-false-value=}}"plaintext"\textgreater{} \newline {\bf{ng-model=}}"expression" \newline {\bf{ng-mousedown=}}"expression" \newline {\bf{ng-mouseenter=}}"expression" \newline {\bf{ng-mouseleave=}}"expression" \newline {\bf{ng-mousemove=}}"expression" \newline {\bf{ng-mouseover=}}"expression" \newline {\bf{ng-mouseup=}}"expression" \newline \textless{}select {\bf{ng-multiple}}\textgreater{} \newline {\bf{ng-non-bindable}} \newline {\bf{ng-options=}}"select {[}as label{]} {[}group by group{]} \{\{nl\}\}~~for ({[}key,{]} value) in object|array" \newline {\bf{ng-pluralize|\textless{}ng-pluralize}} count="number" \{\{nl\}\}~~when="object" offset="number"\textgreater{} \newline {\bf{ng-readonly=}}"expression" \newline {\bf{ng-repeat=}}"({[}key,{]} value) in object|array" \newline \textless{}option {\bf{ng-selected=}}"boolean"\textgreater{} \newline {\bf{ng-src=}}"string" \newline {\bf{ng-style=}}"string|object" \newline {\bf{ng-submit=}}"expression" \newline {\bf{ng-switch=}}"expression"|\textless{}{\bf{ng-switch}} on="expression"\textgreater{} \newline {\bf{ng-switch-when=}}"plaintext" \newline {\bf{ng-switch-default}} \newline {\bf{ng-view|\textless{}ng-view\textgreater{}}} \newline {\bf{ng-bind-html=}}"expression"} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Routing}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{With routing, you can introduce navigation between screens \newline (actually, between Angular components) in your app. \newline Define routes in {\bf{app-routing.module.ts}} \newline Instantiate the router in html as : \newline ~~{\bf{\textless{}router-outlet\textgreater{}\textless{}/router-outlet\textgreater{}}} \newline To redirect the user to a defined route \newline use the {\bf{routerLink}} directive} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Data Binding}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{Angular components are defined in three files: \newline an HTML file for the layout (view), \newline a TypeScript file for the logic (controller), and \newline a CSS file for the style. \newline \newline {\bf{One-way}} data binding is the mechanism for rendering in the \newline view objects defined in the controller (property binding) \newline and for allowing the view to call methods in the \newline controller (event binding). \newline \newline {\bf{Two-way}} data binding, where using the notation {[}(object){]}, \newline a bidirectional relationship between the view and \newline the controller is established, so any changes on the bound \newline object from the controller will be reproduced in the \newline view and vice versa.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Structural Directives}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{Structural directives allow the developers to include \newline some code logic inside the HTML template in a very quick \newline and easy way in order to determine when and how many \newline times an HTML element has to be rendered} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Template-Reference Variables}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{Inside the template of a component, we can assign a \newline reference to an HTML element so we can access its content \newline from other elements inside the DOM.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{RxJS}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{A library for reactive programming in JS, an \newline asynchronous-programming paradigm where it exists an \newline entity called Observable\textless{}T\textgreater{}, which consists in a value \newline of type T that changes over time. \newline \newline Our application components can subscribe to this observable, \newline becoming observers by implementing a callback which will be \newline triggered whenever the value changes. \newline The main method of observable objects is \newline subscribe(data =\textgreater{} \{\}), which enables us to ask Angular to \newline notify us whenever the data changes. \newline \newline Other interesting functions: map, pipe, filter, delay..} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Services}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{Components without UI \newline {\bf{ng g s services/datafetch}} \newline Tell Angular to inject this service in all of the \newline app components that ask for it, so let's add it to \newline the providers section of the {\bf{app.module.ts}} file \newline \newline To use it in any component of our app, \newline you just have to ask for it in the constructor.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Promises}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{These are JS mechanism for async programming, where a \newline pending value is returned, which might be available soon \newline (resolve) or never (reject) \newline Promises allow you to specify what to do when the answer to \newline your request arrives or when something goes wrong, and \newline meanwhile you can continue with the execution of your program. \newline {\bf{.service.ts}} \newline @Injectable(\{ \newline providedIn: 'root' \newline \}) \newline export class UserService \{ \newline constructor() \{\} \newline getUsers(): Promise\textless{}User\textgreater{} \{ \newline return new Promise( \newline function(resolve, reject)\{ \newline // get the data from some API... \newline if(successful) \{ \newline // Data was successfully retrieved \newline resolve(result); \newline \} else \{ \newline // There was an error retrieving the data \newline reject(error); \newline \} \newline \}); \newline \} \newline \} \newline {\bf{.ts (component that consumes the service)}} \newline @Component(\{ \newline selector: 'app-users', \newline templateUrl: './users.component.html', \newline styleUrls: {[}'./users.component.scss'{]} \newline \}) \newline export class UsersComponent implements OnInit \{ \newline constructor(private userService: UserService) \{\} \newline myUsers: User{[}{]}; \newline getUsers()\{ \newline this.userService.getUsers() \newline .then(users =\textgreater{} this.myUsers = users) \newline // the Promise was resolved \newline .catch(error =\textgreater{} console.log(error)) \newline // the Promise was rejected \newline \} \newline ngOnInit(): void \{\} \newline \}} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{HTTP Request}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{The HttpClient class underlies the JavaScript XMLHttpRequest \newline object and returns an observable with the server-response \newline body encoded as an object of the specified class. \newline Sample: \newline Image a GET request to \seqsplit{http://localhost:1234/items} \newline returns following JSON \newline {[} \newline \{ \newline "name": "Porcelain cup", \newline "price": 9.99, \newline "quantity": 20 \newline \}, \newline \{ \newline "name": "Photo frame", \newline "price": 5.99, \newline "quantity": 50 \newline \} \newline {]} \newline create a model to capture the data \newline export class Item \{ \newline name: string; \newline price: number; \newline quantity: number; \newline \} \newline After importing HttpClientModule in app.module.ts \newline .service.ts \newline import \{ Injectable, Inject \} from '@angular/core'; \newline import \{ Item \} from '../shared/item' \newline import \{ Observable \} from 'rxjs'; \newline import \{ map, catchError \} from 'rxjs/operators'; \newline import \{ HttpClient \} from '@angular/common/http'; \newline \newline @Injectable(\{ \newline providedIn: 'root' \newline \}) \newline export class ItemService \{ \newline baseURL = 'http://localhost:1234/' \newline \newline /{\bf{ \newline {\emph{ Injects an HTTPClient and the BaseURL \newline }} into the service. \newline {\emph{ @param http HTTPClient used for making \newline }} HTTP requests to the backend. \newline {\emph{/ \newline constructor(private http: HttpClient) \{ \} \newline \newline /}} \newline }} Return the list of items from the API, \newline {\emph{ as an array of Item objects \newline }}/ \newline getItems(): Observable\textless{}Item{[}{]}\textgreater{} \{ \newline return this.http.get\textless{}Item{[}{]}\textgreater{} \newline (this.baseURL + 'items'); \newline // make the HTTP GET request \newline \} \newline \newline /{\bf{ \newline {\emph{ Send a new item to the API, as \newline }} an Item object \newline {\emph{/ \newline addItem(item: Item): Observable\textless{}Item\textgreater{} \{ \newline return this.http.post\textless{}Item\textgreater{} \newline (this.baseURL + 'items', item); \newline // make the HTTP POST request \newline \} \newline \} \newline component to consume the service: \newline }}.ts}}* \newline import \{ Component, OnInit \} from '@angular/core'; \newline import \{ ItemService \} from '../services/item'; \newline import \{ Item \} from '../shared/item'; \newline \newline @Component(\{ \newline selector: 'app-items', \newline templateUrl: './items.component.html', \newline styleUrls: {[}'./items.component.scss'{]} \newline \}) \newline export class ItemsComponent implements OnInit \{ \newline constructor(private itemService: ItemService) \{\} \newline myItems: Item{[}{]}; \newline \newline ngOnInit(): void \{ \newline this.itemService.getItems() \newline .subscribe(items =\textgreater{} this.myItems = items, \newline // any time the value of the Observable \newline // changes, update the myItems object \newline error =\textgreater{} console.log(error)); \newline // if there is an error, log it to the \newline // console \newline \} \newline \}} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{8.4cm}{X} \SetRowColor{DarkBackground} \mymulticolumn{1}{x{8.4cm}}{\bf\textcolor{white}{Workflow}} \tn \SetRowColor{LightBackground} \mymulticolumn{1}{x{8.4cm}}{Steps to creating a reactive form: \newline \newline 1. Create the Domain Model \newline 2. Create the Controller with references to View \newline 3. Create the View \newline 4. Add Validations \newline 5. Add Submit Validation Control \newline 6. Add Dynamic Behaviors} \tn \hhline{>{\arrayrulecolor{DarkBackground}}-} \end{tabularx} \par\addvspace{1.3em} % That's all folks \end{multicols*} \end{document}