I'm Matt - You're here for my blog!

Category: Development

Standalone Components in Angular 15

Up next in the Funemployment series, I’m taking a look at Standalone Components – specifically, Standalone Components in Angular 15.

Since I follow the official Angular Twitter account, I recently saw a link to this tutorial shared and so I figured it would be a good place to start: https://codelabs.developers.google.com/angular-standalone-components

Standalone Components and Chatbots?! Perfect!

One of the first things one might notice is that the tutorial targets Angular 14 – but since I’m really wanting to get a jump on Angular 15, I figured I’d forge ahead and try to tackle whatever issues may arise as they arise.

My environment

Since the tutorial largely just works in Angular 15, I’m not going to reproduce it step-by-step here – instead, I’m just going to highlight some of the issues I encountered when following along verbatim.

tl;dr:
1) environments/environment is no longer generated by default: https://github.com/angular/angular-cli/commit/283b564d1de985f0af8c2fcb6192801a90baacda

2) ngOnInit and default constructor no longer generated by default: https://github.com/angular/angular-cli/commit/301b5669a724261d53444d5172334966903078c0

So, yeah… The tutorial mostly just translates to Angular 15, and most experienced Angular developers will be able to quickly workaround any issues that may arise from working through this Angular 14 tutorial in Angular 15… But if you’re curious about my journey, please feel free to continue on…

Hiccup #1 – in the ‘Create a new application’ section of the tutorial, we’re shown how to strip down our application in order to remove the ngModule (basically a cornerstone of ‘standalone components’) – and as part of those instructions, we’re shown how to enable production mode by leveraging the long familiar ./environments/environment.ts file… Okay… But I’m getting an error indicating this long standing file isn’t present in my project… odd… that fella is always hanging out there…

Can’t reference what doesn’t exist…

Since I can’t ever seem to just do what I set out to do, I must now satisfy my curiosity concerning why this file, which was previously generated as part of the new project, no longer exists… After a bit of poking around in the Angular CLI github repo, I see the following: https://github.com/angular/angular-cli/commit/283b564d1de985f0af8c2fcb6192801a90baacda

feat(@schematics/angular): remove environment files in new applications

This commit removes the usage of environment files and `fileReplacements` in new application projects. Previously, the environment files was used to distinguish between a prod build to invoke `enableProdMode`. The `enableProdMode` however needed only for the case of JIT mode in production mode, which is a rare case as JIT mode is recommanded to be used in production.

In the CLI, calling `enableProdMode` is not needed as `ngDevMode` it's set using the minifier.

Whelp… That settles that… Moving on…

Since we no longer have this environment.ts file out of the box with new apps, it seems logical to assume we can skip some steps – basically, we just need to ensure we bootstrap our now-standalone AppComponent.

main.ts for Angular 15 Standalone Component

Skipping ahead to the next section, “Display the photos”, things seem straight forward enough… It’s worth noting that there seems to be a bit of a typo in the HTML, as the closing ‘article’ tag isn’t properly formed – no worries, as we just need to add an ‘>’ to make it valid.

Screenshot of tutorial showing ‘</article’ rather than ‘</article>’

Upon saving and running our updated project, we will see that while things are technically working, they aren’t working great because we’re missing some assets – namely, the images…

Hmm.. That doesn’t look very nice…

This makes sense, as image assets aren’t going to be generated by ‘ng new’ and are merely artifacts for this demo project… For simplicity, I’m just going to download these assets from the github project for this demo app: https://github.com/angular/codelabs/tree/standalone-components/src/assets

This looks better…

Continuing on to ‘Add a new standalone component’, everything in the original tutorial translates perfectly to Angular 15 and we can see our lazy loaded component as expected when we click the ‘Find out more about these guys!’ button as instructed:

Kewwwwl…

Another small note to make… Once you get to the ‘Add event handling to the form‘ section, step 4 of the ‘Add the send message form model to the component’ subsection instructs us to remove the default constructor:

