{"id":530,"date":"2017-01-16T14:30:49","date_gmt":"2017-01-16T14:30:49","guid":{"rendered":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/?p=530"},"modified":"2020-09-10T14:09:05","modified_gmt":"2020-09-10T14:09:05","slug":"building-a-file-explorer-with-angular-2-and-electron","status":"publish","type":"post","link":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/","title":{"rendered":"Building a file explorer with Angular 2 and Electron"},"content":{"rendered":"\n<p>After having a deeper look into the project environment and the basic anatomy of an Angular-CLI-Electron project in the <a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-cross-platform-desktop-apps-with-angular-2-and-electron\/\" target=\"_blank\" rel=\"noreferrer noopener\">last article<\/a> we now want to build a simple application using the Node.js as well as the Electron API to get a deeper insight into the possibilities of such an app and to gain more familiarity with the environment. Our example will be a basic file explorer which can browse through the directories of our file system and open files in their associated default program. It should also provide a keyboard shortcut to move up in the file tree.<\/p>\n\n\n\n<p>You can find the sample project of this article in the <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/DevWurm\/electron-explorer\" target=\"_blank\">electron-explorer GitHub Repo<\/a>. If you want to have a look at a bigger sample project, you could use <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/Electron-Microscope\/electron-microscope\" target=\"_blank\">Electron-Microscope.<\/a><\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Setting up the project<\/h2>\n\n\n\n<p>Commit: <a href=\"https:\/\/github.com\/DevWurm\/electron-explorer\/commit\/7ecab6c35124a6039437a8256e29bda1f7911bb4\" target=\"_blank\" rel=\"noreferrer noopener\">7ecab6c<\/a><\/p>\n\n\n\n<p>To set up the project you can either follow the steps in the <a href=\"https:\/\/sogehtsoftware.de\/2016\/12\/building-cross-platform-desktop-apps-with-angular-2-and-electron\/\" target=\"_blank\" rel=\"noreferrer noopener\">last article<\/a> or you use the <a href=\"https:\/\/github.com\/DevWurm\/angular-2-electron-seed\" target=\"_blank\" rel=\"noreferrer noopener\">angular-2-electron-seed project<\/a>. For the purpose of this article I will do the latter. So after cloning the seed with<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone git@github.com:DevWurm\/angular-2-electron-seed.git .\/electron-explorer<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>we change into the project directory (<code>electron-explorer<\/code>) and open the <code>package.json<\/code> where we adapt the <code>name<\/code> field to match our project name <code>electron-explorer<\/code>. After this we have to run<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>to install the required dependencies.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Building the application<\/h2>\n\n\n\n<p>After setting up the project we can run <code>npm run start<\/code> to have a look at the current state.<\/p>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"316\" src=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_2-600x316.png\" alt=\"Screenshot Angular 2 \u2013 Electron seed default app\" class=\"wp-image-636\" srcset=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_2-600x316.png 600w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_2-1024x539.png 1024w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_2-768x404.png 768w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_2-1536x809.png 1536w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_2-2048x1078.png 2048w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_2-640x337.png 640w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_2-1200x632.png 1200w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_2-1920x1011.png 1920w\" sizes=\"auto, (max-width: 639px) 98vw, (max-width: 1199px) 64vw, 600px\" \/><figcaption><em>Figure 1: Angular 2 \u2013 Electron seed default app<\/em><\/figcaption><\/figure>\n\n\n\n<p>We can see the default app of the Angular-CLI inside of Electron.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Creating the file list<\/h3>\n\n\n\n<p>Commit: <a href=\"https:\/\/github.com\/DevWurm\/electron-explorer\/commit\/767575867720eace2e26770fe6fafd4eb674bab8\" target=\"_blank\" rel=\"noreferrer noopener\">7675758<\/a><\/p>\n\n\n\n<p>To build a simple file list view we just need a component which displays a list of all files in the current directory. All directory entries are displayed as links, which change the currently displayed directory or open the selected file. For the purpose of simplicity we store the currently active directory in the component itself. We fetch all available files in the active directory via the Node.js core module <a href=\"https:\/\/nodejs.org\/api\/fs.html\" target=\"_blank\" rel=\"noreferrer noopener\"><code>fs<\/code><\/a> and display the entries via <a href=\"https:\/\/angular.io\/docs\/ts\/latest\/api\/common\/index\/NgFor-directive.html\" target=\"_blank\" rel=\"noreferrer noopener\"><code>NgFor<\/code><\/a>.<\/p>\n\n\n\n<p>So let\u2019s start with creating the component. To do so, change into the directory <code>src\/app<\/code> and create a new component via the scaffolding command of the Angular-CLI by running<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>ng generate component files<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This creates a new component called <code>FilesComponent<\/code> which is bound to the HTML tag &lt;app-files&gt;&lt;\/app-files&gt;. The generated component already contains a basic component class in the file <code>src\/app\/files\/files.component.ts<\/code>, decorated with the correctly configured <code>@Component<\/code> decorator. To implement our component we have to include the necessary file system functions from the Node.js core module <code>fs<\/code> and some other functions from the Node core via<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>    import { readdir, stat } from 'fs';\n    import { resolve } from 'path';\n    &#91;...]<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>After this we implement our properties for storing the current directory, as well as all file system elements in this directory. These properties are always updated in sync via the <code>changeDir<\/code> method when the user clicks on a directory entry. When a regular file is clicked we want to open it in the systems default application, rather than changing the directory. This can be implemented the following way:<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>    &#91;...]\n    @Component({\n      selector: 'app-files',\n      templateUrl: '.\/files.component.html',\n      styleUrls: &#91;'.\/files.component.css']\n    })\n    export class FilesComponent implements OnInit {\n      private currentPath: string = process.cwd();\n      private entries: Array&lt;string>;\n      constructor() {\n        this.updateEntries();\n      }\n      ngOnInit() {}\n      private updateEntries() {\n        readdir(this.currentPath, (err: Error, files: &#91;string]) => {\n          if (err) {\n            console.error(err);\n          }\n          this.entries = &#91;'..\/'].concat(files);\n        });\n      }\n      private changeDir(newDir: string) {\n        const targetPath = resolve(this.currentPath, newDir);\n        stat(targetPath, (err, stats) => {\n          if (err) {\n            console.error(err);\n          }\n          if (stats.isFile()) {\n            this.openFile(targetPath);\n          } else if (stats.isDirectory()) {\n            this.currentPath = targetPath;\n            this.updateEntries();\n          } else {\n            console.error(new Error(`Unknown file system object: ${targetPath}`));\n          }\n        });\n      }\n      private openFile(path: string) {\n        \/\/ TODO: Implement file opening\n        return\n      }\n    }<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To represent these information in our view we list all the file system entries via <code>NgFor<\/code> and handle the user interaction via a <code>click<\/code> binding by inserting the following into <code>src\/app\/files\/files.component.html<\/code>:<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>    &lt;ul *ngFor=\"let entry of entries\">\n      &lt;li>&lt;a (click)=\"changeDir(entry)\">{{entry}}&lt;\/a>&lt;\/li>\n    &lt;\/ul><\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>During development you can live-test and debug your app by running <code>npm run start<\/code> and you can create unit tests by adding test cases in the <code>&lt;component&gt;.spec.ts<\/code> file of your component and run them via <code>npm run test<\/code>.<\/p>\n\n\n\n<p>After adding the directive to the main view (it is added to the module automatically by the CLI), by inserting<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>    &lt;app-files>&lt;\/app-files><\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>at the end of <code>src\/app.component.html<\/code> and setting the correct application title in <code>src\/app.component.ts<\/code> we can have a first look at our file list.<\/p>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"316\" src=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3-600x316.png\" alt=\"Screenshot Electron-Explorer file list\" class=\"wp-image-634\" srcset=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3-600x316.png 600w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3-1024x539.png 1024w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3-768x404.png 768w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3-1536x809.png 1536w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3-2048x1078.png 2048w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3-640x337.png 640w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3-1200x632.png 1200w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3-1920x1011.png 1920w\" sizes=\"auto, (max-width: 639px) 98vw, (max-width: 1199px) 64vw, 600px\" \/><figcaption><em>Figure 2: Electron-Explorer file list<\/em><\/figcaption><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Opening files<\/h3>\n\n\n\n<p>Commit: <a href=\"https:\/\/github.com\/DevWurm\/electron-explorer\/commit\/b93f98f884db471558a99a8106aee5c8426d2674\" target=\"_blank\" rel=\"noreferrer noopener\">b93f98f<\/a><\/p>\n\n\n\n<p>If the user clicks on a file, we want to open the file in the default program associated with the file type on the users system. Fortunately Electron provides this feature out of the box with the function <a href=\"http:\/\/electron.atom.io\/docs\/api\/shell\/#shellopenitemfullpath\" target=\"_blank\" rel=\"noreferrer noopener\"><code>shell.openItem<\/code><\/a>.<br>Lets include the <code>shell<\/code> object by adding<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>    import { shell } from 'electron';<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>to the top of <code>src\/app\/files\/files.component.ts<\/code> and implement our <code>openFile<\/code> method by using the provided helper function:<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>    &#91;...]\n      private openFile(path: string) {\n        shell.openItem(path);\n      }\n    &#91;...]<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>When clicking on a file entry in our file list our app now opens it in the associated default application or prompts for action.<\/p>\n\n\n\n<figure class=\"wp-block-image size-medium\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"315\" src=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_4-600x315.png\" alt=\"Screenshot Electron-Explorer when opening a file\" class=\"wp-image-635\" srcset=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_4-600x315.png 600w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_4-1024x538.png 1024w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_4-768x403.png 768w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_4-1536x807.png 1536w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_4-2048x1076.png 2048w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_4-640x336.png 640w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_4-1200x630.png 1200w, https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_4-1920x1009.png 1920w\" sizes=\"auto, (max-width: 639px) 98vw, (max-width: 1199px) 64vw, 600px\" \/><figcaption><em>Figure 3: Electron-Explorer when opening a file<\/em><\/figcaption><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Using keyboard shortcuts<\/h3>\n\n\n\n<p>Commit: <a href=\"https:\/\/github.com\/DevWurm\/electron-explorer\/commit\/61b07350b44a24a7e6fc8f95a687632a3dba92eb\" target=\"_blank\" rel=\"noreferrer noopener\">61b0735<\/a><\/p>\n\n\n\n<p>Implementing keyboard shortcuts is a bit harder because of Electrons architecture. Electron allows the registration of keyboard shortcuts in the <code>MainProcess<\/code> only, while our application gets executed in a <code>RendererProcess<\/code>. Because we want to handle the keyboard shortcuts in our application we have to use Inter-process communication (IPC) to communicate between the <code>MainProcess<\/code> and a <code>RendererProcess<\/code>. Fortunately Electron provides an easy event-based IPC mechanism to achieve this. In the Electron IPC mechanism the <code>MainProcess<\/code> doesn\u2019t know how to send information to a <code>RendererProcess<\/code> until it gets a reference to corresponding IPC endpoint through an incoming message. Therefor our application has to request the keyboard shortcut in the <code>RendererProcess<\/code> using <a href=\"http:\/\/electron.atom.io\/docs\/api\/ipc-renderer\/#ipcrenderersendchannel-arg1-arg2-\" target=\"_blank\" rel=\"noreferrer noopener\"><code>ipcRenderer.send<\/code><\/a>:<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>    import { &#91;...], ipcRenderer } from 'electron';\n    &#91;...]\n    class FilesComponent implements OnInit {\n      &#91;...]\n      ngOnInit() {\n        ipcRenderer.send(\"request-keyboard-shortcut\", \"Backspace\");\n      }\n      &#91;...]\n    }<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Our files component now sends a message to our <code>MainProcess<\/code> containing the desired keyboard shortcut. Our <code>MainProcess<\/code> now listens for the <code>request-keyboard-shortcut<\/code> message, subscribes to the provided shortcut via <a href=\"https:\/\/github.com\/electron\/electron\/blob\/master\/docs\/api\/global-shortcut.md#globalshortcutregisteraccelerator-callback\" target=\"_blank\" rel=\"noreferrer noopener\"><code>globalShortcut.register<\/code><\/a> and notifies our component via <a href=\"http:\/\/electron.atom.io\/docs\/api\/ipc-main\/#eventsender\" target=\"_blank\" rel=\"noreferrer noopener\"><code>event.sender.send<\/code><\/a>. To implement this behavior, we edit <code>src\/entry.js<\/code>:<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>    const {&#91;...], ipcMain, globalShortcut} = require('electron')\n    &#91;...]\n    ipcMain.on('request-keyboard-shortcut', (event, shortcut) => {\n      globalShortcut.register(shortcut, () => {\n        event.sender.send(`keyboard-shortcut-${shortcut}`);\n      });\n    })\n    &#91;...]<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Make sure to make the corresponding changes in <code>src\/entry.live.js<\/code> to enable the feature when running your app with <code>npm run start<\/code>, too. Now we can listen for the corresponding <code>keyboard-shortcut-Backspace<\/code> event in our component and move upwards in the file tree:<\/p>\n\n\n\n<div style=\"height:40px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>    &#91;...]\n    class FilesComponent implements OnInit {\n      &#91;...]\n      ngOnInit() {\n        &#91;...]\n        ipcRenderer.on('keyboard-shortcut-Backspace', () => {\n            this.changeDir('..');\n        })\n      }\n      &#91;...]\n    }<\/code><\/pre>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now our app reacts to key presses on <code>Backspace<\/code> and moves to the parent directory. Great!<\/p>\n\n\n\n<p>With only little code we created our own small file explorer which already integrates itself into the surrounding system and there are a lot more APIs we could use to achieve more system integration and features!<\/p>\n\n\n\n<p>As we have seen Electron can be a great tool to develop full-featured desktop applications especially when combined with a modern GUI application framework like Angular 2.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article we go over the process of building a simple file explorer using Angular 2 and Electron.<\/p>\n","protected":false},"author":68,"featured_media":703,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","footnotes":""},"categories":[8],"tags":[270,271,272,258,259,260,261,262,263,264,265,266,267,268,269],"topics":[],"class_list":["post-530","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web","tag-hybrid-apps","tag-cross-platform","tag-node-js","tag-cli","tag-angular-cli","tag-angular-2","tag-angular","tag-file-explorer","tag-electron","tag-electron-explorer","tag-explorer","tag-file","tag-electron-explorer-2","tag-web-development","tag-desktop-applications"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Building a file explorer with Angular 2 and ... - ZEISS Digital Innovation Blog<\/title>\n<meta name=\"description\" content=\"In this article we go over the process of building a simple file explorer using Angular 2 and Electron, including an example with a basic file explorer.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a file explorer with Angular 2 and ... - ZEISS Digital Innovation Blog\" \/>\n<meta property=\"og:description\" content=\"In this article we go over the process of building a simple file explorer using Angular 2 and Electron, including an example with a basic file explorer.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/\" \/>\n<meta property=\"og:site_name\" content=\"Digital Innovation Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-01-16T14:30:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-09-10T14:09:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3_fi.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1204\" \/>\n\t<meta property=\"og:image:height\" content=\"677\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Leo Lindhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Leo Lindhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/\",\"name\":\"Building a file explorer with Angular 2 and ... - ZEISS Digital Innovation Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3_fi.png\",\"datePublished\":\"2017-01-16T14:30:49+00:00\",\"dateModified\":\"2020-09-10T14:09:05+00:00\",\"author\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/c356f48797f27ea4dae06817bc32afae\"},\"description\":\"In this article we go over the process of building a simple file explorer using Angular 2 and Electron, including an example with a basic file explorer.\",\"breadcrumb\":{\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#primaryimage\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3_fi.png\",\"contentUrl\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3_fi.png\",\"width\":1204,\"height\":677},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a file explorer with Angular 2 and Electron\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/\",\"name\":\"Digital Innovation Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/c356f48797f27ea4dae06817bc32afae\",\"name\":\"Leo Lindhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2024\/06\/Lindhorst_Leo_Profilbild_300x300px-150x150.jpg\",\"contentUrl\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2024\/06\/Lindhorst_Leo_Profilbild_300x300px-150x150.jpg\",\"caption\":\"Leo Lindhorst\"},\"description\":\"Leo Lindhorst is a Management Consultant with ZEISS Digital Innovation. He is working together with his clients in the healthcare, medical technology and pharmaceuticals industries, to define the vision for their digital product landscape, consults them on the best technological and organizational solution for their ambitions and supports them in setting up and leading their software development program.Together with the teams of ZEISS Digital Innovation, Leo is ensuring the delivery of the client\u2019s innovative digital health solutions from design, over implementation to successful operations in the field.\",\"url\":\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/author\/enleolindhorst\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building a file explorer with Angular 2 and ... - ZEISS Digital Innovation Blog","description":"In this article we go over the process of building a simple file explorer using Angular 2 and Electron, including an example with a basic file explorer.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/","og_locale":"en_US","og_type":"article","og_title":"Building a file explorer with Angular 2 and ... - ZEISS Digital Innovation Blog","og_description":"In this article we go over the process of building a simple file explorer using Angular 2 and Electron, including an example with a basic file explorer.","og_url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/","og_site_name":"Digital Innovation Blog","article_published_time":"2017-01-16T14:30:49+00:00","article_modified_time":"2020-09-10T14:09:05+00:00","og_image":[{"width":1204,"height":677,"url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3_fi.png","type":"image\/png"}],"author":"Leo Lindhorst","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Leo Lindhorst","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/","name":"Building a file explorer with Angular 2 and ... - ZEISS Digital Innovation Blog","isPartOf":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#primaryimage"},"image":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#primaryimage"},"thumbnailUrl":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3_fi.png","datePublished":"2017-01-16T14:30:49+00:00","dateModified":"2020-09-10T14:09:05+00:00","author":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/c356f48797f27ea4dae06817bc32afae"},"description":"In this article we go over the process of building a simple file explorer using Angular 2 and Electron, including an example with a basic file explorer.","breadcrumb":{"@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#primaryimage","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3_fi.png","contentUrl":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3_fi.png","width":1204,"height":677},{"@type":"BreadcrumbList","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/building-a-file-explorer-with-angular-2-and-electron\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/"},{"@type":"ListItem","position":2,"name":"Building a file explorer with Angular 2 and Electron"}]},{"@type":"WebSite","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#website","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/","name":"Digital Innovation Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/c356f48797f27ea4dae06817bc32afae","name":"Leo Lindhorst","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/#\/schema\/person\/image\/","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2024\/06\/Lindhorst_Leo_Profilbild_300x300px-150x150.jpg","contentUrl":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2024\/06\/Lindhorst_Leo_Profilbild_300x300px-150x150.jpg","caption":"Leo Lindhorst"},"description":"Leo Lindhorst is a Management Consultant with ZEISS Digital Innovation. He is working together with his clients in the healthcare, medical technology and pharmaceuticals industries, to define the vision for their digital product landscape, consults them on the best technological and organizational solution for their ambitions and supports them in setting up and leading their software development program.Together with the teams of ZEISS Digital Innovation, Leo is ensuring the delivery of the client\u2019s innovative digital health solutions from design, over implementation to successful operations in the field.","url":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/author\/enleolindhorst\/"}]}},"author_meta":{"display_name":"Leo Lindhorst","author_link":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/author\/enleolindhorst\/"},"featured_img":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-content\/uploads\/sites\/3\/2020\/06\/201701_Building_a_file_explorer_3_fi-600x337.png","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Web<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">Web<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Hybrid Apps<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Cross platform<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Node.js<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">CLI<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Angular-CLI<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Angular 2<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Angular<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">File Explorer<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Electron<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">electron-explorer<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">explorer<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">file<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">electron explorer<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Web development<\/a>","<a href=\"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/category\/web\/\" class=\"advgb-post-tax-term\">Desktop Applications<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">Hybrid Apps<\/span>","<span class=\"advgb-post-tax-term\">Cross platform<\/span>","<span class=\"advgb-post-tax-term\">Node.js<\/span>","<span class=\"advgb-post-tax-term\">CLI<\/span>","<span class=\"advgb-post-tax-term\">Angular-CLI<\/span>","<span class=\"advgb-post-tax-term\">Angular 2<\/span>","<span class=\"advgb-post-tax-term\">Angular<\/span>","<span class=\"advgb-post-tax-term\">File Explorer<\/span>","<span class=\"advgb-post-tax-term\">Electron<\/span>","<span class=\"advgb-post-tax-term\">electron-explorer<\/span>","<span class=\"advgb-post-tax-term\">explorer<\/span>","<span class=\"advgb-post-tax-term\">file<\/span>","<span class=\"advgb-post-tax-term\">electron explorer<\/span>","<span class=\"advgb-post-tax-term\">Web development<\/span>","<span class=\"advgb-post-tax-term\">Desktop Applications<\/span>"]}},"comment_count":"0","relative_dates":{"created":"Posted 9 years ago","modified":"Updated 6 years ago"},"absolute_dates":{"created":"Posted on January 16, 2017","modified":"Updated on September 10, 2020"},"absolute_dates_time":{"created":"Posted on January 16, 2017 2:30 pm","modified":"Updated on September 10, 2020 2:09 pm"},"featured_img_caption":"","series_order":"","_links":{"self":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts\/530","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/users\/68"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/comments?post=530"}],"version-history":[{"count":6,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts\/530\/revisions"}],"predecessor-version":[{"id":1030,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/posts\/530\/revisions\/1030"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/media\/703"}],"wp:attachment":[{"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/media?parent=530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/categories?post=530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/tags?post=530"},{"taxonomy":"topics","embeddable":true,"href":"https:\/\/blogs.zeiss.com\/digital-innovation\/en\/wp-json\/wp\/v2\/topics?post=530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}