Build native desktop apps with Angular 4 and Electron 1.7. In this lesson I create a simple timer app, then package it for Windows, MacOS, and Linux. Full Lesson at https://angularfirebase.com/lessons/desktop-apps-with-electron-and-angular/

Source Code: https://github.com/AngularFirebase/angular-electron
Electron: https://electron.atom.io/
Angular: https://angular.io
2024-02-04T08:04:49.182Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
01d16f4f-710c-4146-8101-d5202a0340d5
2c24c42bcbd6bcd49a38ad7ab4babe0b6d2606b7873f38c743ebd88cd250ea7f
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
When you combine Angular with the Electron framework, it becomes easy to create native desktop apps that can run on any platform.
In this episode, we're going to build a simple timer application with Angular, then run that app natively on Mac OS, Windows 10, and Ubuntu.
With just a little bit of configuration, we'll be able to build an executable file for all all 3 of these platforms, while still being able to run the app in a web browser.
A large number of high profile companies use Electron to distribute their software.
It was originally developed by GitHub, with and.
It's used by WordPress, Versus Code, Slack, and many others.
Before we get started building the app for this video, I I just wanna point out that you can get all the source code at angularfirebase.com or on GitHub, and all the links are in the description.
So the first thing we're going to do is install the Angular CLI, then create a new app by running ng new, and then we'll CD into that directory.
From there, we just need to make one small change to the index HTML file in the source directory.
You'll notice the base h ref points to a single slash.
To make this work with Electron, we just need to add a single period in front of it.
From here, we're going to install Electron into our development environment.
Serum NPM install Electron flag save dev.
The next step is to create a file called main JS and the root of your Angular project.
Main JS is where you handle all the back end logic for an Electron app.
So first, we're going to import the app and browser window objects.
First, we declare your variable win that defines how the app will look when the user first opens it on their operating system.
So our timer app's going to be 600 pixels by 600 pixels with a background color of white, and I also have a logo image file in the assets folder of my app.
And just so you know, the underscore dir name is a Node JS variable that refers to the actual location of a file on this particular system.
Then the next step is to call win load URL with the index file for our app.
It's important to point out that we're telling Electron to use the index HTML file in our dist folder, not the source folder.
At this point, that file doesn't actually exist, but we're going to build it here in the next step with ahead of time compilation.
I also wanna point out that Electron's built with the Chromium browser engine.
So if you wanna use Chrome Dev Tools during development, you can just uncomment this line and they'll appear directly in your app window.
The window object has a whole bunch of different events that we can listen to.
In this case, when the window is closed, we just set it equal to null and the app object also has events we can listen to.
The most important one being when the app is ready.
In that case, that's when we run the create window function.
There There are certain situations where you wanna handle things differently based on the operating system.
In macOS or Darwin as it's called, it generally doesn't close the application when you close the window.
It stays running in the background.
So as long as the operating system doesn't equal Darwin, we can go ahead and tell the app to quit when all the windows are closed.
So So depending on the complexity of your app, you may need to listen to different events and handle things differently on a per operating system basis.
The next thing we're going to do is create a custom command that will build our app in Angular with ahead of time compilation and then run Electron.
Here inside package dot JSON, we'll first add the main JS file.
Then we create the custom command by going down here to scripts, and we'll create one command just to run Electron, then a second command called Electron dash build that will first run the Angular production build with ahead of time compilation and then run Electron directly after that.
Let's try it out from the command line.
Go ahead run, npm run, electron build.
After Angular's done building your production app, electron will then pull up a window on your operating system with the baseline Angular app.
So that's pretty cool.
We already have our own desktop app.
Now we just need to turn it into something useful and then package it for execution on various operating systems.
What we're going to build is just a simple timer using the Angular SVG round progress bar package, which you can install with NPM.
Then we'll allow the user to set the value of the timer and have it play a sound once it reaches the end.
To build the app, we'll first go into the app module, then we'll import the forms module and the round progress module that we just installed, then add both of those to the import section.
From here, we can start building the timer and the app component.
First time importing a few RX JS operators, which you'll see in use here in a second.
Then for the timer itself, we're going to set a max value, which is the total length of the timer.
And then we'll set a current value which is the current second that that timer is at.
Then we're going to use TypeScript getters to handle a few issues that I came across during development.
The progress bar will throw an error if the value is not a number.
If that is the case, then we'll return a default floor value of 0.1.
This will ensure that the max value is always a number and always greater than or equal to 0.1.
Then we'll do the same basic thing here for the current value, but This time, we'll allow its floor value to go down to 0.
And we can determine if the timer is finished by seeing if the current value is greater than or equal to the max value.
From this point, we'll set up some event handlers to allow the user to interact with the timer.
The first thing they can do is start it.
And to do that, we'll use an observable interval from RxJS JS that will tick every 10th of a second.
We can use the take while operator to only take values from this observable when the timer is not finished.
Then we'll use the do operator to increment the current value by 1 tenth of a second each time this observable emits.
Then we can start the timer by just calling subscribe on it.
To finish the timer, all we have to do is set the current value to the max value.
Because we set up the take while operator in the previous method, this will automatically cause the observable to complete.
The last thing we need is to reset the timer and we can do that by simply setting the current value back to 0.
Now we just need to put everything together in the HTML.
I'm wrapping everything in a main div and then I'll set another div here that holds the progress timer and we're only gonna show this if the max value does exist.
Then we can declare the round progress component and add a few input values to it.
Current will be the current value getter and max will be the max value getter.
Round Progress has a whole bunch of other customization options that you can check out in the documentation.
For now, I'm just going to set the radius and the stroke width.
When the progress timer has not finished, we wanna be able to show the user how many seconds are remaining.
We can do that by just subtracting the max value from the current value, and then we'll use the angular number pipe to format this as just one digit with at least one decimal point.
When the timer is finished, we want to show the user that it's done and also play a sound.
So to play a sound, we can just use the HTML audio tag and point the source to an MP 3 file that I have saved in the assets directory.
And also make sure to include the autoplay property.
The next step is to give the user a form input where they can set the number of seconds the timer will be set for.
So we'll do that with NG model and set that to the max value in the TypeScript.
Whenever the user types in this input, we know Odessa resetting the timer, so we'll go ahead and call the reset method.
And we'll set up a couple buttons here that are displayed conditionally based on the state of the timer, and the first one will be to start it.
That is shown if the current value is less than or equal to 0.
Then we'll set up a second button here to finish the timer if the user decides they want to complete it early.
So that's it for the Angular app.
That's all we need to create a basic timer.
Let's go ahead and rebuild the app and test it out.
I'm currently working on a Linux Ubuntu machine and this is the result that I get here.
We can have the user enter the number of seconds and click start and the timer starts and it's animated and plays the sound.
So at this point, the Angular app's ready to go, but we still need to package it to be used on native desktop applications.
There's a tool called Electron Packager that will help us do this from the command line.
So so we wanna have that installed globally and in our local Angular development environment.
With our current configuration, we can just call Electron Packager from the root of the project, then specify the platform we wanna build for, in this case, Win 32 or Windows.
If you're not on a Windows machine, you'll also have to install Wine HQ, so just a heads up on that.
After a few seconds, it creates a new directory in the root of the project with the build for Windows.
So you can see all the different Windows specific files here as well as the executable file.
So now I'm switching over to a Windows machine and we'll see if this actually works.
We'll click on the EXE file, and then that timer comes up as expected and works just like it did on Linux.
Now we can go back and repeat the process for macOS.
This time, we'll specify the platform as Darwin, and you'll see we get another build file here, this time with all macOS specific files in it.
Now I'm jumping over to my Mac laptop to make sure it works here as well.
You will get warnings that it's an unknown developer because the application hasn't been signed.
That's beyond the scope of this video, but I may cover it in the future.
Other than a few presentational differences, the timer works exactly the same on all three platforms.
With That's it for Angular with Electron.
If this video helped you, please like and subscribe.
And if you wanna support the channel, consider becoming a pro member at angularfirebase.com.
You'll get 1 on 1 project consulting as well as a free copy of my Angular Firebase survival guide.
Thanks for watching, and I'll see you soon.