Whelp… We don’t have a constructor in our newly created Angular 15 standalone component… Not particularly important, as it was empty and not really doing anything – but why doesn’t it exist?! MY ADHD WILL NOT ALLOW ME TO CONTINUE ON WITH WHAT I SET OUT TO DO UNTIL I KNOW… After a bit more poking around the Angular CLI repo, I see the following indicating that ngOnInit and the default constructor have been removed in Angular 15, as apparently users of these features generally prefer to simply add them manually: https://github.com/angular/angular-cli/commit/301b5669a724261d53444d5172334966903078c0

Moving on…

Reactive form up and running…

The next section, ‘Add a chat dialog’, just works. Unrelated note: I really liked this section… Having never played with a virtual agent / chat system, I learned something new, which is always fun! And that’s pretty much it – standalone components in Angular 15…

NEAT-O!

At this point, I’m going to stick a fork in this write up and consider it done. The remainder of the Angular Standalone Component tutorial details deploying the project to Google App Engine with Express.js – which I feel is a bit out of scope for this write up, which was to detail the hang ups I encountered working through this Angular 14 tutorial in Angular 15 (which were very minimal – YAY!).

Happy coding!
-Matt

Exploring Denoland – Home of the Deno JavaScript Runtime

With some of my newly found ‘free time’ while Funemployed, I really wanted to start playing around with some of the newer projects that I’ve simply not had the time or energy for.

At the top of this list has been Deno, the new-ish JavaScript, TypeScript and WebAssembly runtime based on V8, co-created by Ryan Dahl (Node.js creator).

Why Deno? Well, for starters I love new and shiny things. But also, I have a special place in my heart for JavaScript runtimes – having been an early adopter of Node.js, at a time when serverside JavaScript was a controversial topic in the dev world (Thanks, Whiteboard IT! It’s because of my time with this company that I was exposed to a lot of really cool things, including Node.js and CouchDB/NoSQL). “How early?”, one might ask… Early enough that I’m listed as contributor #306 in the Node.js AUTHORS file – as a result of contributing a slash to the first official Windows installer.

I began my journey with Deno as I normally do – essentially iterating on some basic Hello World types of projects to get familiar with the dev flow, tooling and capabilities. Pretty quickly, I encountered something in my codebase that confused me – a warning notifying me that the deno window typings didn’t have everything supported by window exposed. Surprisingly, it wasn’t just me randomly plugging in code that landed me here – it was in following along with the Deno lifecycle docs that brought me to this error.

“Element implicitly has an ‘any’ type because type ‘typeof globalThis’ has no index signature.deno-ts(7017)”

At this point in my journey, not only was I getting the warning in VSCode, but I was also unable to get beforeunload or onbeforeunload to fire… Hmm… So off to Google I go – which lead me to this thread discussing a related matter.

In digging a bit deeper, I came to realize that beforeunload/onbeforeunload weren’t firing due to my Deno version – with support for these not being added to window in Deno until v1.24.0 (and me currently running v1.23.0). “Alright”, I thought – “I just need to upgrade and this will all be solved.”

Sure enough, once on 1.24.0 I was able to play with beforeunload/onbeforeunload – but the “Element implicitly has an ‘any’ type because type ‘typeof globalThis’ has no index signature.deno-ts(7017)” warning remained…

Having wished I had more time to contribute to open source over the last several years, I saw this as an opportunity to make my wish a reality – and so I did what any developer would do, created a fork and started to work on a new branch in the hopes I could become a Deno contributor!

As most experienced devs know, stepping into a large and complex codebase isn’t always the easiest thing to do – especially if you’ve never worked with some of the core tooling. With this being my first real exposure to Rust, I was completely unfamiliar with Cargo and how to go about building and testing my changes in an efficient manner… Fortunately, after a handful of web searches, I learned the basics of working in Rust and with Cargo, how to run specific tests by name, and I was off to the races to become a real life Deno contributor.

