Angular 13: How to make a clickoutside Directive with RXjs

Going outside with clickoutside directives

Hi all, it has certainly been a while, even though the only comments I get are from bizarre spam bots. As always there is a TLDR for you down below. So lets get into it.

Have you ever been in a situation where you make a lovely custom dropdown menu for someone and you do not know how to close the dropdown when you or they click away?

Well this is where a directive comes in and we even get to use fancy Rxjs in the mix.

Directives are defined as classes that can add new behavior to the elements in the template or modify existing behavior.

First off you will need to create your directive would recommend using the Angular CLI tool on this one.

// Angular generate new service
ng g s servicename

[Pro tip]: If you are unsure where the CLI tool will place your directive you can use the extension –dry-run.

We will be using RXjs in this directive to listen to the clicking of the element outside the assigned element

TLDR here is the Directive code to handle the clicking outside directive. Be sure to declare the Directive in your module that you are using said directive.

import { DOCUMENT } from "@angular/common";
import { AfterViewInit, Directive, ElementRef, EventEmitter, Inject, OnDestroy, Output } from "@angular/core";
import { filter, fromEvent, Subscription } from "rxjs";

@Directive({
    selector: '[appClickOutside]',
})

export class ClickOutsideDirective implements AfterViewInit, OnDestroy {
    @Output() appClickOutside = new EventEmitter<void>();

    documentClickSubscription: Subscription | undefined;

    constructor(
        private element: ElementRef,
        @Inject(DOCUMENT) private document: Document,
    ) { }

    ngAfterViewInit(): void {
        // you are listening for a click anywhere on the document
        this.documentClickSubscription = fromEvent(this.document, 'click')
            .pipe(
                filter((event) => {
                    // the Rxjs filter will return when a click is not within the directive element
                    return !this.isInside(event.target as HTMLElement);
                }),
            )
            .subscribe(() => {
                // upon the case of element clicked outside the subscription will be emitted
                this.appClickOutside.emit();
            });
    }

    ngOnDestroy(): void {
        this.documentClickSubscription?.unsubscribe();
    }

    isInside(elementToCheck: HTMLElement): boolean {
        return (
            elementToCheck === this.element.nativeElement ||
            this.element.nativeElement.contains(elementToCheck)
        );
    }
}

How does this directive work?

The finer detail is that the subscription is being used to subscribe to specifically where the user is clicking on the document. The pipe contains a filter which checks if the user has clicked off the element or on the element, this is where we subscribe to said subscription to when the event has been clicked outside the element. The emitter will emit the appClickOutside emitter.

I don’t care how it works, what else must I do to get this setup in my project!

Assuring that you have created your directive and have declared it in your module next you will need to update the view. On the view of your component you will need to add the appClickOutside directive to the element that wraps around your custom dropdown menu, as you can see on line 2 I have a dropdown wrapper class to ensure that I have the area of the dropdown covered so you may need to specify the height or width depending on your layout.

If the click off is not quite working, I’d advice to take look at your styles and element wrapper.

Ya that is about it. Feel free to take a look at my working sample on github if you are facing any challenges

Working with component instances & @ng-bootstrap’s pop up modal

pop up modal

I’m gonna cut to the chase, so no story time here.

First off here is the documentation for the @ngbootrap Modal !

To install and setup first
run this command line to get access to the @ng-bootstrap/ng-bootstrap node modules.

npm i @ng-bootstrap/ng-bootstrap

Once you have installed the files make a new component for the Modal itself

You would need to import the NgbModal with the line below.


// import into modal.component.ts file
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

For this sample I am using the NgbModal. If you take a look at the documentation it has a list of APIs associated with the NgbModal and we are going to use some of the basic samples to get this up and running.

For the modal.component.html view what is nice is that you can use conditional rendering if you want to hide some of the details. or comment it out…I was having issues toggling and where to hide and show these details and I think this is the simplest way to manage with my specific demo project.

