"Easy way to understand change detection in angular with example"

Easy way to understand change detection in angular with example

Angular’s change detection is a mechanism that allows the framework to automatically detect and update the view whenever there is a change in the application data. It’s a core part of Angular’s functionality that enables the framework to maintain a reactive and interactive user interface.

Angular’s change detection system operates by comparing the current and previous states of the application data. When there is a change in the data, the change detection mechanism triggers a re-evaluation of the view, updating it with the new data.

Angular offers two modes of change detection: default and OnPush. The default change detection mode checks for changes in all component properties and their nested properties. In contrast, the OnPush mode is an optimization technique that limits the change detection to the components with an @Input decorator, or that use immutable objects and observables.

The change detection process can be triggered in three ways:

  1. Default change detection: This is the default change detection strategy used by Angular. In this strategy, Angular checks for changes to the component’s properties and inputs on every change detection cycle. This can be resource-intensive and can slow down the application in large and complex applications. Here’s an example:

In the above code, the CounterComponent has a count property that is incremented every time the increment method is called. Since the default change detection strategy is used, Angular will detect and update the view on every change detection cycle.

OnPush change detection: The OnPush change detection strategy is an optimization that can improve the performance of an application by reducing the number of change detection cycles. In this strategy, Angular only checks for changes to the component’s inputs and properties if the reference to the input or property has changed. Here’s an example:

Manually triggering change detection: This can be achieved by calling the ChangeDetectorRef.detectChanges() method in the component code.

In this above example, we are using the push strategy that means CheckOnce, rather than the default CheckAlways, then forces a second check after an interval

In Angular, we can manually trigger change detection using the detectChanges() method of the ChangeDetectorRef service. The ChangeDetectorRef service is available in every Angular component and provides several methods for manually triggering change detection:

  • detectChanges(): This method triggers a change detection cycle for the component and its children.
  • markForCheck(): This method marks the component and its children for change detection but doesn’t trigger a change detection cycle immediately. Angular will trigger change detection during the next change detection cycle.
  • detach(): This method detaches the component from the change detection tree, preventing it from being checked for changes. This can be useful when we have a component that doesn’t need to be updated frequently.
  • reattach(): This method reattaches the component to the change detection tree, allowing it to be checked for changes again.

Here’s an example of manually triggering change detection:

In the above code, the MyComponent retrieves items from a DataService asynchronously and displays them in a list. When the user clicks the “Add Item” button, we add a new item to the list and mark the component for change detection using the markForCheck() method.

In summary, we can manually trigger change detection in Angular using the detectChanges() method of the ChangeDetectorRef service. Additionally, the markForCheck(), detach(), and reattach() methods provide additional flexibility for controlling when change detection is triggered.

It’s worth noting that Angular’s change detection mechanism is highly performant, thanks to its ability to detect only the changes that occur in the application data. However, it’s important to be mindful of the number of components that are being checked for changes, as this can impact the performance of the application. In some cases, optimizing the change detection strategy can lead to significant performance gains in large applications.

Step by step guide to create a theme in liferay with Angular Material UI

Liferay theme is a collection of files that define the look and feel of a Liferay portal instance. It includes files such as CSS, JavaScript, images, and templates that control the presentation and layout of the portal’s pages, as well as its overall styling and behavior.

Themes in Liferay can be customized and created from scratch to meet specific design requirements, or they can be based on pre-built templates that are available from the Liferay community or commercial sources. They can also be applied to individual sites or globally to affect the appearance of the entire portal.

In addition to providing a consistent and visually appealing user interface, Liferay themes can also improve the accessibility and usability of a portal, enhance its branding and identity, and help to create a seamless and engaging user experience for visitors and users.

What is Angular Material UI and how it can help building a better UI (User Interface) ?

Material UI is a popular user interface (UI) library for building web applications using Angular, a JavaScript library for building user interfaces. Material UI provides a set of pre-built UI components that follow Google’s Material Design guidelines, which is a design language for creating intuitive and engaging user experiences across platforms and devices.

The library includes components for common UI elements such as buttons, forms, dialogs, navigation, and more. It also provides support for responsive design, accessibility, and internationalization.

Material UI can help to speed up the development process by providing a consistent and visually appealing set of UI components that can be easily customized to fit specific design requirements. It is also widely used and supported by a large community, with regular updates and improvements being made to the library.

Here’s an example of creating Liferay theme with Angular Material UI

1. Create an Angular application using the Angular CLI:

2. Add Angular Material and the Liferay theme dependencies to the Angular project:

3. Use the Liferay Theme Generator to generate a base Liferay theme for Angular, and select Angular Material as the UI framework:

4. Customize the theme as needed by modifying the Angular code and using the Liferay theme configuration files. For example, you can modify the styles in the _custom.scss file:

5. Use Angular Material’s theming capabilities to customize the look and feel of the UI components. For example, you can change the color scheme of a button:

6. Build the theme using the Liferay theme tasks and deploy it to your Liferay instance:

Note that this is just a basic example and there are many other customization options available for both Liferay and Angular Material. Also, make sure to check the official documentation and best practices for each technology to ensure proper usage.