My commit is simple enough – really just a few lines to add beforeunload and onbeforeunload to the type definition for Deno window, and some updated integration tests to ensure everything is working as expected – you can see the pull request / merge here. While a small contribution by pretty much all standards of measurement, it felt good to see an issue, fix the issue and contribute that fix back to the community – and I hope to be doing more of this in the near future.

So, what’s next? Well, I guess I can actually begin with what I set out to do – learn Deno (rather than Deno’s codebase) and start playing with Fresh! 😁

Happy Coding!
-Matt

Bootstrap 5 – Using components without jQuery in Angular

I recently found myself on yet another Angular + Bootstrap project. Usually, when spinning up a new Angular Bootstrap project, this means npm installing a library like @ng-bootstrap, but this time we wanted to keep things as vanilla as possible.

“How to use Bootstrap in an Angular application without jQuery?”

Bootstrap

Since we’re in Angular, and since it’s generally considered a bad idea to use jQuery in an Angular project (though it is most certainly possible), we were forced to think about how to best use Bootstrap “from scratch”.

Up first – get a major pre-req out of the way… It’s been a while, so I guess I should ensure I’m on latest LTS😲

Install Node and NPM

For this project, we’re also going with the latest and greatest from Angular, so…

Ensuring the global @angular/cli is up to date – using v14 here…

Now lets get a clean Angular workspace spun up…

> ng new bootstrap-5-demo

For simplicity, we will start slow – simply displaying a Modal from the AppComponent in the presentation of a Confirmation Dialog.

I’m opting to go with a Modal because it’s a frequently desired component of Bootstrap, and I believe that it allows us to demonstrate a number of angles with regards to using a Bootstrap Modal ‘natively’ from Angular (without jQuery).

Normally, I’d opt to go with self-hosting for my libraries, but since this crash course is more focused on how to use Bootstrap natively in an Angular application rather than productionizing the solution, I’m just going to use a CDN from the Bootstrap getting started docs to get things wired up.

Setting up Bootstrap and the Popper dependency in index.html

To make things a bit easier on ourselves, we’re also going to install the Bootstrap types package from the Definitely Typed project as a developer dependency in our project.

npm install @types/bootstrap --save-dev

Now that we have the basics set up, let’s start in our AppComponent by importing Modal from bootstrap (via the @types/bootstrap package installed in the previous step):

Importing Modal with help from the @types library

To get our Modal setup, we’re going to utilize the AfterViewInit lifecycle hook to wire up our event listeners so that we can respond to our Modal instance:

Getting AfterViewInit in place

As a sanity check, let’s go ahead and wire up the Modal as simply as we can – triggering the modal show with a button click:

Basic Modal scaffolding and a button passing in the HTMLElement via the ‘confirmationDialog’ template variable to the openModal method.
Basic openModal implementation – instantiating a new Modal and assigning it to our private ‘confirmDialog’ property.

As you can see in the above code, we’re able to simply create a Modal instance in TypeScript-land thanks to our @types/bootstrap library -then we can simply call ‘show()’ to open our new Modal:

WOW! SUCH MODAL!

Okay. That’s all well and good, but unless we’re just wanting to show some static message, this Modal is pretty lackluster.

Let’s go back to our AfterViewInit lifecycle and set some things up… But what exactly? Perhaps we should go take a quick, cursory glance at the Modal docs

Modal Events

Alright… So we’ve got a handful of events we can respond to… For the purposes of this example, we’re going to focus in on ‘hide’ and ‘show’.

In addition to wiring up event listeners for ‘show’ and ‘hide’, we’re also going to change our implementation a little bit – rather than passing in the element from our template, we’re going to access the element via the @ViewChild property decorator. And lastly, we will log our events to the console:

Getting Modal from template via @ViewChild decorator rather than passing in to click handler

Some points to note in the above code… We’ve introduced the Angular property decorator @ViewChild(…) – this has enabled us to stop passing in the element from the template via the template variable as we were originally doing. We’ve also added some code to our ngAfterViewInit lifecycle method, which is responsible for listening to the ‘show’ and ‘hide’ events – simply logging the ‘type’ property associated with the Event via the processDialogEvent() method.

