Electron with Angular 2 and Angular 2 CLI


In this tutorial ,we are going to build a starter project which shows you how you can use Electron with Angular 2 to build Desktop applications .The final project starter will be available from GitHub so feel free to clone it and start using it to build your Electron app with Angular 2 without reinventing the wheel .

But if you want to go through the process step by step ,lets get started .

The first thing you need to do is installing the Angular 2 CLI which is a nice tool inspired from ember-cli that allows you to quickly scaffold a new Angular 2 based project and also assists you during the development of your project by providing commands to scaffold different Angular 2 artifacts such as components ,routes etc .and provides you with a development server .So oepn up your terminal/command prompt and enter the following

npm install -g angular-cli

Make sure you have Node.js and NPM installed on your system but since your are working with Electron then you’ll definitely have them already installed .

Next we need to scaffold a new Angular 2 project

ng new electron-angular2-starter

cd electron-angular2-starter

ng serve

If you have no problem you should be able to visit your app from your browser by going to http://localhost:4200 .

You’ll have a nice “app works!” message displayed .

Now just go back to your terminal and enter CTRL+C to terminate the development server and then start integrating our Angular 2 project with Electron .

But before we continue you need to have Electron installed

npm install -g electron

Inside electron-angular2-starter create a folder with name ‘electron’

mkdir electron
touch main.js package.json

open up package.json and copy the following

{
  "name": "electron-angular2-starter",
  "version": "0.1",
  "main": "main.js"
}

Next open up main.js and copy the following code

const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
let mainWindow

function createWindow () {

  mainWindow = new BrowserWindow({width: 800, height: 600})

  mainWindow.loadURL(`file://${__dirname}/index.html`)

  mainWindow.webContents.openDevTools()

  mainWindow.on('closed', function () {
    mainWindow = null
  })
}
app.on('ready', createWindow)

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  if (mainWindow === null) {
    createWindow()
  }
})

Next go to your app src/index.html file and modify this line

<base href="/">

to

<base href="./">			  

Next we need to create some npm scripts which will make the process easy for us .

So open up your Angular 2 project package.json (exists on the root of your project folder )

Under scripts add these 3 scripts

"build": "ng build && cp -R src/public dist/public",
"postbuild": "cp -a electron/. dist",
"electron": "npm run postbuild && electron dist" 

For windows –

 

“build-electron”: “ng build –base-href . && copy src\\electron\\* dist”,
“electron”: “npm run build-electron && electron dist”

 

Now, let’s create “Package.json” for electron app

 

srs/electron –> package.json

 

{
  “name”: “angular2-electron-cli”,
  “version”: “0.1.0”,
  “main”: “main.js”
}

 

That’s it you can now build and run your project with

npm run build 
npm run electron

You should have your Electron app started with the “app works!” message just like in the browser .

Electron with Angular 2 and Angular 2 CLI

Conclusion

This tutorial comes to end .You can also find the complete project on GitHub .I hope this post was helpful for you and see you in next tutorials .

Angular 2 Errors


If you’ve begun to try out Angular 2, you might have encountered some pretty baffling errors. I know I sure did…

It always feels a bit frustrating to start fresh in a new library or language (or both, in this case) – all your previous experience goes out the window, and you’re back to making beginner mistakes and hitting confusing errors.

Here’s a list of some errors I ran into, my best guesses as to what caused them, and how I fixed them.

The relevance of these errors may (hopefully) decay over time – these ones were encountered in Angular 2 Beta 0 or a late Alpha version.

General Advice
  • If you get an error in the console, scroll to the top! The later errors are not very helpful. Look at the first one.

  • Some of these can be really tricky to track down. As a general strategy, make small changes and test as you go. At least that way it’ll be easier to figure out which bit of code broke (like when the stack traces are not so helpful).

  • Styles don’t seem to cascade to subcomponents by default… (this can be controlled by the encapsulation property of the @Component decorator. See the docs for more info.)

Errors, Errors, Everywhere…
EXCEPTION: TypeError: allStyles.map is not a function

‘styles’ needs to be an array of strings, not a single string.


EXCEPTION: Component ‘Something’ cannot have both ‘styles’ and ‘@View’ set at the same time”

I provided a @View decorator, and also put a ‘styles’ key in the @Component – this doesn’t work. Put ‘styles’ in the object passed to @View.

From Igor: Put everything in @Component and don’t use @View – it might be used in the future but it’s not needed right now.