Speaker 0: When you combine Angular with the Electron framework, it becomes easy to create native desktop apps that can run on any platform. In this episode, we're going to build a simple timer application with Angular, then run that app natively on Mac OS, Windows 10, and Ubuntu. With just a little bit of configuration, we'll be able to build an executable file for all all 3 of these platforms, while still being able to run the app in a web browser. A large number of high profile companies use Electron to distribute their software. It was originally developed by GitHub, with and.

It's used by WordPress, Versus Code, Slack, and many others. Before we get started building the app for this video, I I just wanna point out that you can get all the source code at angularfirebase.com or on GitHub, and all the links are in the description. So the first thing we're going to do is install the Angular CLI, then create a new app by running ng new, and then we'll CD into that directory. From there, we just need to make one small change to the index HTML file in the source directory. You'll notice the base h ref points to a single slash.

To make this work with Electron, we just need to add a single period in front of it. From here, we're going to install Electron into our development environment. Serum NPM install Electron flag save dev. The next step is to create a file called main JS and the root of your Angular project. Main JS is where you handle all the back end logic for an Electron app.

So first, we're going to import the app and browser window objects. First, we declare your variable win that defines how the app will look when the user first opens it on their operating system. So our timer app's going to be 600 pixels by 600 pixels with a background color of white, and I also have a logo image file in the assets folder of my app. And just so you know, the underscore dir name is a Node JS variable that refers to the actual location of a file on this particular system. Then the next step is to call win load URL with the index file for our app.

It's important to point out that we're telling Electron to use the index HTML file in our dist folder, not the source folder. At this point, that file doesn't actually exist, but we're going to build it here in the next step with ahead of time compilation. I also wanna point out that Electron's built with the Chromium browser engine. So if you wanna use Chrome Dev Tools during development, you can just uncomment this line and they'll appear directly in your app window. The window object has a whole bunch of different events that we can listen to.

In this case, when the window is closed, we just set it equal to null and the app object also has events we can listen to. The most important one being when the app is ready. In that case, that's when we run the create window function. There There are certain situations where you wanna handle things differently based on the operating system. In macOS or Darwin as it's called, it generally doesn't close the application when you close the window.

It stays running in the background. So as long as the operating system doesn't equal Darwin, we can go ahead and tell the app to quit when all the windows are closed. So So depending on the complexity of your app, you may need to listen to different events and handle things differently on a per operating system basis. The next thing we're going to do is create a custom command that will build our app in Angular with ahead of time compilation and then run Electron. Here inside package dot JSON, we'll first add the main JS file.

Then we create the custom command by going down here to scripts, and we'll create one command just to run Electron, then a second command called Electron dash build that will first run the Angular production build with ahead of time compilation and then run Electron directly after that. Let's try it out from the command line. Go ahead run, npm run, electron build. After Angular's done building your production app, electron will then pull up a window on your operating system with the baseline Angular app. So that's pretty cool.

We already have our own desktop app. Now we just need to turn it into something useful and then package it for execution on various operating systems. What we're going to build is just a simple timer using the Angular SVG round progress bar package, which you can install with NPM. Then we'll allow the user to set the value of the timer and have it play a sound once it reaches the end. To build the app, we'll first go into the app module, then we'll import the forms module and the round progress module that we just installed, then add both of those to the import section.

From here, we can start building the timer and the app component. First time importing a few RX JS operators, which you'll see in use here in a second. Then for the timer itself, we're going to set a max value, which is the total length of the timer. And then we'll set a current value which is the current second that that timer is at. Then we're going to use TypeScript getters to handle a few issues that I came across during development.

The progress bar will throw an error if the value is not a number. If that is the case, then we'll return a default floor value of 0.1. This will ensure that the max value is always a number and always greater than or equal to 0.1. Then we'll do the same basic thing here for the current value, but This time, we'll allow its floor value to go down to 0. And we can determine if the timer is finished by seeing if the current value is greater than or equal to the max value.

From this point, we'll set up some event handlers to allow the user to interact with the timer. The first thing they can do is start it. And to do that, we'll use an observable interval from RxJS JS that will tick every 10th of a second. We can use the take while operator to only take values from this observable when the timer is not finished. Then we'll use the do operator to increment the current value by 1 tenth of a second each time this observable emits.

Then we can start the timer by just calling subscribe on it. To finish the timer, all we have to do is set the current value to the max value. Because we set up the take while operator in the previous method, this will automatically cause the observable to complete. The last thing we need is to reset the timer and we can do that by simply setting the current value back to 0. Now we just need to put everything together in the HTML.

I'm wrapping everything in a main div and then I'll set another div here that holds the progress timer and we're only gonna show this if the max value does exist. Then we can declare the round progress component and add a few input values to it. Current will be the current value getter and max will be the max value getter. Round Progress has a whole bunch of other customization options that you can check out in the documentation. For now, I'm just going to set the radius and the stroke width.

When the progress timer has not finished, we wanna be able to show the user how many seconds are remaining. We can do that by just subtracting the max value from the current value, and then we'll use the angular number pipe to format this as just one digit with at least one decimal point. When the timer is finished, we want to show the user that it's done and also play a sound. So to play a sound, we can just use the HTML audio tag and point the source to an MP 3 file that I have saved in the assets directory. And also make sure to include the autoplay property.

The next step is to give the user a form input where they can set the number of seconds the timer will be set for. So we'll do that with NG model and set that to the max value in the TypeScript. Whenever the user types in this input, we know Odessa resetting the timer, so we'll go ahead and call the reset method. And we'll set up a couple buttons here that are displayed conditionally based on the state of the timer, and the first one will be to start it. That is shown if the current value is less than or equal to 0.

Then we'll set up a second button here to finish the timer if the user decides they want to complete it early. So that's it for the Angular app. That's all we need to create a basic timer. Let's go ahead and rebuild the app and test it out. I'm currently working on a Linux Ubuntu machine and this is the result that I get here.

We can have the user enter the number of seconds and click start and the timer starts and it's animated and plays the sound. So at this point, the Angular app's ready to go, but we still need to package it to be used on native desktop applications. There's a tool called Electron Packager that will help us do this from the command line. So so we wanna have that installed globally and in our local Angular development environment. With our current configuration, we can just call Electron Packager from the root of the project, then specify the platform we wanna build for, in this case, Win 32 or Windows.

If you're not on a Windows machine, you'll also have to install Wine HQ, so just a heads up on that. After a few seconds, it creates a new directory in the root of the project with the build for Windows. So you can see all the different Windows specific files here as well as the executable file. So now I'm switching over to a Windows machine and we'll see if this actually works. We'll click on the EXE file, and then that timer comes up as expected and works just like it did on Linux.

Now we can go back and repeat the process for macOS. This time, we'll specify the platform as Darwin, and you'll see we get another build file here, this time with all macOS specific files in it. Now I'm jumping over to my Mac laptop to make sure it works here as well. You will get warnings that it's an unknown developer because the application hasn't been signed. That's beyond the scope of this video, but I may cover it in the future.

Other than a few presentational differences, the timer works exactly the same on all three platforms. With That's it for Angular with Electron. If this video helped you, please like and subscribe. And if you wanna support the channel, consider becoming a pro member at angularfirebase.com. You'll get 1 on 1 project consulting as well as a free copy of my Angular Firebase survival guide.