Let’s check it out:

WOW! SUCH MODAL!…still…

Whelp… Still pretty lackluster… One could be forgiven for mistakenly concluding we’re just showing the same demo as earlier – but we know they’d be wrong because this is a completely different monster altogether (since we’re using ViewChild and listening to/logging events now)!

Alright… Let’s get this thing done… Right now, we just have a message modal – but we need a confirmation dialog… So we will spruce things up a bit with some formatting/structure and we will add a couple of user prompts – something for them to confirm (or not).

Hamming up the Modal a bit

And here’s how it looks in action:

New Modal look

Now it’s starting to look more like a proper confirmation dialog!

Something I’d like to point out at this point in the process. Remember our event listeners? Perhaps you noticed we added a new ‘X’ close button element, and that this element has an interesting ‘data-bs-dismiss’ now present. Bootstrap supports interaction via data attributes, and this attribute demonstrates how to close this modal instance using one such data attribute – read more here in the docs. Oh, yeah – and the event listeners? Still listening – even when we’re closing via the data attribute:

Still listening for events from the Modal even through we’re explicitly handling clicks

But we still need to do something about those button clicks… And as cool as being able to close the modal via the data attribute is, we don’t really know if the close was by clicking outside of the dialog or if it was intentional via the ‘X’ – and I’d think the ‘X’ could commonly be interpreted as “No”, as where closing via clicking outside of the dialog could be “I’m declining to answer right now”, and that perhaps we want to handle those two interactions differently.

First up, let’s add a new method to assess if the user likes to rock or not – ‘userRocks’:

Getting user response

Next, let’s wire this up on the template to the ‘X’ close button and the other choice buttons – passing ‘true’ when they do and ‘false’ when they don’t (I have a feeling those ‘false’ ones rarely get used, and only by people you probably wouldn’t enjoy writing apps for):

Wire up user actionable controls so that the application can react

And let’s see it in action:

Updated view of Modal

Cool-cool-cool. Looking more and more like a proper Confirm Dialog by the minute! But we have a bit of an issue… We know if the user rocks or not – but most users would expect the dialog to do something other than log to the console, which they wouldn’t even be aware of unless they’re a super 1337 hacker looking at the console while trying to find their exploit.

Let’s start simply by having the modal hide after the user has provided an answer… Easy enough – let’s just modify our userRocks method to call ‘hide()’ on our Modal instance:

Closing the modal after user input

Now we’re cooking! Let’s put this baby to bed! At this point in time, we have a functional confirmation dialog that allows the user to let us know if they like to rock or not – all that’s left is to do something based on the user’s willingness to rock.

For the sake of brevity (🤣🤣🤣 Never been a strong suit of mine), we’re just going to introduce a few lines of code to our userRocks method and some supporting code to our AppComponent implementation. Namely, we’re going to add another Modal (why not?! This is a Modal example, afterall!) as well as another ViewChild that makes accessing an element within the Modal a bit easier so that we can mess with it in our userRocks() method based on the user’s input.

Here’s our updated component TS:

The whole shebang!

And here’s our updated template:

The rest…of the whole…shebang…

And here’s how it looks running:

A done-ish Modal

We like to rock:

Rocking out…

We have sensitive ears and “refined” musical tastes:

Not rocking out…

There you have it – how to use Bootstrap 5 from Angular 14 ‘natively’.

While we really only covered the Modal here, many/most of the approach we’ve reviewed here translates to other Bootstrap Components.

I hope that you’ve found this helpful and perhaps even a little entertaining. If you would like to check out the full source for this project, feel free to check out the project here: https://github.com/mattezell/bootstrap-5-demo

Tootles!
-Matt

The Magical Power of NestJS

Today I wanted to make a quick post about a framework/toolset that I’ve become increasingly fond of – NestJS. For those not in the know, NestJS enables developers to write Express APIs (and more) in a very Angular-ish way, including coding in TypeScript.

