How To Add In-App Notifications To Your Angular App
Tags: angular, webdev, tutorial, javascript
Published: 2023-05-02 08:50:55

### TL;DR

This article explains how to add an in-app notification center to your Angular app and gives you a few reasons to smile 🙃

> In one of the screenshots, there's a reference to one of my all-time favorite movies. If you can correctly guess which movie it is and leave your answer in the comments section, I'll make sure to acknowledge you in some way in my upcoming article. 🤓



![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5u60jitf4gf3i2yd0lfv.jpeg)

Now that you're happy, we can start the tutorial.

Many notifications that may be convenient or necessary for your use case are available.

Here are some notification (communication) channels you are probably familiar with:

- In-App
- SMS
- Emails
- Chat (Discord, Slack, MS Teams, WhatsApp, Telegram)
- Push

However, we will eat only 1/5 of this delicious pie - In-App notification. This communication channel allows you to interact with your users within your application.

Assuming you've not been living under a rock for the past decade, let's observe an example of an In-App event-based notification workflow for a social media app like Instagram:


![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1gcowxcdjvy4y2o52nvq.png)

1. User opens the Instagram app and scrolls through their feed, looking at photos and videos posted by other users.
2. The user posts a photo or video to their own Instagram profile.
3. Another user sees the post and likes it.
4. The Instagram app detects the like event and triggers a notification to the user who posted the content.
5. The notification appears on the user's screen, notifying them that another user has liked their post.
6. The user can either dismiss the notification or tap on it to open the app and view the user who liked their post.
7. If the user taps on the notification and opens the app, they can see the profile of the user who liked their post and engages with them by liking their posts or following their account.


![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/79ytd5incifan9vp4d8p.jpeg)

Now that we know what we're doing let's integrate In-App notifications into our app.

Well…It’s not a chicken and egg type of question; we need to have our chicken first - our app.

I recently started experimenting with Angular and have grown quite fond of this framework, but I will not be trying to convince you to join to the dark side. 