I have a working Angular 9 project that I have setup to emit a value of a userProfile component that contains the details of Name, Job and bio.

I was thinking of going through the code line by line but you’ll need to pass data to the component and through the emitter the function will emit the value to the parent component and now to create the component instance. So in the view you can see I’m using the event emitter value from the card profile component, so
this ‘(selectedProfile)= parentFunction(userProfile)” is going to help us create this component instance of the bootstrap modal in the main app component .

  parentfunction(userProfile:CardProfile) {
    const modalReff = this.modalService.open(ModalComponent, { size: 'sm' });
    const componentInstance = modalReff.componentInstance as ModalComponent;

    componentInstance.userProfile = userProfile
  }

The above is where the magic happens, upon clicking the parentFunction it’ll create a const modalReff. from there you can reference the componentInstance and should have access to the ModalComponent’s inputs and variables.

Granted its a bit of setup work but this is how one would use a component instance in a project

If you have any issues you can check out the working sample project right here

this carries examples of inputs and outputs

Angular how to make reuseable components with @Output Part 2

If you have read my first post covering @inputs then be sure to give that a quick read before continuing.

In the previous post we have covered all our inputs and you might be thinking what about @outputs, well lets make one. When you have an @output it would emit a value up to the parent component, I believe there are many ways to do this, but all I’m trying to say is that @output requires at least an emmitter. As seen in the card.profle component. (picture below).


Update the following code in the app.component.ts file:
  data = [
    {
      name: 'Jonny Doe',
      job: 'FrontEnd Gopher',
      bio: 'I am a Gopher that likes to FrontEnd Gophe',
    },
    {
      name: 'John Dear',
      job: 'Dear FrontEnd',
      bio: 'I am a Dear that likes to dearly FrontEnd',
    },
    {
      name: 'Tony Tones',
      job: 'FrontEnd Developer',
      bio: 'I am a Tony Tones,I use JavaScript, TypeScript and Angular Framework',
    },
  ];

  ngOnInit() {
    this.userProfiles = this.data;
  }

Refresh and you should have 3 loverly gophers staring at you.

In this example we will link the follow button to emit the username of the profile selected to the parent component. This exercise we will use the eventmitter to help us emit the profile name selected to the parent component.

Line 13 we have our @output named btnClick connected to our new eventEmitter of type string (for our name variable).

We use the buttonClicked() function and pass the variable name in the buttonClick(name), which we have declared in our cardprofile component and the next step is to link it on the app.component.html and you can see the emitter btnClick.

And finally to add the function in the app component

Now spin up the project and open the dev tools and click on one of the profiles.

Here we are console logging the profile username to the parent component and thats about it.


Feel free to fork my github, here is the source code.

Deploying angular cannot find js files?

Deploying Angular

Hey gents and ladies, as always there is a TLDR section for all of you. From time to time I need to deploy an angular project to my hosting site and just about everytime I try I come across the same issue.

I have a site hosted by Gator and I have access to the file manager where I can upload my Angular projects and what not.

Just about everytime I come across the following issue and at first it always baffels me.

First is create a folder on my gator file manager and give it the name of my angular project and then do a ng build which creates a dist folder and then upload the dist folder contents (mainly js files) into the folder I created on the gator file manager ( that I pay a hefty price for) then this happens.

Then I think to myself, how does one fix this issue?
Upon closer inspection you will see that the file structure is not quite right. When selecting one of the failed js files have a look at the Request URL. It appears to have skipped my Angular project file name and tries to find the files at the base of my URL as seen below when highlighting main.js.

TLDR

I came across this Stackoverflow solution , which in the command terminal the command will set the baseUrl for the distribution file to find the proper location of said files. I forget the command line so this is a personal note for me.

ng build --base-href=/ANGULARPROJECTNAME/

This will update the file structure and the results after deploying and uploading the appropriate files should look something this. Make sure your File naming convention is inline, I won’t lie this took me a few tries and yes my project is called fireCrud. I had to update my angular.json file to fix my naming convention.