EXCEPTION: Unexpected directive value ‘undefined’ on the View of component ‘AppComponent’

I defined a component as class Something when it should’ve beenexport class Something – forgot to export it from the file it was defined in. The importdidn’t fail, but the directives: [Something] did…

From Igor: This is a problem with polyfilling ES Modules. Something outside of Angular, and in fact a well known issue with all ES module polyfills. Once we have a native implementation you will get an error, but in the meantime if you use the TypeScript compiler you’ll get a compile time error.


EXCEPTION: No provider for UserList! (UserCmp -> UserList)

I forgot to add UserList to the viewProviders array in the parent view. The fix was@Component({viewProviders: [UserList]})


EXCEPTION: Cannot resolve all parameters for UserList(?). Make sure they all have valid type or annotations.

I got this when I was trying to inject the Http service.

For WHY this happens, see Injecting services in services in Angular 2.

There are 2 different ways to fix this:

Way #1 (preferred): Put @Injectable() above the class (don’t forget the parens!)

This is the way to go if you’re using TypeScript.

@Injectable()
constructor(public http: Http)

Way #2: Put @Inject(Http) before the param that should be injected with Http:

From Igor: If using TypeScript you should almost never use @Inject because@Injectable is less verbose and easier to understand. @Inject should primarily used by ES6 users that don’t use TypeScript.

// This doesn't work :(
constructor(public http: Http)

// This works :)
constructor(@Inject(Http) public http: Http)

EXCEPTION: Error during instantiation of UsersCmp

TypeError: this.http.get(…).map is not a function

I thought TypeScript was supposed to save us from TypeErrors!

Removing .map fixed the error… but it seems like it should work. I don’t know too much about this new Http service so, maybe the request failed?

Nope: You have to explicitly include the map operator from RxJS. Awesome. Add this line to app.ts (or whatever your main file is):

import 'rxjs/add/operator/map';

From Igor: This is an intentional trade off we made as a part of larger effort to curb the uncontrolled increase in payload size. The current behavior sucks. The right fix is to get the pipe operator through TC39 and have it implemented in TypeScript and Babel.


EXCEPTION: Cannot find a differ supporting object ‘[object Object]’ in [users in UsersCmp@2:14]

I’m pretty sure this means that a non-array was passed to ngFor. Make sure the thing you pass is an array.


Compile error: “Type ‘Observable’ is not assignable to type ‘any[]’.”

Got this when I was trying to return this.http.get() as any[] – it’s not an array, so that doesn’t work. Changing to any works better (or the actual type, for that matter).


and my personal favorite:

EXCEPTION: [object Object]

WTF? Caused by:

return this.http.get('/users/list')
    .map(res => res.json())
    .subscribe(users => this.users = users); // this line. Why?

Without an error handler, a 404 response causes an exception.

Call subscribe this way instead:

.subscribe(
	res => res.text(), 						// success
	err => handleErr(err),				// error
	() => console.log('done'));		// done

Angular 2.0 Architechture


Starting new series – Learning Angular 2.0 on My Github –

https://github.com/bapatel1/Learning-Angular-2.0

##### angular 2.0 building blocks
– Module
– Component
– Template
– Metadata
– Data Binding
– Service
– Directive
– Dependency Injection

##### 1. Module
– Angular apps are modular and so in general we assemble our application from many modules. A typical module is a cohesive block of code dedicated to a single purpose.
– A module exports something of value in that code, typically one thing such as a class.
– Some modules are libraries of other modules.
– Angular itself ships as a collection of library modules called “barrels”. Each Angular library is actually a public facade over several logically related private modules.
– The angular2/core library is the primary Angular library module from which we get most of what we need.
– There are other important Angular library modules too such as angular2/common, angular2/router, and angular2/http.
– e.g import {Component} from ‘angular2/core’;
– The key take aways are:
    – Angular apps are composed of modules.
    – Modules export things — classes, function, values — that other modules import.
    – We prefer to write our application as a collection of modules, each module exporting one thing.
    – The first module we write will most likely export a component.

##### 2. Component
– Perhaps the first module we meet is a module that exports a component class. The component is one of the basic Angular blocks, we write a lot of them
– Most applications have an AppComponent. By convention, we’ll find it in a file named app.component.ts
– Components are the collection of templates, styles, selector configurations etc.
– Angular creates, updates, and destroys components as the user moves through the application.
– Each components is a typescript class which again includes variable, functions, prop declaration etc.

