This is handy for situations like avoiding a hard coded set of values for a dropdown menu or displaying different content based on your component state. In my opinion, this pairs very nicely with reactive forms. By default, Angular applies the ChangeDetectionStrategy.Default mechanism to the changeDetection attribute. In this case we can directly get names of enum by looping string enum object. Why because string enums directly store key value pairs in enum object. The @Input allows parent components to be able to pass values, objects, functions down into a child to use as necessary.
Even though a child might have an input property declared, this does not mean the parent has to call it. Also, the value bound to an input property attribute needs to be the same as what the child component expects. Thus, users of the component now have the capability to change part of the UI of the component as they see fit. We can even access functionality from the parent component as well, which makes it truly flexible.
It is also possible to project multiple different sections and content into our child component. While the official Angular documentation is spare on this topic, there is a great article that can give you more insight on content projection. Notice that the two stock item components on our browser, each with slightly different content, are based on what we provided. If you click the button in the first stock widget, you will see that the method in the AppComponent gets called and the console.log is triggered. For a very large application, you will have lots of bindings on a given page.
When a user takes any action, you as a developer might know for sure that most of the page will not change. In such cases, you can actually give a hint to the Angular change detector to check or not check certain components as you see fit. For any given component, we can accomplish this by changing the ChangeDetectionStrategy from the default to ChangeDetectionStrategy.OnPush. What this tells Angular is that the bindings for this particular component will need to be checked only based on the Input to this component.
ChangeDetectionBy default, Angular checks every binding in the UI to see if it needs to update any UI element whenever any value changes in our component. This is acceptable for most applications, but as our applications get larger in size and complexity, we might want control over how and when Angular updates the UI. Instead of Angular deciding when it needs to update the UI, we might want to be explicit and tell Angular when it needs to update the UI manually. To do this, we use the changeDetection attribute, where we can override the default value of ChangeDetectionStrategy.Default to ChangeDetectionStrategy.OnPush.
This means that after the initial render, it will be up to us to let Angular know when the value changes. Angular will not check the component's bindings automatically. We will cover this in more detail later in the chapter.
The very basic component only needs a selector and a template . All other attributes in the Component decorator are optional. Let's talk about the attributes of the decorator in a bit more detail. In this chapter, we will go a bit deeper into components, those elements we have been creating to render the UI and let users interact with the applications we build.
By the end of the chapter, you should be able to perform most common tasks related to components while understanding what you are doing and why. We worked with directives like ngIf and ngForOf and got a feel for how and when to use them. Material implementation takes the glass box approach, while Nebular leans more towards black-boxing. We believe this makes the Material implementation more flexible. For example, the material implementation allows you to have buttons or anchor elements inside the menu and to have custom components like icons inside each menu item. This is also possible with Nebular, but support for that had to be added in the menu component itself, by adding additional properties inside the menu data objects.
This bloats the NbMenuItem interface which now includes all the various edge cases like icons, path matching, query params, badges, etc. If you need something similar to a badge but use your own custom component instead of the Nebular's badge, it might be hard to do it with this black box approach that Nebular took. Pipes can have multiple input values and one output value.
Input values are mapped to the output value in the transformation method. Impure pipes will execute the transformation method on each change detection cycle. This is probably not optimal nor the desired behaviour in most situations.
On the other hand, pure pipes will execute the transformation method only if some of the input values change. Angular has 2 kinds of directives, Attribute and Structural. You can create your own directives to enhance functionality or add styles. For example, at SpotDraft, we use a custom structural directive to hide elements based on feature flags. A class is a template is used to create an object with its properties like data types member variables and methods. We can say it is an object constructor or blueprint for creating an object.
A template reference can get a reference to an element by specifying the pound symbol followed by a reference variable name #thirdParty. Within the template, this template reference variable can be used along with any property/function on that DOM element. Change Detection starts at the top of the Component Tree and works its way down through every leaf checking for changes. By default, Angular starts at the top of the component tree and runs change detection on every component.
Because JavaScript objects are mutable, Angular runs change detection for every component for every event. By changing the detection strategy to OnPush, components will be marked as immutable, which will cause change detection to only run when input properties are changed. Event Binding binds a particular action to an HTML element. When this bounded action occurs, the event binding syntax also specifies the action to take, such as an inline action within the HTML or a function to call within the component. The code below shows an example of event binding where a event calls handleButtonClick(). $event is an object which conveys information about the event and can be used in the action being taken.
Specifies that changing a value within a component will change the value in the HTML as well as changing the value in the HTML will also change the value in the component. In this case, I am using ngModel, which is an internal Angular directive for form elements. ContentChildren is any child component that gets projected into the view of the component, but is not directly included in the template within the component. Imagine something like a carousel, where the functionality is encapsulated in the component, but the view, which could be images or pages of a book, comes from the user of the component. We will cover this in more depth later in this chapter. We just added an event binding using Angular's event-binding syntax to the output declared in the stock-item component.
Notice again that it is case sensitive and it has to exactly match what member variable we decorated with the Output decorator. Also, to get access to the value emitted by the component, we use the keyword $event as a parameter to the function. Without it, the function would still get triggered, but you would not get any arguments with it. We use Angular's data binding to pass in the stock from the AppComponent to the StockItemComponent. The name of the attribute has to match the name of the variable in the component that has been marked as input.
The attribute name is case sensitive, so make sure it matches exactly with the input variable name. The value that we pass to it is the reference of the object in the AppComponent class, which is stockObj. A given component can have multiple styles attached to it. This allows you to pull in component-specific CSS, as well as potentially any other common CSS that needs to be applied to it.
In the previous chapter, we saw that Angular only has directives, and that directives are reused for multiple purposes. We dealt with attribute and structural directives, which allow us to change the behavior of an existing element or to change the structure of the template being rendered. By using this approach, your translation keys are all in one place, easing refactoring and keeping the translation file clean and up to date. You will also get compilation errors if a new enum is added without adding a corresponding entry with the translation key in the record. You can further expand on this pattern by adding additional "metadata" about the enum to the record.
For example, a sortingIndex property that is taken into account when the enum values are rendered as dropdown options. In Typescript, enums are used astypes at compile-timeto achieve type-safety for the constants but they are treated asobjects at runtime. This is because they are converted to plain objects once the Typescript code is compiled to Javascript. Hence, in order to dynamically access an enum by a string key, we need to use the combination of keyof and typeof operators.
In our previous article, we have implemented user email verification based on a short-lived token. In this scenario, the token can have a different status like Valid, Invalid, Expired, etc., and based on this status, we had to render the view page. Hence, we have used an Enum for this use case to hold the different types of status. Now let's dive deep to understand how to create a TypeScript Enum and use it in Angular components. Please note that this is different from how to create html select options based upon ALL of the values of an enum . This question is about ngSwitch based upon a particular value of an enum.
Although the same approach of creating an class-internal reference to the enum appears. Here we are performing component property binding and using ngIf. To read more about component property binding, go the link Angular Property Binding Example. Now if emp1 will be null or undefined, the child component with selector my-msg will not execute.
Pipes can be used to transform date formats, convert enums to their label values and even enhance data structures. Angular comes with some built-in pipes and users can create their own too. The app component template contains all the html markup for displaying the example registration form in your browser. The form element uses the directive to bind to the registerForm FormGroup in the app component above.
To get past the template reference limitation, the @ViewChild decorator is used. Inside the decorator constructor, the name of the template reference needs to be inserted. This allows one to reference the DOM object for a template element inside the component.
From here, one can call functions and assign values on the child. We should use when we just want to apply multiple structural directives without introducing any extra element in our DOM. There's another use case where it is used to inject a template dynamically into a page.
The ngClass directive allows you to dynamically set CSS classes on an HTML element by databinding an expression that represents all classes to be added. If the expression evaluates to an object, then for each key-value pair of the object with a truthy value the corresponding key is used as a class name. We have added two instances of the app-stock-item component in our HTML. And both of these now have some content inside them, as opposed to previously where these elements had no content. In one, we have a button that triggers the testMethod we added in the AppComponent, and the other simply has text content. ViewChildren is any child component whose tags/selectors appear within the template of the component.
So in our case, app-stock-item would be a ViewChild of the AppComponent. We mentioned changeDetection as an attribute on the Component decorator. Now that we have seen how Input and Output decorators work, let's deep dive a little bit into how Angular performs its change detection at a component level.
We have removed all instantiation logic from the app-stock-item component, and marked the stock variable as an input. DeclarationsThe declarations attribute ensures that components and directives are available to use within the scope of the module. The Angular CLI will automatically add your component or directive to the module when you create a component through it. The third kind of directives are components, which we have been using pretty much from the first chapter. To some extent, you can consider an Angular application to be nothing but a tree of components.
Each component in turn has some behavior and a template that gets rendered. This template can then continue to use other components, thus forming a tree of components, which is the Angular application that gets rendered in the browser. This ends up with a bunch of if statements or similar logic in the component, growing in complexity and decreasing readability of the component's source code. There is a simple solution to this problem, and it is called the single data observable pattern.
In its purest form, it allows us to have only one subscription in the template . You can also utilize this pattern to create multiple combined observables instead of having many more individual subscriptions. The following examples in this chapter are using my-app component selector prefix. For the purposes of future-proofing and avoiding conflicts with other libs, prefix all component selectors with something unique/app-specific. If you think of it, it is not very often that the user changes the screen size when browsing the app.
You may handle the screen sizes changes application wide or just handle it everytime you need it (per use case / component basis). The TypeScript enum can be used directly in your class, but it has to be assigned to a local variable to be used in the template. The template can work only with your local variable and not the enum self.
The template can access only objects exposed by the controller or the component. In the above code, we have declared the method getProfiles() to return the list of Profile data. We can call this method from any component in the application to get the list of Profile data.