Here is the stackOverflow solution that I referenced

Enjoy and happy deploying. Hope this helps

JavaScript What is hoisting?

adorable niece

Very important concept to understand, I’ll need to start with some context.

Context of Hoisting

We need to understand the life cycle of code and there are two main phases code goes through. The Creation Phase and the Execution Phase.

When does hoisting happen?

During the Creation Phase, the program will set all the global variables and if there are var variables declared they will be initialized with the value of ‘undefined’, upon the programs Execution Phase this will assign the value officially to the variable if the var is above the invoked function.

MDN definition:

The var statement declares a function-scoped or globally-scoped variable, optionally initializing it to a value.

My understanding of hoisting is:

The process of a variable(var, let, const) declaration a default value of undefined during the creation phase. Functions on the other hand upon starting up of the program are stored in memory source

https://youtube.com/watch?v=Nt-qa_LlUH0
Been through a few tuts and this guy explains it well enough for me to understand

The above tutorial also goes through other important concepts of JavaScript functions and their behavior when invoked.

How OAuth 2.0 and OpenID connect work

I was shared this video for a tech discussions and I have learned so much from this man. I wanted to add some personal notes below but its actually a fair amount to digest. Enjoy the video and get ready for the flow of knowledge coming your way.

Understanding EventEmitters [for newbies]

I was trying to figure out how to use eventEmitters, be cause I forgot and I had no clue how to use them anymore. Then I came across this amazing video that shows you how its done.

this guy knows his stuff.

If you don’t want to watch the video or don’t have access to speakers, saving data… whatever, you can just follow along with me and my ways of explaining things to help me understand myself.

So I just want to explain it the best way i can understand it…so this won’t be textbook but it’ll probably just makes sense to me..ok enough disclaimers lets go.

Firstly you want to have an eventEmitter sample you can just go and clone this fella.

git clone https://github.com/tony2tones/eventEmitter-sample.git

There, now you have a project that has some eventEmitter action going down. It’s simple and it is a console log, but it’s the foundation to where we can start to understand whats happening.

Off the bat we can see that we will have a parent and child components to work with.

<app-component></app-component>
<header-component></header-component>

Let’s Navigate to the header component.

Now import Output, EventEmitter and a message to emit.

Maybe i’m going a bit slow, but it’ll pick up quickly i promise.

Now we can use those imports with making a new EventEmitter variable. This is very exciting and for the sake of speed you also added a function that emits the message…Oh also forgot an array of menu options.

Sweet, so we have made an emitterable variable called ‘messageBus’ which will “carry” the message string and emit it world wide.(within the boundaries of your angular project)

So we head on over to our Header view(html) and add the clickHandler function.

So thats officially in our header component…the parent component still doesn’t know anything about it just yet. There is one more step… ok there isn’t but we are close.

So how to we make it available? well you put it over here.

So we linkup that emitter variable called ‘messageBus’ to a function that can be found in our parent component.

Run that, check your console click on the nav and you’ll see the console responding with your emitted message all the way from the child component.

How do I add a Fancy github ribbon, this is the fastest way I know

If you want the story version you can continue reading, if you want to solution i found then skip to the bottom of the page. 😉

I was recently updating my rock paper scissors game to work on mobile sized screens.

The mobile screen adjustments took me some time, because I learned only after i finishing my css, making all my styles for desktop use only. I found out that most people will browse this link via their mobile phones and so my beta was a disaster in mobile views… but i digress.

Anthony Marques 2019

Aaaand when I was done, I was very proud of the results. I even figured lets make this public, so i shared my work of art on Reddit waiting for the likes to come rolling in.

BUT i got flagged for showing off by the mods…which they were more or less correct. I wanted to show the world what i have done, but then they insisted of the following rules:

Only one thing came into mind, i need to add a fork me on github ribbon, it sounded like a sure fire way for my rps game to be accepted by the JavaScript sub. I needed to know how to do this.