Feel free to visit the deployed version: [https://in-app-notification-with-angular.vercel.app/](https://in-app-notification-with-angular.vercel.app/)

Or clone this [repo](https://github.com/iampearceman/in-app-notification-with-angular)

That’s what it should look like:

![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il4cla8hp41f36j77fcr.png)

## Create an Angular app

Prerequisites: (The things you need to ensure you have not lost your hair)

Before we start, make sure you have the following installed on your system:

- Node.js
- NPM (Node Package Manager)
- Angular CLI (Command Line Interface)
- Angular version > 0.15.0

If you still need to install these tools, you can download and install them from their official websites.

### Step 1: Creating a new Angular app

To create a new Angular app, open a terminal or command prompt and run the following command:

```
ng new my-app
```

Here, `my-app` is the name of your new Angular app. This command will create a new Angular app with a basic file structure and all the necessary dependencies installed.

### Step 2: Starting the development server

Navigate to the app directory by running the following command:

```
cd my-app
```

Once you are in the app directory, you can start the development server by running the following command:

```
ng serve
```

This command will start the development server and launch your app in the default browser. You can access your app by navigating to `http://localhost:4200/`.


![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/go9ch8vqvatmroiiz8c5.png)

### Step 3: Modifying the app

Now that your app is up and running, you can start modifying it to fit your requirements. You can modify the app by editing the files located in the `src` directory.

- `index.html`: This file is the main entry point of your app.
- `app.component.ts`: This file contains the main component of your app.
- `app.component.html`: This file contains the HTML template for your app component.
- `app.component.css`: This file contains the CSS styles for your app component.
- `app.component.spec.ts`: This file contains unit tests for the App root.

You can modify these files to add new components, change the layout, and add tests or new functionality to your app.

## Signing up for Novu

We will use an out-of-the-box solution for our notifications because we are lazy and constantly looking for shortcuts in life

(those millennials….)

If you tried to build a notification system by yourself in the past, before reading this, you will love me in a few moments.

We will be using Novu, as it’s an open-source notification infrastructure that enables us to trigger an event-based notification workflow.

### Step 1:  Sign Up

Click this [link](https://web.novu.co/auth/signup)


![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rie4g2dmnx571h3eizom.png)

### Step 2:  Creating A Workflow

You can follow the Get Started guide or head to [notification templates](https://web.novu.co/templates) and create your template (workflow)


![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s8zsk0w7j17oouuif7on.png)

## Adding a notification center

### Step 1: **Installation**

In the terminal, navigate to the root directory of your Angular application.

```
cd my-app
```

Run the following command to generate a new component:

```
npm install @novu/notification-center-angular

or

yarn add @novu/notification-center-angular
```

### Step 2: Adding Novu Module

Now, navigate to the **`app.module.ts` file (my-app/src/app/app.module.ts)**

```tsx
// my-app/src/app/app.module.ts
****
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

Import `CUSTOM_ELEMENTS_SCHEMA` from `'@angular/core'`.

```tsx
// my-app/src/app/app.module.ts

import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

Add Novu’s notification center module

```tsx
// my-app/src/app/app.module.ts

import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { NotificationCenterModule } from '@novu/notification-center-angular';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    NotificationCenterModule
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

### Step 3: Configuring Application Environments

Using the Angular CLI, start by running the [generate environments command](https://angular.io/cli/generate#environments-command)
 shown here to create the `src/environments/`
 directory and configure the project to use these files.

```
ng generate environments
```

Navigate to `my-app/src/environments/environment.ts` and add the following variables: `subscriberId`, `applicationIdentifier`

```tsx
export const environment = {
    production: false,
    subscriberId: "",
    applicationIdentifier: ""
};
```

These variables are needed for the `GET` request our notification center will make to Novu’s API to actually push notifications into the feed.

Now we need to add those variables:

 **`Application Identifier`** can be found here:[https://web.novu.co/settings](https://web.novu.co/settings) (Novu’s settings section)


![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5u4ikp45je4zyrio46v.png)

**`subscriberId`** can be found here: [https://web.novu.co/subscribers](https://web.novu.co/subscribers) (Novu’s Subscribers section)


![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uflftzxpchsb8rd1cnvu.png)

Now add it into your `my-app/src/environments/environment.ts` file

```tsx
export const environment = {
    production: true,
    subscriberId: "<REPLACE_WITH_USER_UNIQUE_IDENTIFIER>",
    applicationIdentifier: "<REPLACE_WITH_APP_ID_FROM_ADMIN_PANEL>"
};
```

and to the `my-app/src/environments/environment.development.ts` file

```tsx
export const environment = {
    production: false,
    subscriberId: "<REPLACE_WITH_USER_UNIQUE_IDENTIFIER>",
    applicationIdentifier: "<REPLACE_WITH_APP_ID_FROM_ADMIN_PANEL>"
};
```

Let’s head to `my-app/src/app/app.component.ts` file

```tsx
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'my-app';
}
```

The **`app.component.ts`** file is a critical part of an Angular application, as it defines the root component and provides the foundation for the rest of the app's functionality.

Now, we are going to import the `environment` variables to make them accessible in the `app.component.html` and the `styles` properties of our notification center (there are many properties, but you can discover them later on)

```tsx
import { Component } from '@angular/core';
import { environment } from '../environments/environment';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'my-app';

  subscriberId = environment.subscriberId;
  applicationIdentifier = environment.applicationIdentifier;

styles = {
    bellButton: {
      root: {
        svg: {
          color: 'white',
          width: '45px',
          height: '40px',
          fill: 'white',
        },
      },
      dot: {
        rect: {
          fill: 'rgb(221, 0, 49)',
          strokeWidth: '0.2',
          stroke: 'white',
          width: '3.5px',
          height: '3.5px',
        },
        left: '40%',
      },
    },
    header: {
      root: {
        backgroundColor: '',
        '&:hover': { backgroundColor: '' },
        '.some_class': { color: '' },
      },
    },
    layout: {
      root: {
        backgroundColor: '',
      },
    },
    popover: {
      arrow: {
        backgroundColor: '',
        border: '',
      },
    },
  };

  sessionLoaded = (data: unknown) => {
    console.log('loaded', { data });
  };
}
```

You might see some errors in the `[localhost:4200](http://localhost:4200)` we will fix it now!


![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v37b5j0af103qbtylfg9.png)

This occurs because the Angular component is generated as a wrapper around the original React component. This approach is clever, as it allows Novu's engineers to focus on creating and developing things in the React way. Additionally, many other frameworks can still use the created components using the wrapping approach.

We need to add `@types/react` as dev dependency for the angular component to work properly.

Open your terminal and navigate to the app root directory and type the following:

```
npm i @types/react

or

yarn add @types/react
```

Now head to the `my-app/tsconfig.json` file

```json
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "ES2022",
    "module": "ES2022",
    "useDefineForClassFields": false,
    "lib": [
      "ES2022",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}
```

And we’re going to add `"allowSyntheticDefaultImports": true` to the `compilerOptions` array.

```json
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "allowSyntheticDefaultImports": true, 
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "ES2022",
    "module": "ES2022",
    "useDefineForClassFields": false,
    "lib": [
      "ES2022",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}
```

To see the error resolved, you might need to go to the terminal that is running the app and serve the app again for `compilerOptions` changes to take effect.

### Step 4: Add the notification center component

Open the `my-app/src/app/app.component.html` file.

This file contain the CSS code along with the HTML one - ideally you should separate the CSS to the `my-app/src/app/app.component.css` file, but it’s not mandatory.

We will add our notification center to the .toolbar div. 

Paste the following into your `app.component.html` file:

```html
	<div id="bell-icon">
    <notification-center-component
      [subscriberId]="subscriberId"
      [applicationIdentifier]="applicationIdentifier"
      [sessionLoaded]="sessionLoaded"
      [styles]="styles"
    ></notification-center-component>
  </div>
```

The div should look like this:

```html
<!-- Toolbar -->
<div class="toolbar" role="banner">
  <img
    width="40"
    alt="Angular Logo"
    src="<TOO LONG FOR DEV.TO MARKDOWN TO PROCESS>"
  />
  <span>Welcome</span>
    <div class="spacer"></div>
    <div id="bell-icon">
    <notification-center-component
      [subscriberId]="subscriberId"
      [applicationIdentifier]="applicationIdentifier"
      [sessionLoaded]="sessionLoaded"
      [styles]="styles"
    ></notification-center-component>
	  </div>
    <a aria-label="Angular on twitter" target="_blank" rel="noopener" href="https://twitter.com/angular" title="Twitter">
      <svg id="twitter-logo" height="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
        <rect width="400" height="400" fill="none"/>
        <path d="<TOO LONG FOR DEV.TO MARKDOWN TO PROCESS>" fill="#fff"/>
      </svg>
    </a>
    <a aria-label="Angular on YouTube" target="_blank" rel="noopener" href="https://youtube.com/angular" title="YouTube">
      <svg id="youtube-logo" height="24" width="24" data-name="Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff">
        <path d="M0 0h24v24H0V0z" fill="none"/>
        <path d="<TOO LONG FOR DEV.TO MARKDOWN TO PROCESS>"/>
      </svg>
    </a>
</div>
```

And in the `<style>` tag, we also want to add some margin to our `#bell-icon` so that it looks good next to the other icons.

```css
.toolbar #bell-icon {
    height: '';
    margin: 0 16px;
}
```

And now you should see the bell icon (the notification center) in the toolbar section of your app


![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmovxzn2ktdizdsldgsl.png)

![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uv7tvfo08i8a0h2ppulr.png)

## Test the notification center

It’s going to be very awkward if you will fail, but don’t let it discourage you and go over the previous steps one more time thoroughly to make sure you haven’t missed/skipped anything. 

Now let’s test our notification workflow (template):

![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mkm6co5ijn7esgf24eik.png)

You should see a red dot indicating that you have received a notification.

![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ae5ym0u9b3auq8myglgp.png)

![Screenshot](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8i8ry3v753s712lgr428.png)

And that’s it!

This is what we’d sought to achieve at the beginning of this tutorial. 
If you’ve followed till this part and your app is working, pat yourself on the back. Congratulations, you did well!

Going forward, I’ll be sharing many such tutorials and apps in Angular so make sure you stay tuned for that.

Until next time, 
Pearceman