What’s new in liferay 7?

Liferay 7 was a major release that introduces several new features and improvements over previous versions of Liferay.

Here are some of the notable new features in Liferay 7:
  1. Modular architecture: It will allows developers to build and deploy individual components as separate modules with modular architecture. This makes it easier to develop, test, and deploy Liferay components.
  2. React-based UI: Liferay 7 introduces a new UI framework built with React, a popular JavaScript library for building user interfaces. The new UI framework provides a modern, responsive, and intuitive user experience.
  3. Content Management System (CMS): Liferay 7 includes a new CMS that provides an intuitive and easy-to-use interface for managing content, pages, and sites. The CMS allows users to create and manage content without the need for technical skills.
  4. Personalized experiences: Liferay 7 introduces features for creating personalized experiences for users based on their preferences, behaviors, and interests. This includes features for segmenting and targeting audiences, and for personalizing the content and layout of pages.
  5. Improved performance: Liferay 7 includes faster page loading times, improved scalability, and reduced resource utilization.
  6. Improved security: Liferay 7 includes several security improvements, including support for OAuth2 and OpenID Connect, improved password policies, and enhanced access control.
  7. Microservices support: Liferay 7 includes support for building and deploying microservices, which are small, independent, and modular components that can be deployed and managed separately. This allows developers to build and deploy Liferay components as microservices, making it easier to manage and scale their applications.

These are just some of the new features and improvements in Liferay 7. If you are considering upgrading to Liferay 7, it is important to carefully evaluate your specific needs and requirements, and to consult with an expert in Liferay development.

Understanding Angular lifecycle methods with Examples

In Angular, components have a lifecycle managed by Angular itself, from creation to destruction. Angular provides lifecycle methods that you can use to tap into this process and perform custom logic at specific points in the lifecycle.

Here are some examples of how you might use each lifecycle method:

ngOnChanges: This method is called whenever a bound input property changes. You can use it to react to changes in input properties and perform logic when the value of an input property changes.

In this example, the CounterComponent implements the ngOnChanges method and logs the changes to its input properties.

  1. ngOnInit: This method is called after the first ngOnChanges call and is used to perform initialization logic for the component.

In this example, the HelloComponent implements the ngOnInit method and initializes its name property.

  1. ngDoCheck: This method is called during every Angular change detection cycle and is used to perform custom change detection.

In this example, the TodoListComponent implements the ngDoCheck method and logs its items array.

  1. ngAfterContentInit: This method is called after the component’s content has been fully initialized.

In this example, the TabsComponent implements the ngAfterContentInit method and logs a message to the console.

  1. ngAfterContentChecked: This method is called after every change detection cycle that updates the component’s content. It can be used to perform logic that depends on the component’s content being fully updated and checked.

In this example, the TabsComponent implements the ngAfterContentChecked method and logs a message to the console.

6. ngAfterViewInit: This method is called after the component’s view (including its child views) has been fully initialized.

In this example, the TabPanelComponent implements the ngAfterViewInit method and logs a message to the console.

7. ngAfterViewChecked: This method is called after every change detection cycle that updates the component’s view (including its child views).

In this example, the TabListComponent implements the ngAfterViewChecked method and logs a message to the console.

8. ngOnDestroy: This method is called just before the component is destroyed by Angular. It can be used to perform cleanup logic for the component, such as unsubscribing from observables or detaching event handlers.

In this example, the TimerComponent implements the ngOnDestroy method and uses it to stop the interval timer it started in its ngOnInit method.

I hope you found this article useful and informative. Thanks 😊

Analyzing a Dendrogram

dendrogram is a tree data structure that allows us to represent the entire clustering hierarchy produced by either an agglomerative or divisive algorithm. The idea is to put the samples on the x axis and the dissimilarity level on the y axis. Whenever two clusters are merged, the dendrogram shows a connection corresponding to the dissimilarity level at which it occurred. Hence, in an agglomerative scenario, a dendrogram always starts with all samples considered as clusters and moves upward (the direction is purely conventional) until a single cluster is defined.

For didactic purposes, it’s preferable to show the dendrogram corresponding to a very small dataset, X, but all the concepts can be applied to any situation. However, with larger datasets, it will often be necessary to apply some truncations in order to visualize the entire structure in a more compact form.

How to do it?

Let’s consider a small dataset, X, made up of 12 bidimensional samples generated by 4 Gaussian distributions with mean vectors in the range (-1, 1) × (-1, 1):

 The dataset (with the labels) is shown in the following screenshot:

Dataset employed for dendrogram analysis

In order to generate a dendrogram (using SciPy), we first need to create a linkage matrix. In this case, we have chosen a Euclidean metric with Ward’s linkage (I encourage you to perform the analysis with different configurations):

The dm array is a condensed pairwise distance matrix, while Z is the linkage matrix produced by Ward’s method (the linkage() function requires the method parameter, which accepts, among others, the values single, complete, average, and ward). At this point, we can generate and plot the dendrogram (the dendrogram () function can automatically plot the diagram using a default or supplied Matplotlib axis object):