Then i came across this little site. This was basically the answer to what I was looking for. I did try to find other ways of implementing it, but i needed a quick solution

<a href="">
<img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub">
</a>

Just update that href with your github site and you are good to go, enjoy forking and sharing.

Here is the end result!

rps game mobile view

Here is a link to the ROCK PAPER SCISSORS game i made your avator which is me takes on real damage. feel free to take a looky

Ng Serve: solution keeps on re-compiling

Quick post here, i’ve come across this a couple of times when starting a new project normally. Where no changes have been made or saved, but the console keeps on compiling every now and again..it kinda looks something like this.

i’m sure we have all seen this before.

What worked for me was just doing the following:

ng update @angular/cli @angular/core

This has helped me out, if you don’t come alright just keep looking.

Angular Toast Notifications, quick! (for newbies)

Alright alright, it has been a long time. Now it’s time to take you through how to add a toast notification and fast.

The quickest and easiest way I could find was using this lil npm package from ngx-toastr is what you need for a quick and simple implementation.

Following the guide and going through the steps its pretty straight forward, but if you are having any troubles like i have…on that one time, i’m happy to share my findings.

Step one:

npm install ngx-toastr --save
// and if you already have it installed
npm install @angular/animations --save

Cool so let that little console run. Once installed be sure to add the imports to your app module like so

Add them imports to your app.module.ts

As you can see I have added something a little extra to the ToastrModule.forRoot({}), in those brackets you can do a number of tricks, adjust positioning animation and the works here are some details

and there are a number of options more

Now you need to add the stylings so the app knows how to make your toastie look good, check out your styles.css the main one ya’ll know what i’m talking about. You have a number of styling imports. This is where you need to be a tiny bit careful and note what style libraries you are using is it Bootstrap? Angular material? is it something else? Luckily we can do an import for whatever your style framework that you have implemented.

// regular style toast 
@import '~ngx-toastr/toastr';
 
// bootstrap style toast 
// or import a bootstrap 4 alert styled design (SASS ONLY) 
// should be after your bootstrap imports, it uses bs4 variables, mixins, functions 
@import '~ngx-toastr/toastr-bs4-alert';
 
// if you'd like to use it without importing all of bootstrap it requires 
@import '~bootstrap/scss/functions';
@import '~bootstrap/scss/variables';
@import '~bootstrap/scss/mixins';
@import '~ngx-toastr/toastr-bs4-alert';

So the problem i was facing was that i have implemented the toast notifications and all but they were not displaying. Turns out i was not using the correct toastr import styles. So lil lesson for me be sure to take note on what styling framework/libraries you are using. I used the regular toast implementation.

For my implementation of the toast notifications i wanted to add it as a service/shared component so it can be reused throughout the app..well “web-app” I am making, it looks a lil something like this (toast-message.service.ts).

import { Injectable } from '@angular/core';
import { ToastrService } from "ngx-toastr";

@Injectable({
  providedIn: 'root'
})
export class ToastMessageService {
  constructor(private toastr: ToastrService) { }
    showSuccess(text: string, title: string) {
        this.toastr.success(text, title);
    }
    showFail(text: string, title: string) {
      this.toastr.error(text, title);
  }
}

this way i’m able to inject this service into the constructor and utilise my toastie notifications for both success and error scenarios also having the freedom of adding my own text for the success/failure situation.


import { ToastMessageService } from "../../services/toast-message.service";
export class SomeCoolComponent implements OnInit {
  constructor(private toastr: ToastMessageService) {}

ngOnInit() {
this.toastr.showSuccess(
           // Body content of toastie
           "Has been successfully created.",
           // Header of toastie
            "A Toast notification"
          );
this.toastr.showError(
           // Body content of toastie
           "Has been successfully created an error.",
           // Header of toastie
            "A Toast notification for the masses and friends"
          );
}
}

I think that that about does it. This should be quick and simple, my project is running Angular 7. Lemme know if you come across any issues.