Integrate Angular with jQuery legacy app

Ryan Hoffnan
5 min readDec 18, 2018

--

jQuery is still a major part of web development, currently, there are around 800k active websites using it in some manner (link). Even though early developers stray away from learning it, in a lot of jobs and projects there may be a requirement to have some sort of knowledge regarding jQuery and how to use it.
In the blooming era of web development, Angular introduced us to a growing trend, web-components, in which it will be easy and simple to add Angular projects to an existing non-Angular project, jQuery project or even other client-side frameworks projects, a sort of plug and play functionality if you will. unfortunately, this is a true statement, majorly when using it as a stand-alone web-app with very low integration to the existing client functionality. In this article, I will try and show the way I learned to implement and integrate Angular elements in a more advanced way. we will start from the very beginning.

Creating An Angular Html Element

Assuming you have Angular CLI installed on your machine we will start with adding a new project. (please make sure you have the latest version)

ng new elements-injectioncd elements-injectionng add @angular/elements --project=elements-injection

When opening the project in any IDE you will see the app.module.ts file, which is the basis of the Angular app. To implement Angular Elements you will need to tweak it a bit, it should look something like this

EntryComponent tells Angular what component the custom element is going to bootstrap as the main app component (note: if you’re going to use a UI library like material-angular, specifically dialogs, you will need to add them to the entryComponent array).
The second part is the AppModule class in which we tweaked to define the tag element which we will be using, as shown in the gist above.

In your package.json of the project, I can highly recommend adding the command listed below to build the project for production (see code block below).
When using projects in Angular you must tell the CLI which project to build (aka elements-injection).

"build:prod": "ng build elements-injection --prod --aot --output-hashing none"

After running the build we will find a folder name “dist” and inside it, a folder named “elements-injection”, open it, inside you will find the files Angular compiled for production. After compiling create a new HTML file and add the scripts and link tags accordingly (look at the image below). First, there is the script tag which is related to Angular Elements, it fixes an issue that the Angular team is informed about and fixed but still has not been merged. Then there are the other Angular script files and finally, we add a stylesheet link in the head tag. (Some other tutorials will show you that the Angular complied js files can concat into one, that is true and also recommended.

If we run the HTML page we will the Angular’s basic “hello-world” demo inside, all thanks to the magic of elements.

Injecting data into the element

In the image above we added a script tag which grabs the custom element and adds an attribute to HTML element (which is an object… ).
Angular catches this injection as an onChange event, so we can grab it and play with the data inside the component.ts file, as seen in the images below. Rebuild the Angular app and refresh the page and you will see “hello King Author welcome to elements injection”, success!
In the second image below, we can see that we can pass also objects in a very simple and same way. this can be done with almost any data type.

Injecting from Angular into legacy code

In the image above we see we created a button element with the class “btnClicked”, we added a data attribute as well. Using “[attr.data-name] “ tells the Angular compiler to keep the attribute data-name as is, which is crucial.
Inside our HTML page. We have added a jQuery CDN (sorry for being lazy) and added an event listener of type click on the class “btnClicked”. Now we wait…
when the button with class btnClicked is clicked even though the element is in the Angular app it is caught by the jQuery listener inside the index.html, we can then get an attribute on it using jQuery’s attr() function. we have just successfully injected data from Angular into jQuery. success!

There is one major downside and complexity issue regarding this subject, only string elements can be passed, while it can be done, it can become a bit complicated on some use cases, for example when dealing with HTML codes (when using any WYSIWYG HTML editor for example).

Conclusion: Dirty but it works

This is a dirty fix, but then again, this is how ideas and best practices are made, using a bleeding edge technology with an old-school legacy has its issues but it also has its benefits and an added value.
I find this an easy way to try and remodel any legacy code step by step.

Why web-components? — not a part of the article, but still nice to read

We have this growing concept, micro-services. It has been shouted from every rooftop, and yet not many companies have been ready or willing to change their existing monolithic architecture (yes yes Netflix did it, sorry, not all of have their amount of money to spend. With adding web components (Angular elements in this example) we can rebuild the architecture little by little, part by part. making every part of the app separate and yet completely connected, keep the same API, keep the listeners, keep the logic, just change the build format.
The major downfall of working with this idea in mind is bundle sizes, even though we were introduced to Angular tree shaking abilities, and its new build engine, the bundle sizes will be larger than your used to, this downfall should be fixed in the next Angular major release, crossing my fingers.

GOOD LUCK!

--

--

Ryan Hoffnan
Ryan Hoffnan

Written by Ryan Hoffnan

Full stack developer - Frontend oriented

No responses yet