The diagram is displayed in the following screenshot:

Dendrogram corresponding to Ward’s linkage applied to the dataset

As explained in the preceding screenshot, the x axis represents the samples intended to minimize the risk of cross-connections, while the y axis shows the dissimilarity level. Let’s now analyze the diagram from the bottom. The initial state corresponds to all samples considered as independent clusters (so the dissimilarity is null). Moving upward, we start to observe the first mergers. In particular, when the dissimilarity is about 0.35, samples 1 and 3 are merged.

The second step happens with a dissimilarity of slightly below 0.5, when the samples 0 and 9 are also merged. The process goes on until a dissimilarity of about 5.25, when a single cluster is created. Let’s now dissect the dendrogram horizontally when the dissimilarity is equal to 1.25. Looking at the underlying connections, we discover that the clustering structure is: {6}, {758}, {09410}, {11}, {213}.

Clustering

Therefore, we have five clusters, with two of them made up of a single sample. It’s not surprising to observe that samples 6 and 11 are the last ones to be merged. In fact, they are much further apart than all the other ones. In the following screenshot, four different levels are shown (only the clusters containing more than one sample are marked with a circle):

Clusters generated by cutting the dendrogram at different levels (Ward’s linkage)

As is easy to understand, the agglomeration starts by selecting the most similar clusters/samples and proceeds by adding the nearest neighbors, until the root of the tree has been reached. In our case, at a dissimilarity level equal to 2.0, three well-defined clusters have been detected. The left one is also kept in the next cut, while the two right ones (which are clearly closer) are selected for merging in order to yield a single cluster. The process itself is straightforward and doesn’t need particular explanations; however, there are two important considerations.

The first one is inherent to the dendrogram structure itself. Contrary to other methods, hierarchical clustering allows observing an entire clustering tree, and such a feature is extremely helpful when it’s necessary to show how the process evolves by increasing the dissimilarity level. For example, a product recommender application could not provide any information about the desired number of clusters representing the users, but executive management might be interested in understanding how the merging process is structured and evolves.

In fact, observing how clusters are merged allows deep insight into the underlying geometry and it’s also possible to discover which clusters could potentially be considered as parts of larger ones. In our example, at level 0.5, we have the small cluster {13}. The question of “what samples can be added to this cluster by increasing the dissimilarity?” can be answered immediately with {2}. Of course, in this case, this is a trivial problem that can be solved by looking at the data plot, but with high-dimensional datasets, it can become more difficult without the support of a dendrogram.

The second advantage of dendrograms is the possibility to compare the behavior of different linkage methods. Using Ward’s method, the first mergers happen at quite low dissimilarity levels, but there’s a large gap between five clusters and three clusters. This is a consequence of both the geometry and the merging strategy. What happens, for example, if we employ a single linkage (which is intrinsically very different)? The corresponding dendrogram is shown in the following screenshot:

Dendrogram corresponding to single linkage applied to the dataset

Conclusion

The conclusion is that the dendrogram is asymmetric and the clusters are generally merged with a single sample or with small agglomerates. Starting from the right, we can see that samples {11} and {6} were merged very late. Moreover, sample {6} (which could be an outlier) is merged at the highest dissimilarity, when the final single cluster must be produced. The process can be better understood with the following screenshot:

Clusters generated by cutting the dendrogram at different levels (single linkage)

As you can see from the screenshot, while Ward’s method generates two clusters containing all samples, a single linkage aggregates the largest blocks at Level 1.0 by keeping the potential outliers outside. Therefore, the dendrogram also allows defining aggregation semantics, which can be very helpful in a psychometric and sociological context. While Ward’s linkage proceeds in a way that is very similar to other symmetric algorithms, single linkage has a step-wise fashion that shows an underlying preference for clusters built incrementally, resulting in the avoidance of large gaps in the dissimilarity.

Finally, it’s interesting to note that, while Ward’s linkage yields a potential optimal number of clusters (three) by cutting the dendrogram at Level 3.0, single linkage never reaches such a configuration (because cluster {6} is merged only in the final step). This effect is strictly related to the double principle of maximum separation and maximum cohesion. Ward’s linkage tends to find the most cohesive and separated clusters very quickly. It allows cutting the dendrogram when the dissimilarity gap overcomes a predefined threshold (and, of course, when the desired number of clusters has been reached), while other linkages require a different approach and, sometimes, yield undesirable final configurations.

Considering the nature of the problem, I encourage you to test the behavior of all linkage methods and to find out the most appropriate method for some sample scenarios (for example, the segmentation of the population of a country according to education level, occupancy, and income). This is the best approach to increase awareness and to improve the ability to provide a semantic interpretation of the processes (which is a fundamental goal of any clustering procedure).

If you found this article interesting, you can explore Hands-On Unsupervised Learning with Python to discover the skill-sets required to implement various approaches to Machine Learning with Python. Hands-On Unsupervised Learning with Python will help you explore the concept of unsupervised learning to cluster large sets of data and analyze them repeatedly until the desired outcome is found using Python.