Part 3 - AEM with Angular 2 – AEM Component development
In previous 2 parts we have seen challenges, project structure and build process for an AEM + Angular 2 project. In this post we’ll focus more on Angular 2 component development and will do a deep dive into sample component development so that we can understand various concepts involved in AEM + Angular 2 component development.
Let’s begin with defining some basic requirement for sample AEM + Angular 2 component that we’ll develop in this article.
Problem statement for our component
- Develop a simple AEM + Angular 2 component to find location details based on IP address
- Use Angular 2 Http service to get location detail (by calling remote REST web service) based on IP address provide via HTML form input
- Display data/response from REST web service using Angular 2 binding on UI
- Provide capability to authors so that they can change labels (e.g. label of “Search” button and label for “Location Detail” card/result) using component’s dialog
Image 1: “ip-location” AEM + Angular 2 in action on a AEM page
The idea behind developing this component is I want to cover AEM Authoring capabilities as well I want to show you how you can use Angular 2 features (like Http service, data binding etc.)
Before we proceed, I assume that you already know how to develop pure and simple AEM component and you also know about Angular 2 framework. Both of these skills are must to understand rest of this tutorial.
So, let’s get started!!!
We’ll be developing this component in 2 phases:
- First we’ll develop Basic AEM component (no Angular 2 code involved here)
- Create an AEM component in your application the way you have been creating AEM components (let’s say component name is ip-location). ip-location component will have a sightly template file called as “ip-location.html” and we are going to modify this file in next step.
- Create a component dialog with 2 text fields “./goBtnLabel” and “./localtionLabel”, these are the fields that author will use to input text for “Search Location” button and “Location” label (as shown in above snapshot)
- Modify basic AEM component and add Angular 2 code: In this step we’ll modify this component by adding an Angular 2 component TypeScript and template file. Here are the steps:
- Create a file in component folder called “ip-location.component.ts”, this is the TypeScript file that will have Angular 2 component’s TypeScript code. Here is screenshot of code (I’ll share github URL towards end of this post):
Image 2: “location.html” Angular 2 template/view
- At 10 we have added Angular 2 annotation/decorator for component and at line 12 we are loading a template/view for this component. NOTE the templateUrl path, we are not loading the “ip-location.html” file (which is actually component’s original sightly file), rather we are loading a different file called as “location.html”. This is because Angular 2 template will not render properly in EDIT mode and that’s why we’ll include this “location.html” explicitly from “ip-location.html” (as show below, line# 4). Have look at the test at line number 2 and 11.
Image 3: “ip-location.html” Sightly view that will load Angular view in PREVIEW mode
Image 4: “location.html” Angular 2 template referred and rendered by Angular 2 component
- At line # 8 (Image 3), we have 2 HTML attributes “goBtnLabel” and “localtionLabel” populated using JCR property values (i.e. values entered by authors via component dialog). Since we don’t have a direct way to access JCR properties from Angular 2 component that’s why we are setting it as HTML attributes so that we can read it in our component’s TypeScript code
- At line # 29 (Image 2), we have define a TypeScript function “getProperty()” that is responsible for reading 2 HTML attributes “goBtnLabel” and “localtionLabel” that we have defined at line # 8 (Image 3) and assigned it to Angular 2 component variables defined at line # 16 and 17 (Image 2) respectively. This is a hack to pass authored properties from JCR/properties to Angular 2 component but, so far it has worked perfectly fine for me
- Once “goBtnLabel” and “localtionLabel” varibale in TypeScript code is populated/binded we can use these variables in Angular 2 templates as shown below line# 6 and 16 (Image 4)
- In our Angular 2 component’s TypeScript code (line# 38, Image 2) we have defined a search() function that uses Angular 2’s “Http” service to call a REST API hosted by https://freegeoip.net. To call this REST API we read IP address entered by user in input field defined in location.html (line 4, Image 4). This input field is binded with an Angular 2 model variable defined in TypeScript file (line # 15, Image 2)
So in this post we have seen:
- How integrate Angular 2 code with AEM component
- How to load Sightly template (in EDIT mode) v/s render actual Angular 2 component (in PREVIEW mode)
- How to pass authored values from Sightly to Angular 2 template and bind it with Angular 2 model
- How to use Angular 2 services from AEM component
- Build process of an AEM application that users Angular 2 is different as compared to regular maven build (Part 2)
I hope this 3 part series will help you to understand, integrate and develop AEM + Angular 2 applications. If you have any questions or suggestion please feel free to post them.
Thanks for reading!!!
Part 2:
In next part of this series we'll learn about how to write unit test for our components developed using Angular 2.
Part 4: http://suryakand-shinde.blogspot.com/2018/01/part-4-aem-with-angular-2-unit-testing.html
Reference
This sample uses REST API provided by https://freegeoip.net
Comments
It's funny, I built an Angular 4 + AEM 6.3 POC and I came up with the same approach you did regarding components :) Although the rest of the architecture differs a bit, I managed to make Angular 4 in edit and preview mode, but having some other pitfalls, let me know if you want to discuss about it.
One of the limitations of this approach is that, you are not using all capabilities that Sightly offers, since from one HTML file you are merely passing the dialog values to the Angular template, therefore it is not possible to build HTML dynamically using HTL markup for instance data-sly-list, or data-sly-use to generate the output from the server side, instead of passing the values to Angular which will be in charge of generating the final HTML, which affects performance.
Another main concern I got is the use of internationalisation i18n in the angular templates, what approach did you consider regarding this?
Thanks for sharing your thoughts and findings with the community, it is much appreciated.
Regards,
Jose.
I am facing below error , when i try to build the project.
Any help on this , pls suggest.
[ERROR] Command execution failed.
java.io.IOException: Cannot run program "C:\Program Files\nodejs\npm" CreateProcess error=193, %1 is not a valid Win32 application
Thanks,
Sajith