Thanks for watching, and I'll see you soon.
When you combine Angular with the Electron framework, it becomes easy to create native desktop apps that can run on any platform. In this episode, we're going to build a simple timer application with Angular, then run that app natively on Mac OS, Windows 10, and Ubuntu.
With just a little bit of configuration, we'll be able to build an executable file for all all 3 of these platforms, while still being able to run the app in a web browser. A large number of high profile companies use Electron to distribute their software. It was originally developed by GitHub, with and.
software
software development
It's used by WordPress, Versus Code, Slack, and many others.
Before we get started building the app for this video, I I just wanna point out that you can get all the source code at angularfirebase.com or on GitHub, and all the links are in the description. So the first thing we're going to do is install the Angular CLI, then create a new app by running ng new, and then we'll CD into that directory.
youtube
From there, we just need to make one small change to the index HTML file in the source directory. You'll notice the base h ref points to a single slash. To make this work with Electron, we just need to add a single period in front of it. From here, we're going to install Electron into our development environment. Serum NPM install Electron flag save dev. The next step is to create a file called main JS and the root of your Angular project. Main JS is where you handle all the back end logic for an Electron app. So first, we're going to import the app and browser window objects. First, we declare your variable win that defines how the app will look when the user first opens it on their operating system. So our timer app's going to be 600 pixels by 600 pixels with a background color of white, and I also have a logo image file in the assets folder of my app. And just so you know, the underscore dir name is a Node JS variable that refers to the actual location of a file on this particular system. Then the next step is to call win load URL with the index file for our app. It's important to point out that we're telling Electron to use the index HTML file in our dist folder, not the source folder. At this point, that file doesn't actually exist, but we're going to build it here in the next step with ahead of time compilation. I also wanna point out that Electron's built with the Chromium browser engine.
So if you wanna use Chrome Dev Tools during development, you can just uncomment this line and they'll appear directly in your app window. The window object has a whole bunch of different events that we can listen to. In this case, when the window is closed, we just set it equal to null and the app object also has events we can listen to.
software
software development
The most important one being when the app is ready. In that case, that's when we run the create window function. There There are certain situations where you wanna handle things differently based on the operating system. In macOS or Darwin as it's called, it generally doesn't close the application when you close the window. It stays running in the background. So as long as the operating system doesn't equal Darwin, we can go ahead and tell the app to quit when all the windows are closed.
So So depending on the complexity of your app, you may need to listen to different events and handle things differently on a per operating system basis. The next thing we're going to do is create a custom command that will build our app in Angular with ahead of time compilation and then run Electron.
software development
software
Here inside package dot JSON, we'll first add the main JS file. Then we create the custom command by going down here to scripts, and we'll create one command just to run Electron, then a second command called Electron dash build that will first run the Angular production build with ahead of time compilation and then run Electron directly after that. Let's try it out from the command line. Go ahead run, npm run, electron build. After Angular's done building your production app, electron will then pull up a window on your operating system with the baseline Angular app.
So that's pretty cool. We already have our own desktop app. Now we just need to turn it into something useful and then package it for execution on various operating systems. What we're going to build is just a simple timer using the Angular SVG round progress bar package, which you can install with NPM. Then we'll allow the user to set the value of the timer and have it play a sound once it reaches the end. To build the app, we'll first go into the app module, then we'll import the forms module and the round progress module that we just installed, then add both of those to the import section.
software development
From here, we can start building the timer and the app component. First time importing a few RX JS operators, which you'll see in use here in a second.
Then for the timer itself, we're going to set a max value, which is the total length of the timer. And then we'll set a current value which is the current second that that timer is at. Then we're going to use TypeScript getters to handle a few issues that I came across during development.
programming
The progress bar will throw an error if the value is not a number. If that is the case, then we'll return a default floor value of 0.1. This will ensure that the max value is always a number and always greater than or equal to 0.1. Then we'll do the same basic thing here for the current value, but This time, we'll allow its floor value to go down to 0. And we can determine if the timer is finished by seeing if the current value is greater than or equal to the max value. From this point, we'll set up some event handlers to allow the user to interact with the timer. The first thing they can do is start it. And to do that, we'll use an observable interval from RxJS JS that will tick every 10th of a second. We can use the take while operator to only take values from this observable when the timer is not finished. Then we'll use the do operator to increment the current value by 1 tenth of a second each time this observable emits. Then we can start the timer by just calling subscribe on it. To finish the timer, all we have to do is set the current value to the max value. Because we set up the take while operator in the previous method, this will automatically cause the observable to complete. The last thing we need is to reset the timer and we can do that by simply setting the current value back to 0. Now we just need to put everything together in the HTML. I'm wrapping everything in a main div and then I'll set another div here that holds the progress timer and we're only gonna show this if the max value does exist. Then we can declare the round progress component and add a few input values to it. Current will be the current value getter and max will be the max value getter. Round Progress has a whole bunch of other customization options that you can check out in the documentation. For now, I'm just going to set the radius and the stroke width. When the progress timer has not finished, we wanna be able to show the user how many seconds are remaining. We can do that by just subtracting the max value from the current value, and then we'll use the angular number pipe to format this as just one digit with at least one decimal point.
When the timer is finished, we want to show the user that it's done and also play a sound. So to play a sound, we can just use the HTML audio tag and point the source to an MP 3 file that I have saved in the assets directory. And also make sure to include the autoplay property.
audio
The next step is to give the user a form input where they can set the number of seconds the timer will be set for. So we'll do that with NG model and set that to the max value in the TypeScript. Whenever the user types in this input, we know Odessa resetting the timer, so we'll go ahead and call the reset method. And we'll set up a couple buttons here that are displayed conditionally based on the state of the timer, and the first one will be to start it. That is shown if the current value is less than or equal to 0. Then we'll set up a second button here to finish the timer if the user decides they want to complete it early. So that's it for the Angular app. That's all we need to create a basic timer. Let's go ahead and rebuild the app and test it out. I'm currently working on a Linux Ubuntu machine and this is the result that I get here. We can have the user enter the number of seconds and click start and the timer starts and it's animated and plays the sound. So at this point, the Angular app's ready to go, but we still need to package it to be used on native desktop applications. There's a tool called Electron Packager that will help us do this from the command line. So so we wanna have that installed globally and in our local Angular development environment. With our current configuration, we can just call Electron Packager from the root of the project, then specify the platform we wanna build for, in this case, Win 32 or Windows.
If you're not on a Windows machine, you'll also have to install Wine HQ, so just a heads up on that. After a few seconds, it creates a new directory in the root of the project with the build for Windows. So you can see all the different Windows specific files here as well as the executable file. So now I'm switching over to a Windows machine and we'll see if this actually works. We'll click on the EXE file, and then that timer comes up as expected and works just like it did on Linux.
wine
microsoft
Now we can go back and repeat the process for macOS.
This time, we'll specify the platform as Darwin, and you'll see we get another build file here, this time with all macOS specific files in it. Now I'm jumping over to my Mac laptop to make sure it works here as well. You will get warnings that it's an unknown developer because the application hasn't been signed.
computer science
apple
That's beyond the scope of this video, but I may cover it in the future. Other than a few presentational differences, the timer works exactly the same on all three platforms. With That's it for Angular with Electron. If this video helped you, please like and subscribe. And if you wanna support the channel, consider becoming a pro member at angularfirebase.com. You'll get 1 on 1 project consulting as well as a free copy of my Angular Firebase survival guide. Thanks for watching, and I'll see you soon.
When you combine Angular with the Electron framework, it becomes easy to create native desktop apps that can run on any platform. In this episode, we're going to build a simple timer application with Angular, then run that app natively on Mac OS, Windows 10, and Ubuntu. With just a little bit of configuration, we'll be able to build an executable file for all all 3 of these platforms, while still being able to run the app in a web browser. A large number of high profile companies use Electron to distribute their software. It was originally developed by GitHub, with and. It's used by WordPress, Versus Code, Slack, and many others. Before we get started building the app for this video, I I just wanna point out that you can get all the source code at angularfirebase.com or on GitHub, and all the links are in the description. So the first thing we're going to do is install the Angular CLI, then create a new app by running ng new, and then we'll CD into that directory. From there, we just need to make one small change to the index HTML file in the source directory. You'll notice the base h ref points to a single slash. To make this work with Electron, we just need to add a single period in front of it. From here, we're going to install Electron into our development environment. Serum NPM install Electron flag save dev. The next step is to create a file called main JS and the root of your Angular project. Main JS is where you handle all the back end logic for an Electron app. So first, we're going to import the app and browser window objects. First, we declare your variable win that defines how the app will look when the user first opens it on their operating system. So our timer app's going to be 600 pixels by 600 pixels with a background color of white, and I also have a logo image file in the assets folder of my app. And just so you know, the underscore dir name is a Node JS variable that refers to the actual location of a file on this particular system. Then the next step is to call win load URL with the index file for our app. It's important to point out that we're telling Electron to use the index HTML file in our dist folder, not the source folder. At this point, that file doesn't actually exist, but we're going to build it here in the next step with ahead of time compilation. I also wanna point out that Electron's built with the Chromium browser engine. So if you wanna use Chrome Dev Tools during development, you can just uncomment this line and they'll appear directly in your app window. The window object has a whole bunch of different events that we can listen to. In this case, when the window is closed, we just set it equal to null and the app object also has events we can listen to. The most important one being when the app is ready. In that case, that's when we run the create window function. There There are certain situations where you wanna handle things differently based on the operating system. In macOS or Darwin as it's called, it generally doesn't close the application when you close the window. It stays running in the background. So as long as the operating system doesn't equal Darwin, we can go ahead and tell the app to quit when all the windows are closed. So So depending on the complexity of your app, you may need to listen to different events and handle things differently on a per operating system basis. The next thing we're going to do is create a custom command that will build our app in Angular with ahead of time compilation and then run Electron. Here inside package dot JSON, we'll first add the main JS file. Then we create the custom command by going down here to scripts, and we'll create one command just to run Electron, then a second command called Electron dash build that will first run the Angular production build with ahead of time compilation and then run Electron directly after that. Let's try it out from the command line. Go ahead run, npm run, electron build. After Angular's done building your production app, electron will then pull up a window on your operating system with the baseline Angular app. So that's pretty cool. We already have our own desktop app. Now we just need to turn it into something useful and then package it for execution on various operating systems. What we're going to build is just a simple timer using the Angular SVG round progress bar package, which you can install with NPM. Then we'll allow the user to set the value of the timer and have it play a sound once it reaches the end. To build the app, we'll first go into the app module, then we'll import the forms module and the round progress module that we just installed, then add both of those to the import section. From here, we can start building the timer and the app component. First time importing a few RX JS operators, which you'll see in use here in a second. Then for the timer itself, we're going to set a max value, which is the total length of the timer. And then we'll set a current value which is the current second that that timer is at. Then we're going to use TypeScript getters to handle a few issues that I came across during development. The progress bar will throw an error if the value is not a number. If that is the case, then we'll return a default floor value of 0.1. This will ensure that the max value is always a number and always greater than or equal to 0.1. Then we'll do the same basic thing here for the current value, but This time, we'll allow its floor value to go down to 0. And we can determine if the timer is finished by seeing if the current value is greater than or equal to the max value. From this point, we'll set up some event handlers to allow the user to interact with the timer. The first thing they can do is start it. And to do that, we'll use an observable interval from RxJS JS that will tick every 10th of a second. We can use the take while operator to only take values from this observable when the timer is not finished. Then we'll use the do operator to increment the current value by 1 tenth of a second each time this observable emits. Then we can start the timer by just calling subscribe on it. To finish the timer, all we have to do is set the current value to the max value. Because we set up the take while operator in the previous method, this will automatically cause the observable to complete. The last thing we need is to reset the timer and we can do that by simply setting the current value back to 0. Now we just need to put everything together in the HTML. I'm wrapping everything in a main div and then I'll set another div here that holds the progress timer and we're only gonna show this if the max value does exist. Then we can declare the round progress component and add a few input values to it. Current will be the current value getter and max will be the max value getter. Round Progress has a whole bunch of other customization options that you can check out in the documentation. For now, I'm just going to set the radius and the stroke width. When the progress timer has not finished, we wanna be able to show the user how many seconds are remaining. We can do that by just subtracting the max value from the current value, and then we'll use the angular number pipe to format this as just one digit with at least one decimal point. When the timer is finished, we want to show the user that it's done and also play a sound. So to play a sound, we can just use the HTML audio tag and point the source to an MP 3 file that I have saved in the assets directory. And also make sure to include the autoplay property. The next step is to give the user a form input where they can set the number of seconds the timer will be set for. So we'll do that with NG model and set that to the max value in the TypeScript. Whenever the user types in this input, we know Odessa resetting the timer, so we'll go ahead and call the reset method. And we'll set up a couple buttons here that are displayed conditionally based on the state of the timer, and the first one will be to start it. That is shown if the current value is less than or equal to 0. Then we'll set up a second button here to finish the timer if the user decides they want to complete it early. So that's it for the Angular app. That's all we need to create a basic timer. Let's go ahead and rebuild the app and test it out. I'm currently working on a Linux Ubuntu machine and this is the result that I get here. We can have the user enter the number of seconds and click start and the timer starts and it's animated and plays the sound. So at this point, the Angular app's ready to go, but we still need to package it to be used on native desktop applications. There's a tool called Electron Packager that will help us do this from the command line. So so we wanna have that installed globally and in our local Angular development environment. With our current configuration, we can just call Electron Packager from the root of the project, then specify the platform we wanna build for, in this case, Win 32 or Windows. If you're not on a Windows machine, you'll also have to install Wine HQ, so just a heads up on that. After a few seconds, it creates a new directory in the root of the project with the build for Windows. So you can see all the different Windows specific files here as well as the executable file. So now I'm switching over to a Windows machine and we'll see if this actually works. We'll click on the EXE file, and then that timer comes up as expected and works just like it did on Linux. Now we can go back and repeat the process for macOS. This time, we'll specify the platform as Darwin, and you'll see we get another build file here, this time with all macOS specific files in it. Now I'm jumping over to my Mac laptop to make sure it works here as well. You will get warnings that it's an unknown developer because the application hasn't been signed. That's beyond the scope of this video, but I may cover it in the future. Other than a few presentational differences, the timer works exactly the same on all three platforms. With That's it for Angular with Electron. If this video helped you, please like and subscribe. And if you wanna support the channel, consider becoming a pro member at angularfirebase.com. You'll get 1 on 1 project consulting as well as a free copy of my Angular Firebase survival guide. Thanks for watching, and I'll see you soon.
When
when
you
you
combine
combine
Angular
angular
with
with
the
the
Electron
electron
framework,
framework
it
it
becomes
becomes
easy
easy
to
to
create
create
native
native
desktop
desktop
apps
apps
that
that
can
can
run
run
on
on
any
any
platform.
platform
In
in
this
this
episode,
episode
we're
we're
going
going
to
to
build
build
a
a
simple
simple
timer
timer
application
application
with
with
Angular,
angular
then
then
run
run
that
that
app
app
natively
natively
on
on
Mac
mac
OS,
os
Windows
windows
10,
10
and
and
Ubuntu.
ubuntu
With
with
just
just
a
a
little
little
bit
bit
of
of
configuration,
configuration
we'll
we'll
be
be
able
able
to
to
build
build
an
an
executable
executable
file
file
for
for
all
all
all
all
3
3
of
of
these
these
platforms,
platforms
while
while
still
still
being
being
able
able
to
to
run
run
the
the
app
app
in
in
a
a
web
web
browser.
browser
A
a
large
large
number
number
of
of
high
high
profile
profile
companies
companies
use
use
Electron
electron
to
to
distribute
distribute
their
their
software.
software
It
it
was
was
originally
originally
developed
developed
by
by
GitHub,
github
with
with
and.
and
It's
it's
used
used
by
by
WordPress,
wordpress
Versus
versus
Code,
code
Slack,
slack
and
and
many
many
others.
others
Before
before
we
we
get
get
started
started
building
building
the
the
app
app
for
for
this
this
video,
video
I
i
I
i
just
just
wanna
wanna
point
point
out
out
that
that
you
you
can
can
get
get
all
all
the
the
source
source
code
code
at
at
angularfirebase.com
angularfirebase.com
or
or
on
on
GitHub,
github
and
and
all
all
the
the
links
links
are
are
in
in
the
the
description.
description
So
so
the
the
first
first
thing
thing
we're
we're
going
going
to
to
do
do
is
is
install
install
the
the
Angular
angular
CLI,
cli
then
then
create
create
a
a
new
new
app
app
by
by
running
running
ng
ng
new,
new
and
and
then
then
we'll
we'll
CD
cd
into
into
that
that
directory.
directory
From
from
there,
there
we
we
just
just
need
need
to
to
make
make
one
one
small
small
change
change
to
to
the
the
index
index
HTML
html
file
file
in
in
the
the
source
source
directory.
directory
You'll
you'll
notice
notice
the
the
base
base
h
h
ref
ref
points
points
to
to
a
a
single
single
slash.
slash
To
to
make
make
this
this
work
work
with
with
Electron,
electron
we
we
just
just
need
need
to
to
add
add
a
a
single
single
period
period
in
in
front
front
of
of
it.
it
From
from
here,
here
we're
we're
going
going
to
to
install
install
Electron
electron
into
into
our
our
development
development
environment.
environment
Serum
serum
NPM
npm
install
install
Electron
electron
flag
flag
save
save
dev.
dev
The
the
next
next
step
step
is
is
to
to
create
create
a
a
file
file
called
called
main
main
JS
js
and
and
the
the
root
root
of
of
your
your
Angular
angular
project.
project
Main
main
JS
js
is
is
where
where
you
you
handle
handle
all
all
the
the
back
back
end
end
logic
logic
for
for
an
an
Electron
electron
app.
app
So
so
first,
first
we're
we're
going
going
to
to
import
import
the
the
app
app
and
and
browser
browser
window
window
objects.
objects
First,
first
we
we
declare
declare
your
your
variable
variable
win
win
that
that
defines
defines
how
how
the
the
app
app
will
will
look
look
when
when
the
the
user
user
first
first
opens
opens
it
it
on
on
their
their
operating
operating
system.
system
So
so
our
our
timer
timer
app's
app's
going
going
to
to
be
be
600
600
pixels
pixels
by
by
600
600
pixels
pixels
with
with
a
a
background
background
color
color
of
of
white,
white
and
and
I
i
also
also
have
have
a
a
logo
logo
image
image
file
file
in
in
the
the
assets
assets
folder
folder
of
of
my
my
app.
app
And
and
just
just
so
so
you
you
know,
know
the
the
underscore
underscore
dir
dir
name
name
is
is
a
a
Node
node
JS
js
variable
variable
that
that
refers
refers
to
to
the
the
actual
actual
location
location
of
of
a
a
file
file
on
on
this
this
particular
particular
system.
system
Then
then
the
the
next
next
step
step
is
is
to
to
call
call
win
win
load
load
URL
url
with
with
the
the
index
index
file
file
for
for
our
our
app.
app
It's
it's
important
important
to
to
point
point
out
out
that
that
we're
we're
telling
telling
Electron
electron
to
to
use
use
the
the
index
index
HTML
html
file
file
in
in
our
our
dist
dist
folder,
folder
not
not
the
the
source
source
folder.
folder
At
at
this
this
point,
point
that
that
file
file
doesn't
doesn't
actually
actually
exist,
exist
but
but
we're
we're
going
going
to
to
build
build
it
it
here
here
in
in
the
the
next
next
step
step
with
with
ahead
ahead
of
of
time
time
compilation.
compilation
I
i
also
also
wanna
wanna
point
point
out
out
that
that
Electron's
electron's
built
built
with
with
the
the
Chromium
chromium
browser
browser
engine.
engine
So
so
if
if
you
you
wanna
wanna
use
use
Chrome
chrome
Dev
dev
Tools
tools
during
during
development,
development
you
you
can
can
just
just
uncomment
uncomment
this
this
line
line
and
and
they'll
they'll
appear
appear
directly
directly
in
in
your
your
app
app
window.
window
The
the
window
window
object
object
has
has
a
a
whole
whole
bunch
bunch
of
of
different
different
events
events
that
that
we
we
can
can
listen
listen
to.
to
In
in
this
this
case,
case
when
when
the
the
window
window
is
is
closed,
closed
we
we
just
just
set
set
it
it
equal
equal
to
to
null
null
and
and
the
the
app
app
object
object
also
also
has
has
events
events
we
we
can
can
listen
listen
to.
to
The
the
most
most
important
important
one
one
being
being
when
when
the
the
app
app
is
is
ready.
ready
In
in
that
that
case,
case
that's
that's
when
when
we
we
run
run
the
the
create
create
window
window
function.
function
There
there
There
there
are
are
certain
certain
situations
situations
where
where
you
you
wanna
wanna
handle
handle
things
things
differently
differently
based
based
on
on
the
the
operating
operating
system.
system
In
in
macOS
macos
or
or
Darwin
darwin
as
as
it's
it's
called,
called
it
it
generally
generally
doesn't
doesn't
close
close
the
the
application
application
when
when
you
you
close
close
the
the
window.
window
It
it
stays
stays
running
running
in
in
the
the
background.
background
So
so
as
as
long
long
as
as
the
the
operating
operating
system
system
doesn't
doesn't
equal
equal
Darwin,
darwin
we
we
can
can
go
go
ahead
ahead
and
and
tell
tell
the
the
app
app
to
to
quit
quit
when
when
all
all
the
the
windows
windows
are
are
closed.
closed
So
so
So
so
depending
depending
on
on
the
the
complexity
complexity
of
of
your
your
app,
app
you
you
may
may
need
need
to
to
listen
listen
to
to
different
different
events
events
and
and
handle
handle
things
things
differently
differently
on
on
a
a
per
per
operating
operating
system
system
basis.
basis
The
the
next
next
thing
thing
we're
we're
going
going
to
to
do
do
is
is
create
create
a
a
custom
custom
command
command
that
that
will
will
build
build
our
our
app
app
in
in
Angular
angular
with
with
ahead
ahead
of
of
time
time
compilation
compilation
and
and
then
then
run
run
Electron.
electron
Here
here
inside
inside
package
package
dot
dot
JSON,
json
we'll
we'll
first
first
add
add
the
the
main
main
JS
js
file.
file
Then
then
we
we
create
create
the
the
custom
custom
command
command
by
by
going
going
down
down
here
here
to
to
scripts,
scripts
and
and
we'll
we'll
create
create
one
one
command
command
just
just
to
to
run
run
Electron,
electron
then
then
a
a
second
second
command
command
called
called
Electron
electron
dash
dash
build
build
that
that
will
will
first
first
run
run
the
the
Angular
angular
production
production
build
build
with
with
ahead
ahead
of
of
time
time
compilation
compilation
and
and
then
then
run
run
Electron
electron
directly
directly
after
after
that.
that
Let's
let's
try
try
it
it
out
out
from
from
the
the
command
command
line.
line
Go
go
ahead
ahead
run,
run
npm
npm
run,
run
electron
electron
build.
build
After
after
Angular's
angular's
done
done
building
building
your
your
production
production
app,
app
electron
electron
will
will
then
then
pull
pull
up
up
a
a
window
window
on
on
your
your
operating
operating
system
system
with
with
the
the
baseline
baseline
Angular
angular
app.
app
So
so
that's
that's
pretty
pretty
cool.
cool
We
we
already
already
have
have
our
our
own
own
desktop
desktop
app.
app
Now
now
we
we
just
just
need
need
to
to
turn
turn
it
it
into
into
something
something
useful
useful
and
and
then
then
package
package
it
it
for
for
execution
execution
on
on
various
various
operating
operating
systems.
systems
What
what
we're
we're
going
going
to
to
build
build
is
is
just
just
a
a
simple
simple
timer
timer
using
using
the
the
Angular
angular
SVG
svg
round
round
progress
progress
bar
bar
package,
package
which
which
you
you
can
can
install
install
with
with
NPM.
npm
Then
then
we'll
we'll
allow
allow
the
the
user
user
to
to
set
set
the
the
value
value
of
of
the
the
timer
timer
and
and
have
have
it
it
play
play
a
a
sound
sound
once
once
it
it
reaches
reaches
the
the
end.
end
To
to
build
build
the
the
app,
app
we'll
we'll
first
first
go
go
into
into
the
the
app
app
module,
module
then
then
we'll
we'll
import
import
the
the
forms
forms
module
module
and
and
the
the
round
round
progress
progress
module
module
that
that
we
we
just
just
installed,
installed
then
then
add
add
both
both
of
of
those
those
to
to
the
the
import
import
section.
section
From
from
here,
here
we
we
can
can
start
start
building
building
the
the
timer
timer
and
and
the
the
app
app
component.
component
First
first
time
time
importing
importing
a
a
few
few
RX
rx
JS
js
operators,
operators
which
which
you'll
you'll
see
see
in
in
use
use
here
here
in
in
a
a
second.
second
Then
then
for
for
the
the
timer
timer
itself,
itself
we're
we're
going
going
to
to
set
set
a
a
max
max
value,
value
which
which
is
is
the
the
total
total
length
length
of
of
the
the
timer.
timer
And
and
then
then
we'll
we'll
set
set
a
a
current
current
value
value
which
which
is
is
the
the
current
current
second
second
that
that
that
that
timer
timer
is
is
at.
at
Then
then
we're
we're
going
going
to
to
use
use
TypeScript
typescript
getters
getters
to
to
handle
handle
a
a
few
few
issues
issues
that
that
I
i
came
came
across
across
during
during
development.
development
The
the
progress
progress
bar
bar
will
will
throw
throw
an
an
error
error
if
if
the
the
value
value
is
is
not
not
a
a
number.
number
If
if
that
that
is
is
the
the
case,
case
then
then
we'll
we'll
return
return
a
a
default
default
floor
floor
value
value
of
of
0.1.
0.1
This
this
will
will
ensure
ensure
that
that
the
the
max
max
value
value
is
is
always
always
a
a
number
number
and
and
always
always
greater
greater
than
than
or
or
equal
equal
to
to
0.1.
0.1
Then
then
we'll
we'll
do
do
the
the
same
same
basic
basic
thing
thing
here
here
for
for
the
the
current
current
value,
value
but
but
This
this
time,
time
we'll
we'll
allow
allow
its
its
floor
floor
value
value
to
to
go
go
down
down
to
to
0.
0
And
and
we
we
can
can
determine
determine
if
if
the
the
timer
timer
is
is
finished
finished
by
by
seeing
seeing
if
if
the
the
current
current
value
value
is
is
greater
greater
than
than
or
or
equal
equal
to
to
the
the
max
max
value.
value
From
from
this
this
point,
point
we'll
we'll
set
set
up
up
some
some
event
event
handlers
handlers
to
to
allow
allow
the
the
user
user
to
to
interact
interact
with
with
the
the
timer.
timer
The
the
first
first
thing
thing
they
they
can
can
do
do
is
is
start
start
it.
it
And
and
to
to
do
do
that,
that
we'll
we'll
use
use
an
an
observable
observable
interval
interval
from
from
RxJS
rxjs
JS
js
that
that
will
will
tick
tick
every
every
10th
10th
of
of
a
a
second.
second
We
we
can
can
use
use
the
the
take
take
while
while
operator
operator
to
to
only
only
take
take
values
values
from
from
this
this
observable
observable
when
when
the
the
timer
timer
is
is
not
not
finished.
finished
Then
then
we'll
we'll
use
use
the
the
do
do
operator
operator
to
to
increment
increment
the
the
current
current
value
value
by
by
1
1
tenth
tenth
of
of
a
a
second
second
each
each
time
time
this
this
observable
observable
emits.
emits
Then
then
we
we
can
can
start
start
the
the
timer
timer
by
by
just
just
calling
calling
subscribe
subscribe
on
on
it.
it
To
to
finish
finish
the
the
timer,
timer
all
all
we
we
have
have
to
to
do
do
is
is
set
set
the
the
current
current
value
value
to
to
the
the
max
max
value.
value
Because
because
we
we
set
set
up
up
the
the
take
take
while
while
operator
operator
in
in
the
the
previous
previous
method,
method
this
this
will
will
automatically
automatically
cause
cause
the
the
observable
observable
to
to
complete.
complete
The
the
last
last
thing
thing
we
we
need
need
is
is
to
to
reset
reset
the
the
timer
timer
and
and
we
we
can
can
do
do
that
that
by
by
simply
simply
setting
setting
the
the
current
current
value
value
back
back
to
to
0.
0
Now
now
we
we
just
just
need
need
to
to
put
put
everything
everything
together
together
in
in
the
the
HTML.
html
I'm
i'm
wrapping
wrapping
everything
everything
in
in
a
a
main
main
div
div
and
and
then
then
I'll
i'll
set
set
another
another
div
div
here
here
that
that
holds
holds
the
the
progress
progress
timer
timer
and
and
we're
we're
only
only
gonna
gonna
show
show
this
this
if
if
the
the
max
max
value
value
does
does
exist.
exist
Then
then
we
we
can
can
declare
declare
the
the
round
round
progress
progress
component
component
and
and
add
add
a
a
few
few
input
input
values
values
to
to
it.
it
Current
current
will
will
be
be
the
the
current
current
value
value
getter
getter
and
and
max
max
will
will
be
be
the
the
max
max
value
value
getter.
getter
Round
round
Progress
progress
has
has
a
a
whole
whole
bunch
bunch
of
of
other
other
customization
customization
options
options
that
that
you
you
can
can
check
check
out
out
in
in
the
the
documentation.
documentation
For
for
now,
now
I'm
i'm
just
just
going
going
to
to
set
set
the
the
radius
radius
and
and
the
the
stroke
stroke
width.
width
When
when
the
the
progress
progress
timer
timer
has
has
not
not
finished,
finished
we
we
wanna
wanna
be
be
able
able
to
to
show
show
the
the
user
user
how
how
many
many
seconds
seconds
are
are
remaining.
remaining
We
we
can
can
do
do
that
that
by
by
just
just
subtracting
subtracting
the
the
max
max
value
value
from
from
the
the
current
current
value,
value
and
and
then
then
we'll
we'll
use
use
the
the
angular
angular
number
number
pipe
pipe
to
to
format
format
this
this
as
as
just
just
one
one
digit
digit
with
with
at
at
least
least
one
one
decimal
decimal
point.
point
When
when
the
the
timer
timer
is
is
finished,
finished
we
we
want
want
to
to
show
show
the
the
user
user
that
that
it's
it's
done
done
and
and
also
also
play
play
a
a
sound.
sound
So
so
to
to
play
play
a
a
sound,
sound
we
we
can
can
just
just
use
use
the
the
HTML
html
audio
audio
tag
tag
and
and
point
point
the
the
source
source
to
to
an
an
MP
mp
3
3
file
file
that
that
I
i
have
have
saved
saved
in
in
the
the
assets
assets
directory.
directory
And
and
also
also
make
make
sure
sure
to
to
include
include
the
the
autoplay
autoplay
property.
property
The
the
next
next
step
step
is
is
to
to
give
give
the
the
user
user
a
a
form
form
input
input
where
where
they
they
can
can
set
set
the
the
number
number
of
of
seconds
seconds
the
the
timer
timer
will
will
be
be
set
set
for.
for
So
so
we'll
we'll
do
do
that
that
with
with
NG
ng
model
model
and
and
set
set
that
that
to
to
the
the
max
max
value
value
in
in
the
the
TypeScript.
typescript
Whenever
whenever
the
the
user
user
types
types
in
in
this
this
input,
input
we
we
know
know
Odessa
odessa
resetting
resetting
the
the
timer,
timer
so
so
we'll
we'll
go
go
ahead
ahead
and
and
call
call
the
the
reset
reset
method.
method
And
and
we'll
we'll
set
set
up
up
a
a
couple
couple
buttons
buttons
here
here
that
that
are
are
displayed
displayed
conditionally
conditionally
based
based
on
on
the
the
state
state
of
of
the
the
timer,
timer
and
and
the
the
first
first
one
one
will
will
be
be
to
to
start
start
it.
it
That
that
is
is
shown
shown
if
if
the
the
current
current
value
value
is
is
less
less
than
than
or
or
equal
equal
to
to
0.
0
Then
then
we'll
we'll
set
set
up
up
a
a
second
second
button
button
here
here
to
to
finish
finish
the
the
timer
timer
if
if
the
the
user
user
decides
decides
they
they
want
want
to
to
complete
complete
it
it
early.
early
So
so
that's
that's
it
it
for
for
the
the
Angular
angular
app.
app
That's
that's
all
all
we
we
need
need
to
to
create
create
a
a
basic
basic
timer.
timer
Let's
let's
go
go
ahead
ahead
and
and
rebuild
rebuild
the
the
app
app
and
and
test
test
it
it
out.
out
I'm
i'm
currently
currently
working
working
on
on
a
a
Linux
linux
Ubuntu
ubuntu
machine
machine
and
and
this
this
is
is
the
the
result
result
that
that
I
i
get
get
here.
here
We
we
can
can
have
have
the
the
user
user
enter
enter
the
the
number
number
of
of
seconds
seconds
and
and
click
click
start
start
and
and
the
the
timer
timer
starts
starts
and
and
it's
it's
animated
animated
and
and
plays
plays
the
the
sound.
sound
So
so
at
at
this
this
point,
point
the
the
Angular
angular
app's
app's
ready
ready
to
to
go,
go
but
but
we
we
still
still
need
need
to
to
package
package
it
it
to
to
be
be
used
used
on
on
native
native
desktop
desktop
applications.
applications
There's
there's
a
a
tool
tool
called
called
Electron
electron
Packager
packager
that
that
will
will
help
help
us
us
do
do
this
this
from
from
the
the
command
command
line.
line
So
so
so
so
we
we
wanna
wanna
have
have
that
that
installed
installed
globally
globally
and
and
in
in
our
our
local
local
Angular
angular
development
development
environment.
environment
With
with
our
our
current
current
configuration,
configuration
we
we
can
can
just
just
call
call
Electron
electron
Packager
packager
from
from
the
the
root
root
of
of
the
the
project,
project
then
then
specify
specify
the
the
platform
platform
we
we
wanna
wanna
build
build
for,
for
in
in
this
this
case,
case
Win
win
32
32
or
or
Windows.
windows
If
if
you're
you're
not
not
on
on
a
a
Windows
windows
machine,
machine
you'll
you'll
also
also
have
have
to
to
install
install
Wine
wine
HQ,
hq
so
so
just
just
a
a
heads
heads
up
up
on
on
that.
that
After
after
a
a
few
few
seconds,
seconds
it
it
creates
creates
a
a
new
new
directory
directory
in
in
the
the
root
root
of
of
the
the
project
project
with
with
the
the
build
build
for
for
Windows.
windows
So
so
you
you
can
can
see
see
all
all
the
the
different
different
Windows
windows
specific
specific
files
files
here
here
as
as
well
well
as
as
the
the
executable
executable
file.
file
So
so
now
now
I'm
i'm
switching
switching
over
over
to
to
a
a
Windows
windows
machine
machine
and
and
we'll
we'll
see
see
if
if
this
this
actually
actually
works.
works
We'll
we'll
click
click
on
on
the
the
EXE
exe
file,
file
and
and
then
then
that
that
timer
timer
comes
comes
up
up
as
as
expected
expected
and
and
works
works
just
just
like
like
it
it
did
did
on
on
Linux.
linux
Now
now
we
we
can
can
go
go
back
back
and
and
repeat
repeat
the
the
process
process
for
for
macOS.
macos
This
this
time,
time
we'll
we'll
specify
specify
the
the
platform
platform
as
as
Darwin,
darwin
and
and
you'll
you'll
see
see
we
we
get
get
another
another
build
build
file
file
here,
here
this
this
time
time
with
with
all
all
macOS
macos
specific
specific
files
files
in
in
it.
it
Now
now
I'm
i'm
jumping
jumping
over
over
to
to
my
my
Mac
mac
laptop
laptop
to
to
make
make
sure
sure
it
it
works
works
here
here
as
as
well.
well
You
you
will
will
get
get
warnings
warnings
that
that
it's
it's
an
an
unknown
unknown
developer
developer
because
because
the
the
application
application
hasn't
hasn't
been
been
signed.
signed
That's
that's
beyond
beyond
the
the
scope
scope
of
of
this
this
video,
video
but
but
I
i
may
may
cover
cover
it
it
in
in
the
the
future.
future
Other
other
than
than
a
a
few
few
presentational
presentational
differences,
differences
the
the
timer
timer
works
works
exactly
exactly
the
the
same
same
on
on
all
all
three
three
platforms.
platforms
With
with
That's
that's
it
it
for
for
Angular
angular
with
with
Electron.
electron
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe.
subscribe
And
and
if
if
you
you
wanna
wanna
support
support
the
the
channel,
channel
consider
consider
becoming
becoming
a
a
pro
pro
member
member
at
at
angularfirebase.com.
angularfirebase.com
You'll
you'll
get
get
1
1
on
on
1
1
project
project
consulting
consulting
as
as
well
well
as
as
a
a
free
free
copy
copy
of
of
my
my
Angular
angular
Firebase
firebase
survival
survival
guide.
guide
Thanks
thanks
for
for
watching,
watching
and
and
I'll
i'll
see
see
you
you
soon.
soon
success
The speaker explains how to create a timer application with Angular on multiple platforms, including Mac OS, Windows 10, and chose the Electron framework. They also provide instructions on installing the Angular CLI, creating a new app, and CD into the directory. The speaker then explains how to install the timer app on different operating systems and build a timer using TypeScript. They also provide instructions on setting variables and input values, creating a command for Electron, and giving instructions on how to access and play a sound. They also discuss setting a timer for a timer in the Angular app, setting a radius and stroke width, and giving a user input for the number of seconds remaining. Finally, they show how to rebuild the app and test it using a Windows machine, and provide a link for friends to install.
Native Desktop Apps with Angular and Electron
When you combine Angular with the Electron framework, it becomes easy to create native desktop apps that can run on any platform. In this episode, we're going to build a simple timer application with Angular, then run that app natively on Mac OS, Windows 10, and Ubuntu. With just a little bit of configuration, we'll be able to build an executable file for all all 3 of these platforms, while still being able to run the app in a web browser. A large number of high profile companies use Electron to distribute their software. It was originally developed by GitHub, with and. It's used by WordPress, Versus Code, Slack, and many others. Before we get started building the app for this video, I I just wanna point out that you can get all the source code at angularfirebase.com or on GitHub, and all the links are in the description. So the first thing we're going to do is install the Angular CLI, then create a new app by running ng new, and then we'll CD into that directory. From there, we just need to make one small change to the index HTML file in the source directory. You'll notice the base h ref points to a single slash. To make this work with Electron, we just need to add a single period in front of it. From here, we're going to install Electron into our development environment. Serum NPM install Electron flag save dev. The next step is to create a file called main JS and the root of your Angular project. Main JS is where you handle all the back end logic for an Electron app. So first, we're going to import the app and browser window objects. First, we declare your variable win that defines how the app will look when the user first opens it on their operating system. So our timer app's going to be 600 pixels by 600 pixels with a background color of white, and I also have a logo image file in the assets folder of my app. And just so you know, the underscore dir name is a Node JS variable that refers to the actual location of a file on this particular system. Then the next step is to call win load URL with the index file for our app. It's important to point out that we're telling Electron to use the index HTML file in our dist folder, not the source folder. At this point, that file doesn't actually exist, but we're going to build it here in the next step with ahead of time compilation. I also wanna point out that Electron's built with the Chromium browser engine. So if you wanna use Chrome Dev Tools during development, you can just uncomment this line and they'll appear directly in your app window. The window object has a whole bunch of different events that we can listen to. In this case, when the window is closed, we just set it equal to null and the app object also has events we can listen to. The most important one being when the app is ready. In that case, that's when we run the create window function. There There are certain situations where you wanna handle things differently based on the operating system. In macOS or Darwin as it's called, it generally doesn't close the application when you close the window. It stays running in the background. So as long as the operating system doesn't equal Darwin, we can go ahead and tell the app to quit when all the windows are closed. So So depending on the complexity of your app, you may need to listen to different events and handle things differently on a per operating system basis. The next thing we're going to do is create a custom command that will build our app in Angular with ahead of time compilation and then run Electron. Here inside package dot JSON, we'll first add the main JS file. Then we create the custom command by going down here to scripts, and we'll create one command just to run Electron, then a second command called Electron dash build that will first run the Angular production build with ahead of time compilation and then run Electron directly after that. Let's try it out from the command line. Go ahead run, npm run, electron build. After Angular's done building your production app, electron will then pull up a window on your operating system with the baseline Angular app. So that's pretty cool. We already have our own desktop app. Now we just need to turn it into something useful and then package it for execution on various operating systems. What we're going to build is just a simple timer using the Angular SVG round progress bar package, which you can install with NPM. Then we'll allow the user to set the value of the timer and have it play a sound once it reaches the end. To build the app, we'll first go into the app module, then we'll import the forms module and the round progress module that we just installed, then add both of those to the import section. From here, we can start building the timer and the app component. First time importing a few RX JS operators, which you'll see in use here in a second. Then for the timer itself, we're going to set a max value, which is the total length of the timer. And then we'll set a current value which is the current second that that timer is at. Then we're going to use TypeScript getters to handle a few issues that I came across during development. The progress bar will throw an error if the value is not a number. If that is the case, then we'll return a default floor value of 0.1. This will ensure that the max value is always a number and always greater than or equal to 0.1. Then we'll do the same basic thing here for the current value, but This time, we'll allow its floor value to go down to 0. And we can determine if the timer is finished by seeing if the current value is greater than or equal to the max value. From this point, we'll set up some event handlers to allow the user to interact with the timer. The first thing they can do is start it. And to do that, we'll use an observable interval from RxJS JS that will tick every 10th of a second. We can use the take while operator to only take values from this observable when the timer is not finished. Then we'll use the do operator to increment the current value by 1 tenth of a second each time this observable emits. Then we can start the timer by just calling subscribe on it. To finish the timer, all we have to do is set the current value to the max value. Because we set up the take while operator in the previous method, this will automatically cause the observable to complete. The last thing we need is to reset the timer and we can do that by simply setting the current value back to 0. Now we just need to put everything together in the HTML. I'm wrapping everything in a main div and then I'll set another div here that holds the progress timer and we're only gonna show this if the max value does exist. Then we can declare the round progress component and add a few input values to it. Current will be the current value getter and max will be the max value getter. Round Progress has a whole bunch of other customization options that you can check out in the documentation. For now, I'm just going to set the radius and the stroke width. When the progress timer has not finished, we wanna be able to show the user how many seconds are remaining. We can do that by just subtracting the max value from the current value, and then we'll use the angular number pipe to format this as just one digit with at least one decimal point. When the timer is finished, we want to show the user that it's done and also play a sound. So to play a sound, we can just use the HTML audio tag and point the source to an MP 3 file that I have saved in the assets directory. And also make sure to include the autoplay property. The next step is to give the user a form input where they can set the number of seconds the timer will be set for. So we'll do that with NG model and set that to the max value in the TypeScript. Whenever the user types in this input, we know Odessa resetting the timer, so we'll go ahead and call the reset method. And we'll set up a couple buttons here that are displayed conditionally based on the state of the timer, and the first one will be to start it. That is shown if the current value is less than or equal to 0. Then we'll set up a second button here to finish the timer if the user decides they want to complete it early. So that's it for the Angular app. That's all we need to create a basic timer. Let's go ahead and rebuild the app and test it out. I'm currently working on a Linux Ubuntu machine and this is the result that I get here. We can have the user enter the number of seconds and click start and the timer starts and it's animated and plays the sound. So at this point, the Angular app's ready to go, but we still need to package it to be used on native desktop applications. There's a tool called Electron Packager that will help us do this from the command line. So so we wanna have that installed globally and in our local Angular development environment. With our current configuration, we can just call Electron Packager from the root of the project, then specify the platform we wanna build for, in this case, Win 32 or Windows. If you're not on a Windows machine, you'll also have to install Wine HQ, so just a heads up on that. After a few seconds, it creates a new directory in the root of the project with the build for Windows. So you can see all the different Windows specific files here as well as the executable file. So now I'm switching over to a Windows machine and we'll see if this actually works. We'll click on the EXE file, and then that timer comes up as expected and works just like it did on Linux. Now we can go back and repeat the process for macOS. This time, we'll specify the platform as Darwin, and you'll see we get another build file here, this time with all macOS specific files in it. Now I'm jumping over to my Mac laptop to make sure it works here as well. You will get warnings that it's an unknown developer because the application hasn't been signed. That's beyond the scope of this video, but I may cover it in the future. Other than a few presentational differences, the timer works exactly the same on all three platforms. With That's it for Angular with Electron. If this video helped you, please like and subscribe. And if you wanna support the channel, consider becoming a pro member at angularfirebase.com. You'll get 1 on 1 project consulting as well as a free copy of my Angular Firebase survival guide. Thanks for watching, and I'll see you soon.
The speaker explains how to create a timer application with Angular on multiple platforms, including Mac OS, Windows 10, and chose the Electron framework. They also provide instructions on installing the Angular CLI, creating a new app, and CD into the directory. The speaker then explains how to install the timer app on different operating systems and build a timer using TypeScript. They also provide instructions on setting variables and input values, creating a command for Electron, and giving instructions on how to access and play a sound. They also discuss setting a timer for a timer in the Angular app, setting a radius and stroke width, and giving a user input for the number of seconds remaining. Finally, they show how to rebuild the app and test it using a Windows machine, and provide a link for friends to install.