Build a Daily video call app with Angular and TypeScript (Part 1)

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 is that it’s front-end framework agnostic. If you love React and Next.js, we have several tutorials and demo apps for you! If you prefer Svelte, Vue, or plain JavaScript, 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 app with Daily’s Client SDK for JavaScript.

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
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.

Creating a Daily account and a Daily room

To use the demo app, you will first need to create a free Daily account. Once you have an account, you can create a Daily room. 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. (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 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

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. 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 and Daily’s Client SDK for JavaScript. It will support multi-participant calls, but will focus on the core functionality and not contain performance optimizations for larger calls, like conferences. (Check out our large calls guide 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 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
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
Component structure in the Angular demo app

Each of the components in the flow chart above is only rendered once except for 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, app-chat, and 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, 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:

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). Otherwise, a message is shown that the page isn’t found (the app-page-not-found component).

"Uh oh. This page doesn't exist."
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 next and two of its child components: join-form, and app-call.

The role of app-daily-container is to determine whether join-form or 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
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 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.
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 component is shown instead of the list of video-tile components. It is rendered when the error event is emitted by Daily’s Client SDK for JavaScript. 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
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 to let the local participant join or leave a call.

Check out the complete source code for this demo app to get a head start and keep an eye on our blog for future posts in this series!

Never miss a story

Get the latest direct to your inbox.