Movatterモバイル変換


[0]ホーム

URL:


Packt
Search iconClose icon
Search icon CANCEL
Subscription
0
Cart icon
Your Cart(0 item)
Close icon
You have no products in your basket yet
Save more on your purchases!discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Profile icon
Account
Close icon

Change country

Modal Close icon
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timerSALE ENDS IN
0Days
:
00Hours
:
00Minutes
:
00Seconds
Home> Web Development> Front End Web Development> Angular Cookbook
Angular Cookbook
Angular Cookbook

Angular Cookbook: Over 80 actionable recipes every Angular developer should know , Second Edition

Arrow left icon
Profile Icon Muhammad Ahsan Ayaz
Arrow right icon
$29.99$33.99
Full star iconFull star iconFull star iconFull star iconEmpty star icon4(13 Ratings)
eBookDec 2023536 pages2nd Edition
eBook
$29.99 $33.99
Paperback
$41.99
Subscription
Free Trial
Renews at $19.99p/m
Arrow left icon
Profile Icon Muhammad Ahsan Ayaz
Arrow right icon
$29.99$33.99
Full star iconFull star iconFull star iconFull star iconEmpty star icon4(13 Ratings)
eBookDec 2023536 pages2nd Edition
eBook
$29.99 $33.99
Paperback
$41.99
Subscription
Free Trial
Renews at $19.99p/m
eBook
$29.99 $33.99
Paperback
$41.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with eBook?

Product feature iconInstant access to your Digital eBook purchase
Product feature icon Download this book inEPUB andPDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature iconDRM FREE - Read whenever, wherever and however you want
Product feature iconAI Assistant (beta) to help accelerate your learning
OR

Contact Details

Modal Close icon
Payment Processing...
tickCompleted

Billing Address

Table of content iconView table of contentsPreview book icon Preview Book

Angular Cookbook

Working with Angular Directives and Built-In Control Flow

In this chapter, you’ll learn about Angular directives in depth, with a real-world example of using a directive that highlights text on searching. You’ll also write your first structural directive and see how theViewContainer andTemplateRef services work together to add/remove elements from theDocument Object Model (DOM), just as in the case of*ngIf. You’ll also create some really cool attribute directives that do different tasks. Finally, you’ll learn how to use theDirective Composition API to apply multiple directives to the same element.

Here are the recipes we’re going to cover in this chapter:

  • Using attribute directives to handle the appearance of elements
  • Creating a directive to calculate the read time for articles
  • Creating a directive that allows you to vertically scroll to an element
  • Writing your first custom structural directive
  • How to apply multiple structural directives to the same element
  • Applying multiple directives to the same element using the Directive Composition API

Technical requirements

For the recipes in this chapter, ensure your setup is complete as per the 'Technical Requirements' in the 'Angular-Cookbook-2E' GitHub repository. For setup details, visit:https://github.com/PacktPublishing/Angular-Cookbook-2E/tree/main/docs/technical-requirements.md. The starter code for this chapter is located athttps://github.com/PacktPublishing/Angular-Cookbook-2E/tree/main/start/apps/chapter02.

Using attribute directives to handle the appearance of elements

In this recipe, you’ll workwith an Angular attribute directive namedhighlight. With this directive, you’ll be able to search words and phrases within a paragraph and highlight them on the go. The wholeparagraph’s container background will also be changed when we have a search in action. For example, by using the following code:

<pclass="text-content max-w-2xl m-auto" appHighlight  [highlightText]="'de'">  <!--text here -->

The result will appear as an output as shown inFigure 2.1:

Figure 2.1: The result when using the highlight directive

Getting ready

The app that we are going to workwith resides instart/apps/chapter02/ng-attribute-directive inside the cloned repository:

  1. Open the code repository in your code editor.
  2. Open the terminal, navigate to the code repository directory, and run the following command to serve the project:
    npm run serve ng-attribute-directive

    This should open the app in a new browser tab, and you should see the following:

    Figure 2.2: ng-attribute-directive app running on http://localhost:4200

How to do it…

The application has a search input and a paragraph of text. We want to be able to type a search query in the input so that we can highlight and find all the matching occurrences in the paragraph. Here are the steps to achieve this:

  1. We’ll create a property namedsearchText in theapp.component.ts file that we’ll use as amodel for the search-text input:
    ...exportclassAppComponent {  searchText ='';}
  2. Then, we use thesearchText property in the template, i.e., in theapp.component.html file, with the search input as anngModel, as follows:
    ...<divclass="content"role="main">  ...<input [(ngModel)]="searchText"type="text"placeholder="Quick Search..."class="pr-4 !pl-10py-2"></div>
  3. Youwill notice thatngModel doesn’t work yet. This is because we’re missing theFormsModule inour application. Let’s import it into theapp.component.ts file as follows:
    ...import {FormsModule }from'@angular/forms'; @Component({selector:'app-root',templateUrl:'./app.component.html',standalone:true,styleUrls: ['./app.component.scss'],imports: [CommonModule,RouterModule,FormsModule],})exportclassAppComponent {  searchText ='';}
  4. Now, we’ll create an attribute directive namedhighlight by using the following command from the workspace root:
    cd start && nx g directive highlight --directory apps/chapter02/ng-attribute-directive/src/app --standalone

    If asked, choose the@nx/angular:directive schematics and choose the “As provided” action. The preceding command generates a standalone directive that has a selector calledappHighlight. See theHow it works… section for why that happens, and for a brief explanation of the standalone API.

  1. Now that we have the directive in place, we’ll create two inputs for the directive to be passed fromAppComponent (fromapp.component.html)—one for the search text and another for the highlight color. The code should look like this in thehighlight.directive.ts file:
    import {Directive,Input }from'@angular/core';@Directive({selector:'[appHighlight]',standalone:true})exportclassHighlightDirective {@Input() highlightText ='';@Input() highlightColor ='yellow';}
  2. Let’s use theappHighlight directive inapp.component.html and pass thesearchText model from there to theappHighlight directive as follows:
    <divclass="content"role="main">  ...<pclass="text-content"appHighlight[highlightText]="searchText">    ...</p></div>
  3. We’ll listen to the input changes now for thesearchText input, usingngOnChanges. Please see theUsing ngOnChanges to intercept input property changes recipe inChapter 1,Winning Component Communication, for how to listen to input changes. For now, we’ll only do aconsole.log when the input changes. Let’s update thehighlight.directive.ts as follows:
    import {Directive,Input,OnChanges,SimpleChanges }from'@angular/core';...exportclassHighlightDirective implementsOnChanges {  @Input() highlightText ='';  @Input() highlightColor ='yellow';ngOnChanges(changes: SimpleChanges) {if (changes['highlightText']?.firstChange) {return;    }const { currentValue } = changes['highlightText'];console.log({ currentValue });  }}

    If you type in the search input and see the console logs, you’ll see the new value being logged whenever you change the value.

  1. Now, we’llwrite the logic for highlighting the search text. We’ll first import theElementRef service so that we can get access to the template element on which our directive is applied. Here’s how we’ll do this:
    import {Directive,Input,SimpleChanges,OnChanges,ElementRef }from'@angular/core';@Directive({selector:'[appHighlight]'})exportclassHighlightDirective implementsOnChanges {  @Input() highlightText ='';  @Input() highlightColor ='yellow';constructor(private el: ElementRef) { }  ...}
  2. Now we’ll replace every matching text in ourel element with a custom<span> tag with some hardcoded styles. Update yourngOnChanges code inhighlight.directive.ts as follows, and see the result:
    ngOnChanges(changes: SimpleChanges) {if (changes.highlightText.firstChange) {return;    }const { currentValue } = changes.highlightText;if (currentValue) {const regExp =newRegExp(`(${currentValue})`,'gi')this.el.nativeElement.innerHTML =this.el.nativeElement.innerHTML.replace(regExp,`<spanstyle="background-color:${this.highlightColor}">\$1</span>`)}}

    TIP

    You’ll notice that if you type a word, it will still show only one letter highlighted. That’s because whenever we replace theinnerHTML property, we end up changing the original text. Let’s fix that in the next step.

  1. To keep the originaltext intact, let’s create a property namedoriginalHTML and assign an initial value to it on the first change. We’ll also use theoriginalHTML property while replacing the values:
    ...exportclassHighlightDirective implementsOnChanges {  @Input() highlightText ='';  @Input() highlightColor ='yellow';originalHTML ='';constructor(private el: ElementRef) { }ngOnChanges(changes: SimpleChanges) {if (changes.highlightText.firstChange) {this.originalHTML =this.el.nativeElement.innerHTML;return;    }const { currentValue } = changes.highlightText;if (currentValue) {const regExp =newRegExp(`(${currentValue})`,'gi')this.el.nativeElement.innerHTML =this.originalHTML.replace(regExp,`<span>\$1</span>`)    }  }}
  2. Now, we’ll write some logic to reset everything back to theoriginalHTML property when we remove our search query (when the search text is empty). In order to do so, let’s add anelse condition, as follows:
    ...exportclassHighlightDirective implementsOnChanges {  ...ngOnChanges(changes: SimpleChanges) {   ...if (currentValue) {const regExp =newRegExp(`(${currentValue})`,'gi')this.el.nativeElement.innerHTML =this.originalHTML        .replace(regExp,`<span      >\$1</span>`)    }else {this.el.nativeElement.innerHTML =this.originalHTML;}  }}