NestJS - A progressive Node.js web framework

My adventures into NestJS began, as one could logically assume, with a need for a new API. Having been deeply submerged in Angular-land for several years now, NestJS looked like it was at least worth a peek – and after a peek, we decided it was a perfect fit and so we adopted it.

High-level, we needed an API to essentially wrap some node, npm and Angular CLI processes so that they could be interfaced with by clients via REST. All in all, the API writing process was very straight forward – a controller exposing our business concepts, which performed various node, npm, and Angular CLI operations via dedicated service implementations.

All in all, the writing experience was very pleasant with NestJS – but as often happens with enterprise projects, the target appeared to be moving pretty late in the game as requirements imposed by external players changed.

“Okay. Great. So now we have this REST API, but we’ve since decided that a CLI would be a better fit. Oh, and we needed it yesterday…”


If you’ve ever been a developer in a large organization, you know this sort of thing happens far more often than you’d generally prefer – but it’s life. Things change – lots of moving parts, lots of cooks in the kitchen, etc.

Behind schedule and over budget due to things that were outside of my control, I found myself considering a frantic rewrite of the API. Logically, my mind quickly moved to ‘how much of the API codebase can we leverage in our CLI’, as I opened up the NestJS docs in the hopes that I’d find my magical answer.

After a bit of hunting, I found ‘Application Context’: https://docs.nestjs.com/application-context

From the NestJS docs:

There are several ways of mounting the Nest application. You can create either a web app, microservice or just a Nest application context. Nest context is a wrapper around the Nest container, which holds all instantiated classes. We can grab an existing instance from within any imported module directly using application object. Hence, you can take advantage of the Nest framework everywhere, including CRON jobs and even build a CLI on top of it.

Perfect – this sounds to be just what the doctor ordered.

Having played with NestJS quite a bit, and being familiar with the transpilation process, I knew I’d essentially get a one-to-one output of my TS implementations in JS. Not wanting to change my API in a way that detracted from using the codebase as a REST API, I instead opted to add another entry point – adding ‘main.cli.ts’ alongside of the NestJS generated main.ts, in which I added my CLI specific logic.

Fortunately, having coded my API with abstractions / separation of concerns the best that I knew how, I had domain specific implementations wrapped in services rather than directly in controllers – this made my CLI experiment a dream rather than a nightmare. With just a few lines of new code in my main.cli, I was able to invoke my service logic from the command line – passing arguments at the CLI rather than properties in a POST body.

> node dist\main.cli.js --id 1

BOOM! DONE!

I honestly found myself blown away by the simplicity of this undertaking. Anxiously considering more or less a full rewrite initially, I found myself empowered by NestJS to fundamentally change my program, additively, in a matter of minutes – rather than the hours or days it would have required to do a full rewrite. With a dozen-or-so lines of new code, I now not only have a fully functional REST API, but I also have a CLI capable of doing the same things as the API.

Image result for magic gif


If you’ve not used NestJS before, I definitely recommend that you give it a look before you write your next API (or CLI)!
https://nestjs.com/
https://twitter.com/nestframework

-Matt


Playing with Docker on Windows 10 with Live Reload (nodemon)

Image result for what year is it

I know. I know. I’m a bit late to the game – and this was long overdue…

For a few years now, I’ve been fully submerged in the world of Enterprise Angular development – which has unfortunately led to me falling behind on some technologies, such as Docker. While I’ve been aware of LXCs for many, many years now, I’d not gotten past 101 setup tutorials for Docker to date – which changes today.

This post details my initial journey with running my first Docker container based Node.js application under Windows 10 – as well as the challenges encountered with live reload via nodemon during the journey, and how I got everything working well enough in the end.

As is often the case, I went looking for a recent basic getting started writeup, which led me to Dinushanka Ramawickrama’s “Let’s Dockerize a Nodejs Express API“. Being a huge fan of Node.js, often choosing it as my stack of preference, this seemed like a great place to start – taking a Node Express API and shoving it into a container using Docker.