##### 3. Template
– We define a Component’s view with its companion template. A template is a form of HTML that tells Angular how to render the Component.
– A template looks like regular HTML much of the time … and then it gets a bit strange.
– Template will have all diff type databinding and html DOM information.

##### 4. Metadata
– Metadata tells Angular how to process a class.
– e.g
“`
@Component({
  selector:    ‘hero-list’,
  templateUrl: ‘app/hero-list.component.html’,
  directives:  [HeroDetailComponent],
  providers:   [HeroService]
})
“`
Here we see the @Component decorator which (no surprise) identifies the class immediately below it as a Component class.

selector – a css selector that tells Angular to create and insert an instance of this component where it finds a <hero-list> tag in parent HTML. If the template of the application shell (a Component) contained

templateUrl – the address of this component’s template

directives – an array of the Components or Directives that this template requires.

providers – an array of dependency injection providers for services that the component requires. This is one way to tell Angular that our component’s constructor requires a HeroService so it can get the list of heroes to display.

##### 5. Data Binding
– There are four forms of data binding syntax.
– Each form has a direction – to the DOM, from the DOM, or in both directions.
– We can group all bindings into three categories by the direction in which data flows. Each category has its distinctive syntax:
    – One Way (from component -> View)   – Binds Property, Attributes, Class, Style.
    “`
    {{expression}}
    [target] = “expression”
    bind-target = “expression”
    “`
    – One Way (from View -> Component) – Binds Events
    “`
    (target) = “Statement”
    on-target=”statement”
    “`
    – Two way binding
    “`
    [(target)] = “expression”
    bindon-target =”expression”
    “`
For More Details – https://angular.io/docs/ts/latest/guide/template-syntax.html

##### 6. Directive
– Our Angular templates are dynamic. When Angular renders them, it transforms the DOM according to the instructions given by a directive.
– A directive is a class with directive metadata. In TypeScript we’d apply the @Directive decorator to attach metadata to the class.
– While the component is technically a directive, it is so distinctive and central to Angular applications that we chose to separate the component from the directive in our architectural overview.
– There are two other kinds of directives as well that we call “structural” and “attribute” directives.
– Structural directives alter layout by adding, removing, and replacing elements in DOM.
    – e.g *ngFor , *ngIf etc.
– Attribute directives alter the appearance or behavior of an existing element. In templates they look like regular HTML attributes, hence the name.
    – e.g. [(ngModel)]

##### 7. Service
– “Service” is a broad category encompassing any value, function or feature that our application needs.
– Almost anything can be a service. A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.
    – Examples include:
        – logging service
        – data service
        – message bus
        – tax calculator
        – application configuration
– Most common usage of services are to bind components with Databases or any similar part which delivers data to components and that way, components will be independent from Data Layer.

##### 8. DI (Dependency Injection)
– “Dependency Injection” is a way to supply a new instance of a class with the fully-formed dependencies it requires. Most dependencies are services. Angular uses dependency injection to provide new components with the services they need.
– dependency injection is wired into the framework and used everywhere.
– the Injector is the main mechanism.
    – an injector maintains a container of service instances that it created.
    – an injector can create a new service instance using a provider.
– a provider is a recipe for creating a service.
– we register providers with injectors.

##### 9. Other Stuff
– Animation: A forthcoming animation library makes it easy for developers to animate component behavior without deep knowledge of animation techniques or css.
– Bootstrapping: A method to configure and launch the root application component.
– Change Detection: Learn how Angular decides that a component property value has changed and when to update the screen
– Zones: Change Detection uses zones to intercept asynchronous activity and run its change detection strategies.
– Events: The DOM raises events. So can components and services.
– Router: With the Component Router service, users can navigate a multi-screen application in a familiar web browsing style using URLs.
– Forms: Support complex data entry scenarios with HTML-based validation and dirty checking.
– Http: Communicate with a server to get data, save data, and invoke server-side actions with this Angular HTTP client.
– Lifecycle Hooks: We can tap into key moments in the lifetime of a component, from its creation to its destruction, by implementing the “Lifecycle Hook” interfaces.
– Pipes: Services that transform values for display. We can put pipes in our templates to improve the user experience.
    “`
    price | currency:’USD’:true
    “`
– Testing: Angular provides a testing library for “unit testing” our application parts as they interact with the Angular framework.

### Author
Bhavin Patel

Happy Coding Smile