How it works…

Wecreated an attribute directive namedhighlight (appHighlight) that takes two inputs:highlightText andhighlightColor. The directive listens to the input changes for thehighlightText input using theSimpleChanges from thengOnChanges life cycle hook by Angular. Every property in thisSimpleChanges object is aSimpleChange object that contains the following properties:

  • previousValue: any
  • currentValue: any
  • firstChange: boolean
  • isFirstChange(): boolean

First, we make sure to save the original content of the target element by getting the attached element using theElementRef service. We get it using the.nativeElement.innerHTML property on the element we apply the directive to. We save the initial value to theoriginalHTML property of the directive.

Whenever the input changes, we assign a replaced version of theoriginalHTML by replacing all the instances of the searched term in the paragraph with an additional HTML element (a<span> element). We also add the background color to this<span> element. The background color applied comes from thehighlightColor input. You can modify it to highlight using a different color. Play around and make this example your own.

See also

Creating a directive to calculate the read time for articles

In this recipe, you’ll create an attribute directive to calculate the read time of an article, just like Medium (https://medium.com), which is a platform for sharing articles and blog posts. The code for this recipe is highly inspired by my existing repository on GitHub, which you can view at the following link:https://github.com/AhsanAyaz/ngx-read-time.

Getting ready

The app that we are going towork with resides instart/apps/chapter02/ng-read-time-directive inside the cloned repository:

  1. Open the code repository in your code editor.
  2. Open the terminal, navigate to the code repository directory, and run the following command to serve the project:
    npm run serve ng-read-time-directive

    This should open the app in a new browser tab and you should see the following:

    Figure 2.3: ng-read-time-directive app running on http://localhost:4200

How to do it…

Right now, we have a paragraph in ourapp.component.html file for which we need to calculate theread-time in minutes. Let’s get started:

  1. First, we’llcreate an attribute directive namedread-time. To do that, run the following command from the project root and select the@nx/angular:directive schematics when asked:
    cd start && nx g directive read-time --directory apps/chapter02/ng-read-time-directive/src/app/directives --standalone=false

    If asked, choose the@nx/angular:directiveschematics and choose the “As provided” action.

    Note that we’re using--standalone = false in the command. That is because we have anNgModule based application and theAppComponent is not a standalone component.

  1. The preceding command creates a directive with the class nameReadTimeDirective and hasappReadTime as the selector. We’ll apply this directive to thediv that hasid set tomainContent inside theapp.component.html file as follows:
    ...<divclass="content"role="main"id="mainContent"appReadTime>...</div>
  2. Now, we’ll create a configuration object for ourappReadTime directive. This configuration will contain awordsPerMinute value, on the basis of which we’ll calculate the read time. Let’s create an input inside theread-time.directive.ts file with aReadTimeConfig exported interface for the configuration, as follows:
    import {Directive,Input }from'@angular/core';export interfaceReadTimeConfig {wordsPerMinute: number;}@Directive({selector:'[appReadTime]'})exportclassReadTimeDirective {@Input()configuration:ReadTimeConfig = {wordsPerMinute:200}constructor() { }}
  3. We cannow move on to getting the text to calculate the read time. For this, we’ll use theElementRef service to retrieve thetextContent property of the element. We’ll extract thetextContent property and assign it to a local variable namedtext in thengOnInit life cycle hook, as follows:
    import {Directive,Input,ElementRef,OnInit }from'@angular/core';...exportclassReadTimeDirectiveimplementsOnInit {  @Input()configuration:ReadTimeConfig = {wordsPerMinute:200  }constructor(private el: ElementRef) { }ngOnInit() {const text =this.el.nativeElement.textContent;}}
  4. Now that we have our text variable filled up with the element’s entire text content, we can calculate the time to read this text. For this, we’ll create a method namedcalculateReadTime by passing thetext property to it, as follows:
    ...exportclassReadTimeDirective implementsOnInit {  ...ngOnInit() {const text =this.el.nativeElement.textContent;const time =this.calculateReadTime(text);console.log({readTime: time });  }calculateReadTime(text: string) {const wordsCount = text.split(/\s+/g).length;const minutes = wordsCount /this.configuration.wordsPerMinute;returnMath.ceil(minutes);}}

    If youlook at the console now, you should see an object containing thereadTime property being logged. The value ofreadTime is the time in minutes:

    Figure 2.4: Console log showing the time in minutes

  1. We’ve got the time now in minutes, but it’s not in a user-readable format at the moment since it is just a number. We need to show it in a way that is understandable for the end user. To do so, we’ll do some minor calculations and createanappropriate string to show on the UI. The code is shown here:
    ...@Directive({selector:'[appReadTime]'})exportclassReadTimeDirective implementsOnInit {...ngOnInit() {const text =this.el.nativeElement.textContent;const time =this.calculateReadTime(text);const timeStr =this.createTimeString(time);console.log({readTime: timeStr });  }...createTimeString(timeInMinutes: number) {if (timeInMinutes <1) {return'< 1 minute';}elseif (timeInMinutes ===1) {return'1 minute';}else {return`${timeInMinutes} minutes`;}}}

    Note that with the code so far, you should be able to see the minutes on the console when you refresh the application.

  1. Now, let’s add an@Output() to the directive so that we can get the read time in the parent component and display it on the UI. Let’s add it as follows in theread-time.directive.ts file:
    import {Directive,Input,ElementRef,OnInit,Output,EventEmitter }from'@angular/core';...exportclassReadTimeDirective implementsOnInit {  @Input()configuration:ReadTimeConfig = {wordsPerMinute:200  }@Output() readTimeCalculated =newEventEmitter<string>();constructor(private el: ElementRef) { }...}
  2. Let’s use thereadTimeCalculated output to emit the value of thetimeStr variable from thengOnInit method when we’ve calculated the read time:
    ...exportclassReadTimeDirective {...ngOnInit() {const text =this.el.nativeElement.textContent;const time =this.calculateReadTime(text);const timeStr =this.createTimeString(time);this.readTimeCalculated.emit(timeStr);  }...}
  3. Since we emit theread-time value using thereadTimeCalculated output, we have to listen to this output’s event in theapp.component.html file and assign it to a property of theAppComponent class so that we can show this on the view. But before that, we’ll create a local property in theapp.component.ts file to store the output event’s value, and we’ll also create a method to be called upon when the output event is triggered. The code is shown here:
    ...exportclassAppComponent {readTime!: string;onReadTimeCalculated(readTimeStr: string) {this.readTime = readTimeStr;}}
  4. We can now listen to the output event in theapp.component.html file, and we can then call theonReadTimeCalculated method when thereadTimeCalculated output event is triggered:
    ...<divclass="content"role="main"id="mainContent"appReadTime(readTimeCalculated)="onReadTimeCalculated($event)">...</div>
  5. Now, wecan finally show the read time in theapp.component.html file, as follows:
    <divclass="content"role="main"id="mainContent"appReadTime  (readTimeCalculated)="onReadTimeCalculated($event)"><h4class="text-3xl">Read Time = {{readTime}}</h4><pclass="text-content">    Silent sir say desire fat him letter. Whatever settling    goodness too and honoured she building answered her. ...</p>...</div>

    If you now go tohttp://localhost:4200, you should be able to see the read time in the app, as shown in the following image:

    Figure 2.5: Read time being displayed in the app

How it works…

TheappReadTime directive is at the heart of this recipe. While creating the directive, we create it as a non-standalone directive because the application itself is bootstrapped using an NgModule instead of a standaloneAppComponent. We use theElementRef service inside the directive to get the native element that the directive is attached to and then we take out its text content. The only thing that remains then is to perform the calculation. We first split the entire text content into words by using the/\s+/gregular expression (regex), and thus we count the total words in the text content. Then, we divide the word count by thewordsPerMinute value we have in the configuration to calculate how many minutes it would take to read the entire text. Finally, we make it readable in a better way using thecreateTimeString method.Easy peasy, lemon squeezy.

See also

Creating a directive that allows you to vertically scroll to an element

Can youimagine being able to instantly jump to any place that your eyes can see? That would be awesome!Wouldn’t it? But what if we wanted our app to be able to do that? In this recipe, you’ll create a directive that the user can click to jump to specific sessions in an Angular application.

Getting ready

The app that we are going to work with resides instart/apps/chapter02/ng-scroll-to-directive inside the cloned repository:

  1. Open the code repository in your code editor.
  2. Open the terminal, navigate to the code repository directory, and run the following command to serve the project:
    npm run serve ng-scroll-to-directive

    This should open the app in a new browser tab, and you should see the following:

    Figure 2.6: ng-scroll-to-directive app running on http://localhost:4200

How to do it…

  1. First, we’ll create ascroll-to directive so that we can enhance our application with smooth scrolls to different sections. We’ll do this using the following command in the workspace root folder:
    cd start && nx g directive scroll-to --directory apps/chapter02/ng-scroll-to-directive/src/app/directives

    If asked, choose the@nx/angular:component schematics and choose the “As provided” action.

  1. Now, we need to make the directive capable of accepting an@Input() that’ll contain theCSS Query Selector for our target section, which we’ll scroll to upon the element’sclick event. Let’s add the input as follows to ourscroll-to.directive.ts file:
    import {Directive,Input }from'@angular/core';@Directive({selector:'[appScrollTo]'})exportclassScrollToDirective {  @Input() target ='';}
  2. Now, we’ll apply theappScrollTo directive to the links in theapp.component.html file along with the respective targets. We’ll replace thehref attribute with thetarget attribute. The code should look like this:
    ...<mainclass="content"role="main"><divclass="page-links"><h4class="page-links__heading">      Links</h4><aclass="page-links__link"appScrollTotarget="#resources">Resources</a><aclass="page-links__link"appScrollTotarget="#nextSteps">Next Steps</a><aclass="page-links__link"appScrollTotarget="#moreContent">More Content</a><aclass="page-links__link"appScrollTotarget="#furtherContent">Further Content</a><aclass="page-links__link"appScrollTotarget="#moreToRead">More To Read</a></div></main>  ...<aappScrollTotarget="#toolbar"class="to-top-button w-12h-12 text-white flex items-center justify-center"><spanclass="material-symbols-outlined text-3xl text-white"> expand_less</span></a>
  3. Now, we’ll implement theHostListener() decorator to bind theclick event to the element thedirective is attached to. We’ll just log thetarget input when we click the links. Let’s implement this, and then you can try clicking on the links to see the value of thetarget input on the console:
    import {Directive,Input,HostListener }from'@angular/core';@Directive({selector:'[appScrollTo]'})exportclassScrollToDirective {  @Input() target ='';@HostListener('click')onClick() {console.log(this.target);}  ...}
  4. We will now implement the logic to scroll to a particular target. We’ll use thedocument.querySelector method, using thetarget variable’s value to get the element, and then theElement.scrollIntoView web API to scroll to the target element. With this change, you should see the page scrolling to the target element already when you click the corresponding link:
    ...exportclassScrollToDirective {  @Input() target ='';  @HostListener('click')onClick() {const targetElement =document.querySelector(this.target);if (!targetElement) {thrownewError('`target' is required.`);}targetElement.scrollIntoView();  }  ...}
  5. All right—we got the scroll to work.“But what’s new, Ahsan? Isn’t this exactly what we were already doing with the href implementation before?” Well, you’re right. But we’regoing to make the scroll supersmoooooth. We’ll passscrollIntoViewOptions as an argument to thescrollIntoView method with the{behavior: "smooth"} value to use an animation during the scroll. The code should look like this:
    ...exportclassScrollToDirective {  @Input() target ='';  @HostListener('click')onClick() {const targetElement =document.querySelector      (this.target);    targetElement.scrollIntoView({behavior:'smooth'});  }}

How it works…

The essence of this recipe is the web API that we’re using within an Angular directive, which isElement.scrollIntoView. We first attach ourappScrollTo directive to the elementsthat should trigger scrolling upon clicking them. We also specify which element to scroll to by using thetarget input for each directive attached. Then, we implement theclick handler inside the directive with thescrollIntoView method to scroll to a particular target, and to use a smooth animation while scrolling, we pass the{behavior: 'smooth'} object as an argument to thescrollIntoView method.

See also

Writing your first custom structural directive

In this recipe, you’ll write your first custom structural directive namedshowFor (or*appShowFor with the prefix). A structural directive is one that can add or remove elements from the DOM. So, with this directive, we will add the particular element to the DOM if a provided Boolean is true, and we will remove it after the specified time (provided as a number representing milliseconds).

Getting ready

The app that we are going to work with resides instart/apps/chapter02/ng-show-for-directive inside the cloned repository:

  1. Open the code repository in your code editor.
  2. Open the terminal, navigate to the code repository directory, and run the following command to serve the project:
    npm run serve ng-show-for-directive

    This should open the app in a new browser tab, and you should see the following:

    Figure 2.7: ng-show-for-directive app running on http://localhost:4200

How to do it…

  1. First of all, we’llcreate a directive using the following command in the workspace root folder:
    cd start && nx g directive show-for --directory apps/chapter02/ng-show-for-directive/src/app/directives --standalone=false

    If asked, choose the@nx/angular:component schematics and choose the “As provided” action.

  1. Now, instead of the*ngIf directive in theapp.component.html file on the element with the class"dialog", we can use our*appShowFor directive:
    ...<mainclass="content"role="main"><button (click)="toggleDialog()">Toggle Dialog</button><divclass="dialog"*appShowFor="showDialog"><divclass="dialog__heading">...</div><divclass="dialog__body">...</div></div></main>
  2. Now that we have set the condition, we need to create two@Input properties inside the directive’s TypeScript file, one being aboolean property and one being anumber. We’ll use asetter to intercept the Boolean value’s changes and will log the value to the console for now:
    import {Directive,Input }from'@angular/core';@Directive({selector:'[appShowFor]',})exportclassShowForDirective {@Input() duration =1500;@Input()setappShowFor(value: boolean) {console.log({showForValue: value });}}
  3. If you tap on theToggle Dialog button now, you should see the values being changed and reflected on the console, as follows:

Figure 2.8: Console logs displaying changes for the appShowFor directive values

  1. Now, we’re moving toward the actual implementation of showing and hiding the content based on the value beingfalse andtrue respectively. For that, we first need theTemplateRef service and theViewContainerRef service injected into the constructor of theif-not.directive.ts file. Let’s add these, as follows:
    import {Directive,Input,TemplateRef,ViewContainerRef }from'@angular/core';@Directive({selector:'[appShowFor]'})exportclassShowForDirective{  @Input() duration =1500;  @Input()setappShowFor(value: boolean) {console.log({showForValue: value });   }constructor(private templateRef: TemplateRef<any>,private viewContainerRef: ViewContainerRef) {}}
  2. Now let’s showthe element. We’re going to create ashow method and we’ll call it when the value of theappShowFor property becomestrue. The code should look as follows:
    ...exportclassShowForDirective {  @Input() duration =1500;  @Input()setappShowFor(value: boolean) {console.log({showForValue: value });if (value) {this.show();}  }show() {this.viewContainerRef.createEmbeddedView(this.templateRef);}constructor(...) {}}

    If you click theToggle Dialog button now, you should be able to see the dialog as follows:

    Figure 2.9: Dialog being shown using the show method

  1. Let’s implement the logic of hiding the dialog. We’ll use an@Output() prop with anEventEmitter for this as we want the value ofappShowFor that’s passed by the parent to be updated, instead of updating it within the directive. Modify the code as follows:
    import { ... ,EventEmitter}from'@angular/core';...exportclassShowForDirective {  @Input() duration =1500;  @Input()setappShowFor(value: boolean) {    ...  }@Output() elementHidden =newEventEmitter();show() {...}hide() {this.viewContainerRef.clear();}constructor(...) {}}
  2. Now that we have thehide method there, let’s call it after the duration time saved in theduration property of the directive. This is so the dialog hides after that duration. Modify the code of theshow method as follows:
    show() {this.viewContainerRef.createEmbeddedView(this.templateRef  );setTimeout(() => {this.elementHidden.emit();},this.duration); }

    With this change, you’ll see that nothing happens if you click theToggle Dialog button after the dialog is shown, i.e., it never gets hidden. For that, we need to listen to theelementHidden event emitter we just created.

  1. Let’s make theapp.component.html listen to theelementHidden event listener to change the value of theshowDialog property as follows:
    <divclass="dialog" *appShowFor="showDialog"(elementHidden)="toggleDialog()"><divclass="dialog__heading">            I am a Dialog</div><divclass="dialog__body">      And this is some random content</div></div>

    With this change, you’ll notice that it still doesn’t work. Yep! Because we need to call thehide method when the value ofshowDialog passed as theappShowFor prop is set tofalse.

  1. Let’s call thehide method in theShowForDirective (in theappShowFor property’sset method) when the value ofappShowFor becomesfalse as follows:
    @Input()setappShowFor(value: boolean) {console.log({showForValue: value });if (value) {this.show();    }else {this.hide();}  }

    The thing is… this still won’t work because a structural directive in Angular can’t emit values. Or even if it does, the parent element won’t be able to listen to it. The following Stack Overflow question discusses why and links to an open GitHub issue in the Angular repository as well:https://stackoverflow.com/q/44235638.

  1. To make our structural directive work, we need to get rid of the syntactic sugar it comes with. Let’s modify theapp.component.html to use the directive in a different (expanded) way, as follows:
    <mainclass="content"role="main"><button (click)="toggleDialog()">Toggle Dialog</button><ng-template [appShowFor]="showDialog"(elementHidden)="toggleDialog()"><divclass="dialog"><divclass="dialog__heading">        I am a Dialog</div><divclass="dialog__body">        And this is some random content</div></div></ng-template></main>

    The dialog should be hidden now. Yay! But wait. Try clicking theToggle Dialog button lots of times quickly. You’ll see that the app goes crazy. That’s because we end up having too manysetTimeout functions registered.

  1. Let’s clear thesetTimeout if we toggle the dialog to manually hide it. Update the code for theShowForDirective class as follows:
    ...exportclassShowForDirective {  ...timer!:ReturnType<typeofsetTimeout>;show() {this.viewContainerRef.createEmbeddedView(this.templateRef    );this.timer =setTimeout(() => {this.elementHidden.emit();    },this.duration);  }hide() {clearTimeout(this.timer);this.viewContainerRef.clear();  }constructor(...) {}}

Awesome! You’ll notice that even if you click theToggle Dialog button fast and too many times, the app behaves correctly.

How it works…

Structural directives in Angular are special for multiple reasons. First, they allow you to manipulate DOM elements—that is, not just showing and hiding but also adding and removing elements entirely from the DOM based on your needs. Moreover, they have the* prefix, which binds to all the magic Angular does behind the scenes. For example, Angular automatically provides theTemplateRef andViewContainer for working with this directive. As an example,*ngIf and*ngFor are both structural directives that work behind the scenes with the<ng-template> directive containing the content you bind the directive to. They then create the required variables/properties for you in the scope ofng-template. In this recipe, we do the same. We use theTemplateRef service to access the<ng-template> directive that Angular creates for us behind the scenes, containingthehost element to which ourappShowFor directive is applied. We use theViewContainerRef service to add theTemplateRef to the DOM via thecreateEmbeddedView method.

We do this when the value of theappShowFor property becomestrue. Notice that we’re intercepting the propertyappShowFor using asetter. We learned about this inChapter 1,Winning Components Communication. We then use asetTimeout to automatically notify the parent component that the value passed to theappShowFor property needs to be changed tofalse. We do this using an@Output() emitter namedelementHidden. Notice that we’re not supposed to make itfalse within the directive. The parent component is supposed to do it and it will automatically reflect in the directive. Our directive is supposed to react to that change and hide (or remove) theTemplateRef from theViewContainer. You can see that we do this in thehide method using thethis.viewContainerRef.clear(); statement. One of the key things to learn from this recipe is that if we use syntactic sugar, i.e.,*appShowFor, in theapp.component.html, we can’t listen totheelementHidden event emitter. That’s because this is a quirk of Angular - there’s an open issue on GitHub about this (check theSee also section). For this to work, we removed the syntactic sugar and expanded the syntax by using a<ng-template> to wrap our dialog’s HTML instep 11. Notice that we just used[appShowFor] to pass theshowDialog variable instead of*appShowFor="showDialog". And we are also listening to theelementHidden event on the<ng-template> element itself.

See also

How to apply multiple structural directives to the same element

In certain situations, you might want to use more than one structural directive on the same host or for the same element—for example, a combination of*ngIf and*ngFor together—which is not something Angular supports out of the box. The reason is that it is hard to identify which directive takes precedence over the other, and even if there was a system, I think the apps would become too complex and hard to manage. In this recipe, we will show a message conditionally using*ngIf when we have no items in the bucket. Since we’re supposed to show it conditionally and apply thefor loop on the element, this is a perfect example to use for this recipe.

Getting ready

The app that we are going to work with resides instart/apps/chapter02/ng-multi-struc-directives inside the cloned repository:

  1. Open the code repository in your code editor.
  2. Open the terminal, navigate to the code repository directory, and run the following command to serve the project:
    npm run serve ng-multi-struc-directives

    This should open the app in a new browser tab, and you should see the following:

    Figure 2.10: ng-multi-struc-directives app running on http://localhost:4200

Now that we have the app running, let’s see the steps for this recipe in the next section.

How to do it…

  1. We’ll start by creating a template for the message to be shown when there are no items in the bucket. We’ll modify theapp.component.html file for this as follows:
    <divclass="fruits">    ...<ng-template #bucketEmptyMessage><divclass="fruits__no-items-msg">No items in bucket. Add some fruits!</div></ng-template></div>
  2. Now we’ll try to apply the*ngIf condition to the element that renders the fruits. Let’s modify the code in the same file, as follows:
    ...<divclass="fruits"><divclass="fruits__item"      *ngFor="let item of bucket"*ngIf="bucket.length > 0; else bucketEmptyMessage">...</div><ng-template #bucketEmptyMessage>...</ng-template></div>

    Assoon as you save the preceding code, you’ll see the application breaks, saying that we can’t use multiple template bindings on one element. This means we can’t use multiple structural directives on one element:

    Figure 2.11: Angular Language Service explaining we can’t use two structural directives on the same element

  1. We can fix this by moving one of the structural directives into a<ng-container> wrapper, which doesn’t create any additional HTML elements in the DOM. Let’s modify the code as follows:
    <divclass="fruits"><ng-container *ngIf="bucket.length > 0; elsebucketEmptyMessage"><divclass="fruits__item" *ngFor="let item of bucket">      ...</div></ng-container><ng-template #bucketEmptyMessage>...</ng-template></div>

    With thechange above, you should be able to see the message when there are no items in the bucket, as follows:

    Figure 2.12: The final result with *ngIf and *ngFor together

How it works…

Since we can’t use two structural directives on the same element (let’s say a button), we can always use another HTML element as a wrapper (parent) to use one of the structural directive on it, and the other structural directive on the target element (button in our case). However, that adds another element to the DOM and might cause problems for your element hierarchy or other layout behavioral issues, based on your implementation. However,<ng-container> is a magical element from Angular that is not added to the DOM. Instead, it just wraps the logic/condition that you apply to it, which makes it ideal for us to use in cases like these.

See also

Applying multiple directives to the same element using the Directive Composition API

In thisrecipe, you’ll use theDirective Composition API to create multiple components and apply directives to them directly for reusability instead of having to apply the directives to each component or create additional elements inside the template of the component to apply the directives.

Getting ready

The app that we are going to work with resides instart/apps/chapter02/ng-directive-comp-api inside the cloned repository:

  1. Open the code repository in your code editor.
  2. Open the terminal, navigate to the code repository directory, and run the following command to serve the project:
    npm run serve ng-directive-comp-api

    This should open the app in a new browser tab, and you should see the following:

    Figure 2.13: ng-directive-comp-api app running on http://localhost:4200

How to do it…

  1. First, we’llcreate a couple of components for our application. We’ll create one directive for the filled button, one for the outline button, and one for abutton with a tooltip. Run the following command from thestart folder within the workspace:
    nx g directive button-filled --directory apps/chapter02/ng-directive-comp-api/src/app/directives --standalone=falsenx g directive button-outlined --directory apps/chapter02/ng-directive-comp-api/src/app/directives --standalone=falsenx g directive button-with-tooltip --directory apps/chapter02/ng-directive-comp-api/src/app/directives --standalone=false

    If asked, choose the@nx/angular:component schematics and choose the “As provided” action.

    Note that all the directives we have created are non-standalone directives. That is because the application is bootstrapped with anNgModule and theAppComponent is not a standalone component. Therefore, we these directives to be imported in theapp.module.ts for this recipe to work.

  1. Let’s make theButtonDirective a standalone directive, which means this isn’t going to be a part of anyNgModule. Update thebutton.directive.ts as follows:
    ...@Directive({selector:'[appButton]',standalone:true,})exportclassButtonDirective {  ...}
  2. Let’s alsoremove it from theapp.module.ts file as it is now astandalone directive. Update theapp.module.ts file as follows:
    ...import {ButtonDirective }from'./directives/button.directive';// <-- remove the import...@NgModule({declarations: [    ...,ButtonDirective,// <-- remove this    ...  ],  ...})exportclassAppModule {}

    You’ll noticethat none of the buttons have the required styles anymore as follows:

    Figure 2.14: Styles from the button directive are gone

  1. Let’s update theButtonFilledDirective to use theButtonDirective usingthe Directive Composition API. Update thebutton-filled.directive.ts file as follows:
    import {Directive,HostBinding }from'@angular/core';import {ButtonDirective }from'./button.directive';@Directive({selector:'[appButtonFilled]',hostDirectives: [{directive:ButtonDirective,inputs: ['color'],},],})exportclassButtonFilledDirective {@HostBinding('attr.fill')fill ='filled';}
  2. We can use theappButtonFilled directive in theapp.component.html file as follows:
    ...<mainclass="content"role="main"><ulclass="flex flex-col"><liclass="flex gap-4 items-center border-b justify-      between border-slate-300 py-3">...</li><liclass="flex gap-4 items-center border-b justify-      between border-slate-300 py-3"><h4class="text-lg">Filled Button:</h4><buttonappButtonFilledcolor="yellow">ClickMe</button></li><liclass="flex gap-4 items-center border-b justify-      between border-slate-300 py-3">...</li><liclass="flex gap-4 items-center border-b justify-      between border-slate-300 py-3">...</li></ul></main>

Notice that we’ve removed thefill attribute from the element.

  1. Let’s update theButtonOutlined directive as well. We’ll modify thebutton-outlined.directive.ts as follows:
    import {Directive,HostBinding }from'@angular/core';import {ButtonDirective }from'./button.directive';@Directive({selector:'[appButtonOutlined]',hostDirectives: [{directive:ButtonDirective,inputs: ['color'],},],})exportclassButtonOutlinedDirective {@HostBinding('attr.fill')fill ='outlined';}
  2. Let’salso modify theButtonWithTooltipDirective class. We’llupdate thebutton-with-tooltip.directive.ts as follows:
    import {Directive }from'@angular/core';import {ButtonDirective }from'./button.directive';import {TooltipDirective }from'./tooltip.directive';@Directive({selector:'[appButtonWithTooltip]',hostDirectives: [{directive:ButtonDirective,inputs: ['color','fill'],},{directive:TooltipDirective,inputs: ['appTooltip: tooltip'],},],})exportclassButtonWithTooltipDirective {}

    You will notice that the app starts throwing an error thatTooltipDirective is not a standalone component. That’s true. We need to dothe same thing we did for theButtonDirective instep 2 andstep 3 for theTooltipDirective as well. Move on to the next step once you’ve done that.

  1. Now, update theapp.component.html file to use both theappButtonOutlined andappButtonTooltip directives as follows:
    ...<mainclass="content"role="main"><ulclass="flex flex-col"><liclass="flex gap-4 items-center border-b justify-      between border-slate-300 py-3">...</li><liclass="flex gap-4 items-center border-b justify-      between border-slate-300 py-3">...</li><liclass="flex gap-4 items-center border-b justify-      between border-slate-300 py-3"><h4class="text-lg">Outlined Button:</h4><buttonappButtonOutlined>Click Me</button></li><liclass="flex gap-4 items-center border-b justify-      between border-slate-300 py-3"><h4class="text-lg">Button with Tooltip:</h4><divclass="flex flex-col gap-4"><buttonappButtonWithTooltiptooltip="code withahsan"fill="outlined"color="blue">Click Me</button><buttonappButtonWithTooltiptooltip="code withahsan"fill="filled"color="blue">Click Me</button></div></li></ul></main>

    If you’ve followed all the steps correctly, you should be able to see thefinal result as follows:

    Figure 2.15: Final result containing buttons with different directives applied

How it works…

The Directive Composition APIwas introduced in Angular v15 and has been one of the most requested features from the Angular community. In this recipe, we tried to create some components that bind the directives to the component directly in the component’s TypeScript classes rather than in the template. This eliminates the need to create a wrapper element within the components to then apply the directives or to map the inputs of the components to the inputs of the directives. This also allows multiple directives to be bound to the same component – even if they may have inputs with the same names, we can alias them differently.

The flow of the directives in our application works in the following way:

  • TheAppComponent uses theButtonFilledDirective,ButtonOutlinedDirective, andButtonWithTooltipDirective directives. For this, these directive need to be non-standalone since the application is bootstrapped with anNgModule
  • ButtonFilledDirective,ButtonOutlinedDirective, andButtonWithTooltipDirective directives use the directive composition API to use theButtonDirective and theTooltipDirective. These need to be standalone directives to be used as ‘hostDirectives'

The key to using the Directive Composition API is to construct your base-directives with thestandalone: true flag. This means your directives aren’t part of anyNgModule and can be imported directly into the imports array of any component they’re being used in. This is why we make both theButtonDirective and theTooltipDirective standalone insteps 2,3, and7. Then, we use those directives inButtonFilledDirective,ButtonOutlinedDirective, andButtonWithTooltipDirective to be able to reuse the logic without having to create any wrapper component or additional HTML. We do it using thehostDirectives property in the directive metadata. Notice that we pass an array of objects to this property and each object can contain thedirective property, which takes the class of thedirective to be applied. And we can also provideinputs andoutputs for the host bindings. As you saw for theButtonWithTooltipDirective, we also aliased theappTooltip input of theTooltipDirective with thetooltip input of theButtonWithTooltipDirective. One thing to notice is that if you don’t want to map any inputs or outputsand just want to bind a directive in thehostDirectives, you can just provide an array of the classes of the directives to be applied as follows:

hostDirectives: [ButtonDirective,TooltipDirective],

See also

Learn more on Discord

To join the Discord community for this book – where you can share feedback, ask questions to the author, and learn about new releases – follow the QR code below:

https://packt.link/AngularCookbook2e

Left arrow icon

Page1 of 8

Right arrow icon
Download code iconDownload Code

Key benefits

  • Explore updated and new recipes to fill gaps in your knowledge while using Angular in production
  • Discover industry best practices and tooling to enhance your development experience with Angular’s renaissance
  • Gain an understanding of advanced Angular topics to become a proficient enterprise web developer

Description

Angular has long been the framework of choice for web development projects of various scales, offering much-needed stability and a rich tooling ecosystem for building production-ready web and mobile apps. This recipe-based guide ensures high performance apps with the latest version of Angular, helping you to build up your Angular expertise with a wide range of recipes across key tasks in web development.In this second edition, the recipes have been updated, added, and improved based on developer feedback, new challenges, and Angular 17. The first few chapters will show you how to utilize core Angular concepts such as components, directives, and services to get you ready for building frontend web apps. You’ll then develop web components with Angular and go on to learn about advanced concepts such as dynamic components loading and state management with NgRx for achieving real-time performance. Later chapters will focus on recipes for effectively testing your Angular apps to make them fail-safe, before progressing to techniques for optimizing your app’s performance. Finally, you’ll create Progressive Web Apps (PWA) with Angular to provide an intuitive experience for users. By the end of this book, you’ll be able to create full-fledged, professional-looking Angular apps and have the skills you need for frontend development.

Who is this book for?

This book is for intermediate-level Angular developers looking for actionable solutions to common problems in Angular enterprise development. Mobile developers using Angular will also find the recipes in this book useful. Working experience with JavaScript and TypeScript is necessary to understand the topics covered in this book more effectively.

What you will learn

  • Gain a better understanding of how components, services, and directives work in Angular
  • Get to grips with creating Progressive Web Apps using Angular from scratch
  • Build rich animations and add them to your Angular apps
  • Manage your app's data reactivity using RxJS
  • Implement state management for your Angular apps with NgRx
  • Optimize the performance of your new and existing web apps
  • Write fail-safe unit tests and end-to-end tests for your web apps using Jest and Cypress
  • Get familiar with Angular CDK components for designing effective Angular components

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date :Dec 29, 2023
Length:536 pages
Edition :2nd
Language :English
ISBN-13 :9781803248073
Vendor :
Google
Languages :
Tools :

What do you get with eBook?

Product feature iconInstant access to your Digital eBook purchase
Product feature icon Download this book inEPUB andPDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature iconDRM FREE - Read whenever, wherever and however you want
Product feature iconAI Assistant (beta) to help accelerate your learning
OR

Contact Details

Modal Close icon
Payment Processing...
tickCompleted

Billing Address

Product Details

Publication date :Dec 29, 2023
Length:536 pages
Edition :2nd
Language :English
ISBN-13 :9781803248073
Vendor :
Google
Category :
Languages :
Concepts :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99billed monthly
Feature tick iconUnlimited access to Packt's library of 7,000+ practical books and videos
Feature tick iconConstantly refreshed with 50+ new titles a month
Feature tick iconExclusive Early access to books as they're written
Feature tick iconSolve problems while you work with advanced search and reference features
Feature tick iconOffline reading on the mobile app
Feature tick iconSimple pricing, no contract
$199.99billed annually
Feature tick iconUnlimited access to Packt's library of 7,000+ practical books and videos
Feature tick iconConstantly refreshed with 50+ new titles a month
Feature tick iconExclusive Early access to books as they're written
Feature tick iconSolve problems while you work with advanced search and reference features
Feature tick iconOffline reading on the mobile app
Feature tick iconChoose a DRM-free eBook or Video every month to keep
Feature tick iconPLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick iconExclusive print discounts
$279.99billed in 18 months
Feature tick iconUnlimited access to Packt's library of 7,000+ practical books and videos
Feature tick iconConstantly refreshed with 50+ new titles a month
Feature tick iconExclusive Early access to books as they're written
Feature tick iconSolve problems while you work with advanced search and reference features
Feature tick iconOffline reading on the mobile app
Feature tick iconChoose a DRM-free eBook or Video every month to keep
Feature tick iconPLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick iconExclusive print discounts

Frequently bought together


Learning Angular
Learning Angular
Read more
Feb 2023446 pages
Full star icon4.7 (32)
eBook
eBook
$38.99$43.99
$54.99
Angular Projects
Angular Projects
Read more
Jul 2023312 pages
Full star icon4.4 (20)
eBook
eBook
$29.99$33.99
$41.99
Angular Cookbook
Angular Cookbook
Read more
Dec 2023536 pages
Full star icon4 (13)
eBook
eBook
$29.99$33.99
$41.99
Stars icon
Total$138.97
Learning Angular
$54.99
Angular Projects
$41.99
Angular Cookbook
$41.99
Total$138.97Stars icon

Table of Contents

15 Chapters
Winning Component CommunicationChevron down iconChevron up icon
Winning Component Communication
Technical requirements
Component communication using component @Input and @Output properties
Component communication using services
Using setters for intercepting input property changes
Using ngOnChanges to intercept input property changes
Accessing a child component in a parent template via template variables
Accessing a child component in a parent component class using ViewChild
Standalone components and passing data through route params
Component communication using signals
Working with Angular Directives and Built-In Control FlowChevron down iconChevron up icon
Working with Angular Directives and Built-In Control Flow
Technical requirements
Using attribute directives to handle the appearance of elements
Creating a directive to calculate the read time for articles
Creating a directive that allows you to vertically scroll to an element
Writing your first custom structural directive
How to apply multiple structural directives to the same element
Applying multiple directives to the same element using the Directive Composition API
The Magic of Dependency Injection in AngularChevron down iconChevron up icon
The Magic of Dependency Injection in Angular
Technical requirements
Using Angular DI tokens
Optional dependencies
Creating a singleton service using providedIn
Creating a singleton service using forRoot()
Providing alternate classes against the same DI Token
Dynamic configurations using value providers
Understanding Angular AnimationsChevron down iconChevron up icon
Understanding Angular Animations
Technical requirements
Creating your first two-state Angular animation
Working with multi-state animations
Creating complex Angular animations using keyframes
Animating lists in Angular using stagger animations
Sequential vs parallel animations in Angular
Route animations in Angular
Disabling Angular animations conditionally
Angular and RxJS – Awesomeness CombinedChevron down iconChevron up icon
Angular and RxJS – Awesomeness Combined
Technical requirements
Sequential and parallel http calls in Angular with RxJS
Listening to multiple observable streams
Unsubscribing streams to avoid memory leaks
Using Angular’s async pipe to unsubscribe streams automatically
Using the map operator to transform data
Using the switchMap and debounceTime operators with autocompletes for better performance
Creating a custom RxJS operator
Retrying failed HTTP calls with RxJS
Reactive State Management with NgRxChevron down iconChevron up icon
Reactive State Management with NgRx
Technical requirements
Creating your first NgRx store with actions and reducers
Using NgRx Store Devtools to debug state changes
Using NgRx selectors to select and render state in components
Using NgRx effects to fetch data from API calls
Using NgRx Component Store to manage the state of a component
Understanding Angular Navigation and RoutingChevron down iconChevron up icon
Understanding Angular Navigation and Routing
Technical requirements
Creating routes in an Angular (standalone) app
Lazily loaded routes in Angular
Preloading route strategies
Authorized access to routes using route guards
Working with route parameters
Showing a global loader between route changes
Mastering Angular FormsChevron down iconChevron up icon
Mastering Angular Forms
Technical requirements
Creating your first template-driven form with validation
Creating your first reactive form with validation
Testing forms in Angular
Server-side validation using asynchronous validator functions
Implementing complex forms with reactive FormArray
Writing your own custom form control using ControlValueAccessor
Angular and the Angular CDKChevron down iconChevron up icon
Angular and the Angular CDK
Technical requirements
Using virtual scroll for huge lists
Keyboard navigation for lists
Pointy little popovers with the Overlay API
Input coercion utilities from the Angular CDK
Using the CDK Drag and Drop API to move items from one list to another
Creating a multi-step game with the CDK Stepper API
Accessible listbox interactions using CDK Listbox directives
Working with nested menus using the Angular CDK Menu API
Writing Unit Tests in Angular with JestChevron down iconChevron up icon
Writing Unit Tests in Angular with Jest
Technical requirements
Setting up unit tests in Angular with Jest
Providing global mocks for Jest
Mocking Angular services using stubs
Using spies on an injected service in a unit test
Mocking child components and directives using the ng-mocks package
Writing even easier tests with Angular CDK component harnesses
Unit-testing responses from HTTP calls
Unit-testing Angular pipes
E2E Tests in Angular with CypressChevron down iconChevron up icon
E2E Tests in Angular with Cypress
Technical requirements
Writing your first Cypress test
Validating if a DOM element is visible on the view
Testing form inputs and submission
Waiting for XHRs to finish
Using Cypress bundled packages
Using Cypress fixtures to provide mock data
Performance Optimization in AngularChevron down iconChevron up icon
Performance Optimization in Angular
Technical requirements
Using OnPush change detection to prune component subtrees
Detaching the change detector from components
Running async events outside Angular with runOutsideAngular
Using trackBy for lists with *ngFor
Moving heavy computation to pure pipes
Using web workers for heavy computation
Using performance budgets for auditing
Analyzing bundles with webpack-bundle-analyzer
Building PWAs with AngularChevron down iconChevron up icon
Building PWAs with Angular
Technical requirements
Converting an existing Angular app into a PWA with the Angular CLI
Modifying the theme color for your PWA
Using dark mode in your PWA
Providing a custom installable experience in your PWA
Precaching requests using an Angular service worker
Creating an App Shell for your PWA
Other Books You May EnjoyChevron down iconChevron up icon
Other Books You May Enjoy
IndexChevron down iconChevron up icon
Index

Recommendations for you

Left arrow icon
Full-Stack Flask and React
Full-Stack Flask and React
Read more
Oct 2023408 pages
Full star icon3.8 (5)
eBook
eBook
$27.99$31.99
$39.99
Real-World Web Development with .NET 9
Real-World Web Development with .NET 9
Read more
Dec 2024578 pages
Full star icon3.5 (4)
eBook
eBook
$35.98$39.99
$49.99
Django 5 By Example
Django 5 By Example
Read more
Apr 2024820 pages
Full star icon4.6 (40)
eBook
eBook
$35.98$39.99
$49.99
React and React Native
React and React Native
Read more
Apr 2024518 pages
Full star icon4.3 (10)
eBook
eBook
$31.99$35.99
$43.99
Scalable Application Development with NestJS
Scalable Application Development with NestJS
Read more
Jan 2025612 pages
Full star icon4.5 (6)
eBook
eBook
$27.99$31.99
$39.99
Responsive Web Design with HTML5 and CSS
Responsive Web Design with HTML5 and CSS
Read more
Sep 2022504 pages
Full star icon4.5 (57)
eBook
eBook
$31.99$35.99
$44.99
Modern Full-Stack React Projects
Modern Full-Stack React Projects
Read more
Jun 2024506 pages
Full star icon4.8 (9)
eBook
eBook
$31.99$35.99
$44.99
Learning Angular
Learning Angular
Read more
Jan 2025494 pages
Full star icon4 (6)
eBook
eBook
$31.99$35.99
$44.99
Right arrow icon

Customer reviews

Top Reviews
Rating distribution
Full star iconFull star iconFull star iconFull star iconEmpty star icon4
(13 Ratings)
5 star69.2%
4 star0%
3 star7.7%
2 star7.7%
1 star15.4%
Filter icon Filter
Top Reviews

Filter reviews by




N/AApr 04, 2024
Full star iconFull star iconFull star iconFull star iconFull star icon5
Feefo Verified reviewFeefo
Francisco RodriguesNov 11, 2024
Full star iconFull star iconFull star iconFull star iconFull star icon5
I'm still reading the book, but so far I'm very satisfied with the content. Well organized and objective.
Feefo Verified reviewFeefo
Stefan DjokicFeb 26, 2024
Full star iconFull star iconFull star iconFull star iconFull star icon5
As a backend developer, I read this book because I was about to land on a project that uses Angular as a front-end technology. The book is quite clearly conceived, and everything is properly explained through examples. It helped me, with all the recommendations!
Amazon Verified reviewAmazon
Chetan NadaJul 21, 2024
Full star iconFull star iconFull star iconFull star iconFull star icon5
I recently read "Angular Cookbook, 2nd Edition," by Muhammad Ahsan Ayaz and found it to be an excellent resource for mastering Angular development. The book offers over 80 actionable recipes that have deepened my understanding of Angular through practical, real-world applications.This guide helps you understand how components, services, and directives work in Angular. It's a must-have for anyone looking to improve their knowledge of this powerful framework.You'll find advanced techniques for content delivery, control flow, rich animations, parallel programming, Angular CDK, and performance optimization.Here's a brief chapter summary:Chapter 1: Communication between parent and child components.Chapter 2: Working with structural directives and the Directive Composition API.Chapter 3: Dependency injection and internal mechanisms.Chapter 4: Multi-state and keyframe animations.Chapter 5: RxJS for sequential and parallel HTTP calls.Chapter 6: Core concepts of the NgRX library.Chapter 7: Navigation and routing.Chapter 8: Template-driven and reactive forms, including testing forms.Chapter 9: Using Angular CDK for optimized content.Chapter 10: Unit testing with Jest.Chapter 11: E2E tests with Cypress, including form validation and HTTP call mocking.Chapter 12: Techniques for optimizing app performance.Chapter 13: Creating PWAs with Angular.The practical examples are well-categorized, carefully explained, and highly useful. This book is a must-have for developers. I highly recommend it to anyone eager to broaden their expertise in Angular.
Amazon Verified reviewAmazon
shubham kambleJul 20, 2024
Full star iconFull star iconFull star iconFull star iconFull star icon5
This book is perfect for any individual or team that is looking to learn how to write scalable, enterprise-grade Angular applications. This book provides 80 actionable recipes along with code samples, design patterns, and effective narratives around challenging concepts faced by any team leveraging Angular. This book will help you become a better Angular developer.Whether you’re just getting started with Angular, or are looking for a solid reference to back up industry experience, this book will be greatly helpful.
Amazon Verified reviewAmazon
  • Arrow left icon Previous
  • 1
  • 2
  • 3
  • Arrow right icon Next

People who bought this also bought

Left arrow icon
Responsive Web Design with HTML5 and CSS
Responsive Web Design with HTML5 and CSS
Read more
Sep 2022504 pages
Full star icon4.5 (57)
eBook
eBook
$31.99$35.99
$44.99
React and React Native
React and React Native
Read more
May 2022606 pages
Full star icon4.6 (17)
eBook
eBook
$35.98$39.99
$49.99
Building Python Microservices with FastAPI
Building Python Microservices with FastAPI
Read more
Aug 2022420 pages
Full star icon3.9 (9)
eBook
eBook
$33.99$37.99
$46.99
Right arrow icon

About the author

Profile icon Muhammad Ahsan Ayaz
Muhammad Ahsan Ayaz
LinkedIn iconGithub icon
Muhammad Ahsan Ayaz is a Google developers expert in Angular, a software architect, and a head instructor of JavaScript at the School of Applied Technology. He loves helping the start-up ecosystem and product owners to bring their ideas to life using JavaScript, Angular, and web technologies. He has built several open-source projects that he maintains and he speaks at events, along with creating articles and video courses.
Read more
See other products by Muhammad Ahsan Ayaz
Getfree access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook?Chevron down iconChevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website?Chevron down iconChevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook?Chevron down iconChevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support?Chevron down iconChevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks?Chevron down iconChevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook?Chevron down iconChevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.


[8]ページ先頭

©2009-2025 Movatter.jp