Build a Daily video call app with Angular and TypeScript (Part 1)
Tags: angular, typescript, webrtc, tutorial
Published: 2023-10-12 17:23:49

_By [Jess Mitchell](https://www.daily.co/blog/author/jess/)_

If you’ve read Daily’s blog before, you’ll know we’re happy to show developers all the different ways you can incorporate Daily’s SDKs into your apps. One of the best aspects of [Daily's Client SDK for JavaScript](https://docs.daily.co/reference/daily-js) is that it’s front-end framework agnostic. If you love [React](https://www.daily.co/blog/tag/react/) and [Next.js](https://www.daily.co/blog/tag/next-js/), we have several tutorials and demo apps for you! If you prefer [Svelte](https://www.daily.co/blog/tag/svelte/), [Vue](https://www.daily.co/blog/tag/vue/), or [plain JavaScript](https://www.daily.co/blog/tag/social-gaming/), we’ve got you covered there, too.

In this series, we’ll be expanding our front-end framework resources even further with our newest series on building an [Angular](https://angular.io/) app with [Daily’s Client SDK for JavaScript](https://docs.daily.co/reference/daily-js).

This will start as a four-part series with the following topics:

1. An overview of the Angular demo app’s features and component structure.
2. Building the user flow of joining and leaving a Daily call.
3. How to render video tiles for each participant and manage any track changes.
4. Adding a custom chat component to the video call app so participants can send text-based messages to each other in the call.

![Three call participants in a video call, two of them with their cameras on](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8dozzcbj8nyo9nj84cd.png)

_In-call demo app view_

Today’s post will focus on the first topic: an overview of the demo app and its components. To follow along with this series, we recommend having existing familiarity with JavaScript/TypeScript, HTML, and Angular. (We won’t go into the CSS styling much since it’s not a key factor in the functionality of the app.)

We’ve got a lot to get through, so let’s get started!

## Testing the demo app locally
To follow along with this series, we recommend testing the demo app yourself and reviewing the [source code](https://github.com/daily-demos/daily-angular).

### Creating a Daily account and a Daily room
To use the demo app, you will first need to [create a free Daily account](https://dashboard.daily.co/signup). Once you have an account, you can [create a Daily room](https://dashboard.daily.co/rooms/create). We recommend using the default settings when creating a room, but if you do update the settings, leave the room `privacy` configuration set to [`public`](https://docs.daily.co/reference/rest-api/rooms/config#privacy). (The app isn’t currently set up to handle access requests, like knocking, but you could add that feature.)

Make note of the room’s URL, which will be required to use the demo app.

### Running the demo app
To use the demo app locally, start by installing Angular if you haven’t already:

```
npm install -g @angular/cli
```

Next, clone the demo [repository](https://github.com/daily-demos/daily-angular) and navigate into the demo’s root directory on your local machine:

```
git clone https://github.com/daily-demos/daily-angular.git
cd daily-angular
Bash
Install its dependencies, start the local server, and visit the app in your browser of choice at localhost:4200.

npm install
npm run start
```

We encourage developers to add to this demo app as needed to try out different features available through [Daily’s Client SDK for JavaScript](https://docs.daily.co/reference/daily-js). If you want to add a new feature, you can create new components with `ng generate component <component-name>`.

Now that we’re set up, let’s dig into the feature set.

## App features overview
As mentioned, the demo app will be built with [Angular](https://angular.io/) and [Daily’s Client SDK for JavaScript](https://docs.daily.co/reference/daily-js). It will support multi-participant calls, but will focus on the core functionality and not contain [performance optimizations](https://www.daily.co/blog/tips-to-improve-performance/) for larger calls, like conferences. (Check out our [large calls guide](https://docs.daily.co/guides/scaling-calls/large-real-time-calls) for more information about building apps for up to 100,000 real-time participants.)

The app UI will be fully customized, but you could also embed [Daily Prebuilt](https://docs.daily.co/guides/products/prebuilt) if you prefer a ready-made solution.

The actual features we’ll have built by the end of this series include:

1. Two views: a home page with a form to join the call and an in-call view.
2. The join form will accept two pieces of information: your name and the Daily room you’d like to join.
3. The in-call view will have a video tile for each participant. Participants can turn their video and audio on/off, and can click a button to leave the call. Video tiles will automatically update when a remote participant toggles their media or the track changes, (e.g., if they change their input device).
4. An error screen is shown for errors and a “Not Found” page is shown if you navigate away from the main route.

![Entry form to join a Daily video call room](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3gt9ca50h57wv9dvjnco.png)
_The demo app's join form in the home page view_

## App component structure
Let’s now see how our Angular components are structured relative to each other:

![A schematic showing app-root, app-call, and other video call Angular application components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jjbt590hoo2d2h16jiho.png)
_Component structure in the Angular demo app_

Each of the components in the flow chart above is only rendered once except for [`video-tile`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/video-tile) component. A `video-tile` component is rendered for each participant present.

The names used in the chart refer to each component’s selector, which can be found in the component’s TypeScript file. For example:

```
@Component({
  selector: "app-call",
  templateUrl: "./call.component.html",
  styleUrls: ["./call.component.css"],
})
```

In general, we’ll refer to a component by its selector in this series, but we may also use its class name if we’re specifically referring to the class definition.

If you’re newer to Angular, another detail to be aware of is that each component has three files associated with it:

1. A TypeScript file that defines the component class.
2. An HTML file defining its DOM elements.
3. A CSS file to style the DOM elements.

The first two are the files we’ll focus on in this series.

And, lastly, if you’re specific looking for example code for the video-aspects of build a video app in Angular, the components with the most Daily-related code are [`app-call`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/call), [`app-chat`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/chat), and [`video-tile`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/video-tile).

Next, let’s see what each component does and when it's rendered.

### `app-root` and routing
Every Angular app will have a root component that parents the entire app. It includes any HTML elements that are rendered on every page, regardless of the route (in our case, the `header` and `main` elements). It also manages app routing and will conditionally render a component based on how the routes are defined.

In [`app.component.html`](https://github.com/daily-demos/daily-angular/blob/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/app.component.html), we see:

```
<main class="content">
  <!-- App router -->
  <router-outlet></router-outlet>
</main>
```

`router-outlet` will render the component that matches the route currently being visited.

The logic for which component should be rendered is defined in [`app-routing.module.ts`](https://github.com/daily-demos/daily-angular/blob/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/app-routing.module.ts):

```
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { PageNotFoundComponent } from "./page-not-found/page-not-found.component";
import { DailyContainerComponent } from "./daily-container/daily-container.component";

const routes: Routes = [
  { path: "", component: DailyContainerComponent },
  { path: "**", component: PageNotFoundComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}
```

In the `routes` array, each path is mapped to a different component. Since our app routing is quite simple, we only have two routes: the base path and literally anything else. If you are visiting the base path (e.g., `localhost:4200/`), the `DailyContainerComponent` is rendered (a.k.a. [`app-daily-container`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/daily-container)). Otherwise, a message is shown that the page isn’t found (the [`app-page-not-found`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/page-not-found) component).

!["Uh oh. This page doesn't exist."](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/64qfnfb9h89epu3lsbbb.png)
_`app-page-not-found` view_

To add more `routes` to the app, the routes array can be updated, though the wildcard option should be left as the last item to catch any routes that aren’t specifically included.

### `app-daily-container`, `join-form`, and `app-call`
Moving further down the flow chart, we have [`app-daily-container`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/daily-container) next and two of its child components: [`join-form`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/join-form), and [`app-call`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/call).

The role of [`app-daily-container`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/daily-container) is to determine whether [`join-form`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/join-form) or [`app-call`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/call) should be rendered. They will never both be rendered at the same time. It does this by keeping track of whether the HTML form in `join-form` has been submitted and, if so, rendering the `app-call` component instead. (In the next post in this series, we’ll look more closely at the code that handles this.)


![Animation showing user clicking Join to enter the call](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mgy3ktmztglhujg7wuzm.gif)
_Submitting the form in `join-form` will cause `app-daily-container` to render `app-call` instead._

`join-form` accepts two pieces of information:

1. Your user name, which will be displayed in-call.
2. The URL for the Daily room you would like to join. (This is the URL for the room created above.)
`app-call` is the actual video call UI where you can see video tiles for any participants who have joined the same Daily room.

### `video-tile` and `error-message`
As mentioned, each participant will have a [`video-tile`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/video-tile) component rendered for them to indicate they are present in the call. The `video-tile` component includes the participant’s name and icons to indicate if their audio is currently on. It also has an HTML `video` element for all participants and an audio element for remote participants. (An HTML `audio` element is not rendered for the local participant – you! – because you can already hear yourself speak, meaning you don’t need to have your audio played back to you.) If the participant’s video is turned off, a placeholder tile is rendered over the video.

You, the local participant, will also see a control panel over your tile with buttons to toggle your audio and video on/off, as well as a button to leave the call.

![Two video tiles: The local participant with the control panel and a remote participant with their video off.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eu3s5zajczvjmu0ahh6l.png)
_Two video tiles: The local participant with the control panel and a remote participant with their video off._

If there is an error related to the call, the [`error-message`](https://github.com/daily-demos/daily-angular/tree/8583a8688c1fd1773bb79175edaa6b6848861e06/src/app/error-message) component is shown instead of the list of `video-tile` components. It is rendered when the [`error` event](https://docs.daily.co/reference/daily-js/events/meeting-events#error) is emitted by [Daily’s Client SDK for JavaScript](https://docs.daily.co/reference/daily-js). It displays the error message included in the error event’s payload and provides a button to leave the call.

### `app-chat`
`app-chat` is also a child component of `app-daily-container`. It is not related to the video part of the call; rather, it represents the text-based chat feature. This component can actually be used in either a custom UI – like this demo app – or in an app that embeds Daily Prebuilt.

Like `app-call`, the chat component requires that the call has been joined before it will work, so it is rendered once the form in `join-form` has been submitted.

![Slide-out chat panel on the right-hand side of the Angular video app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8q2qrwik4fs66p5cz61g.png)
_The `app-chat` component highlighted in the app’s UI._

## Conclusion
Today, we reviewed the structure and features of Daily’s new Angular demo app. In the next post, we’ll look at how the `app-daily-container` component responds to submitting the form in the `join-form` component. We’ll also review how to use [Daily’s Client SDK for JavaScript](https://docs.daily.co/reference/daily-js) to let the local participant join or leave a call.

Check out the complete [source code](https://github.com/daily-demos/daily-angular) for this demo app to get a head start and keep an eye on our [blog](https://www.daily.co/blog/tag/angular) for future posts in this series!