All in all, I have to say that Dinushanka’s write up is pretty good – short, to the point, easy to follow, and accurate. It wasn’t until getting the last section, titled “Dynamically Change the Contents of the Running Container using Nodemon.”, that I ran into problems – for the life of me, I could not get live reload via nodemon to work as expected. Docker would output log messages seemingly indicating that all was well, but when I’d make changes to my server they weren’t syncing in my Docker container.

nodemon reporting for duty – but the duty never shows

As I often do in situations like this, I turned to the comments – assuming that someone else had already experienced my pain and provided me a nicely packaged solution. Nope – not this time. So I went searching, which led me to a relatively recent issue on nodemon’s github repo:
https://github.com/remy/nodemon/issues/1447 . As suggested by a commenter, I checked out “Application isn’t restarting” in the nodemon readme –
https://github.com/remy/nodemon#application-isnt-restarting . Going for the low hanging fruit approach, I updated my package.json’s dev script to include the Legacy Watch flag:


Now, all that was left was to rebuild my image and rerun it:

> docker-compose down
> docker-compose build
> docker-compose up

With the above in place, all was well in the world – containerized live reloading node development. AIN’T LIFE GRAND?!

Long story short, essentially the mechanisms leveraged on Linux systems to detect filesystem changes aren’t available in Windows – and so live reload doesn’t work out of the box. Fortunately, nodemon’s Legacy Watch uses a different (though more costly) polling mechanism to detect changes – which works fine for our purposes of ‘getting started’. Note: this is actually a known issue, as you can see in the Docker official docs:
https://docs.docker.com/docker-for-windows/troubleshoot/#inotify-on-shared-drives-does-not-work

It’s worth mentioning that some folks have reported this issue when developing on host Linux systems, which is believed to be related to inotify-tools not being present in the OS image used to create your container. In these cases, your nodemon woes may be solved by simply updating your Dockerfile with an additional run statement to install the package using the container OS’ package manager. See here:
https://stackoverflow.com/questions/42445288/enabling-webpack-hot-reload-in-a-docker-application/46804953#46804953

-Matt

Installing Node.js in the Ubuntu Windows Linux Subsystem

Installing Node.js in the Windows Linux Subsystem (WLS) is quick and easy – accomplished by essentially running 2 commands. By reading the official Node.js docs, we can see that Ubuntu installs are provided via NodeSource. Once at NodeSource, we see the commands required for Debian based Linux systems, such as Ubuntu (as of the time of this writing, I am running the Ubuntu 18.04.01 LTS subsystem).

First, we need to pull down the installer script and execute it using a 1-liner:

curl -sL https://deb.nodesource.com/setup_11.x | sudo -E bash -

A bit about the command that we just ran. As you’re likely already aware, curl is a command line utility for interfacing with various protocols – in this case, http(s). If so inclined, you can take a look at the contents of the “setup_11.x” bash script. So, as you know, we’re working with a bash script – which we’re pulling down with the assistance of curl, but rather than saving it to our local filesystem, we’re piping it’s contents to bash, which we’re elevating using sudo. As you may have noticed, we’re actually calling “sudo -E”, which instructs sudo to preserve environmental variables while executing. So we call “bash -” as administrator, that training dash instructing bash “take the input from the pipe and treat the contents of a bash script”. By inspecting the output, or better yet from reading the bash script, we can see that we’re essentially modifying our apt sources to allow us to ‘apt install’ Node.js using the NodeSource repo. Easy peasy.

sudo apt-get install -y nodejs

With our apt sources updated to include the NodeSource repo, we use “apt-get install” to install nodejs – just as we would any apt package. Just as is the case with other apt installed packages, apt will evaluate all required dependencies for Node.js and install them on your system as needed before installing the Node.js binary.

Once installation has completed, you should be able to execute “node -v” and “npm -v” to see your installed versions.

We now have a fully functional Node.js environment in our Windows Linux Subsystem!

© 2022 blog.immatt

Theme by Anders NorenUp ↑