Angular + Cordova
Tags: angular, angular2, cordova
Published: 2019-12-31 21:01:25

---
title: Angular + Cordova
published: true
date: 2018-07-21 00:00:00 UTC
tags: angular,angular2,cordova
canonical_url: https://jspizziri.com/blog/angular-cordova/
---

 ![](https://jspizziri.com/images/banner-angularjs.jpg)

Lets port a new angular project to Cordova without using Ionic or NativeScript. **Why?** Because those frameworks can sometimes be too opinionated and constraining. By the end of this article, you'll have a functioning angular/cordova project which will be as loosely coupled with Cordova as possible. You'll be able to conform to the angular style conventions, and install whatever plugins, frameworks, or libraries you desire. (e.g. bootstrap, ng-bootstrap, pug, etc.)

First, I'd like to [give credit to this post](https://www.becompany.ch/en/blog/2016/10/19/creating-apache-cordova-app-with-angular2) as it's what got me heading in the right direction however I found it to be a little incomplete.

You can find the demo source code [here](https://github.com/jspizziri/hello-cordova)

* * *

**Ok. Lets Get Started.**

* * *

### 1. Setup A Vanilla Angular App

First we're going to create a vanilla angular 6 project called `hello-cordova` with the following command: `ng new hello-cordova`.

Some things you may want to do at this point would be to install and configure things like `bootstrap` & `ng-bootstrap` or any other angular library's you're interested in working with.

### 2. Basic Cordova Setup

Now that we have a basic angular app running with `npm start` we're going to create some basic scaffolding to setup our cordova build.

First let's make sure we have the cordova cli installed: `npm install -g cordova`.

Now let's create a basic cordova app. We're going to create the cordova app in a `cordova` subdirectory and give it an id of `com.hellocordova.www` and a name of `Hello Cordova`.

```
cordova create cordova com.hellocordova.www "Hello Cordova"
```

Now let's add some git tracking files to ignore some build files and keep directories:

```
touch cordova/.gitignore
touch cordova/www/.gitkeep
```

And add the following to `cordova/.gitignore`:

```
node_modules
www/*
!www/.gitkeep
platforms
plugins
```

Finally, let's add the iOS platform. To add platforms (and plugins) we'll want to make sure we're in the `cordova` directory and then run the following:

```
cordova platform add ios
```

### 3. Add Scripts

In the **root** directory of our project (not the one in the `cordova` folder), lets add some basic scripts to the `package.json` to automate a few things:

```
"clean": "rm -rf dist cordova/www/* && touch cordova/www/.gitkeep",
"build:cordova": "npm run clean && ng build --base-href=. --output-path=cordova/www",
"cordova:prepare": "cd cordova && rm -rf platforms plugins node_modules && npm ci && cordova prepare && cd ..",
"cordova:build:ios": "npm run build:cordova && cd cordova && cordova build ios && cd ..",
"cordova:emulate:ios": "npm run cordova:build:ios && cd cordova && cordova emulate ios && cd ..",
"open:xcode": "open $(find ./cordova/platforms/ios -name '*.xcworkspace')"
```

We're also going to modify the `build` script to be the following:

```
"build": "ng build --base-href=/"
```

This will give you the following utilities:

- `npm run cordova:prepare` - Other devs should be able to run this script to initialize the Cordova app in their environment.
- `npm run open:xcode` - Run this to easily open the project in Xcode
- `npm run cordova:build:ios` - Run this to rebuild the iOS project
- `npm run cordova:emulate:ios` - Run this to run an iOS emulator of the project

### 4. Performance Improvements (400ms delay)

Yes. Now let's remove [the infamous 400ms delay](https://stackoverflow.com/questions/39902055/web-app-feels-less-responsive-when-added-to-iphones-home-screen) that iOS defaults on webview clicks. We're going to add [FastClick.js](https://github.com/ftlabs/fastclick) to our angular app.

```
$ npm i fastclick
```

Add the following to the top of your `src/main.ts`:

```
import * as FastClick from 'fastclick';

// attach FastClick.js
FastClick.attach(document.body);
```

**Note:** this should be added to main.ts as close to the top as possible so it executes immediately.

### 5. Initializing Plugins

Now if you want to install other plugins you'll need to configure them. This can be done in the `ngOnInit()` of your `app.component.ts`:

```
// src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { CordovaService } from './service/cordova.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'app';

  constructor(protected _cordovaService: CordovaService) {}

  public ngOnInit(): void {
    this._cordovaService.initialize();
  }
}

// src/app/service/cordova.service.ts
import { Injectable } from '@angular/core';

@Injectable()
export class CordovaService {

  protected hasBegunInitialization: boolean = false;

  constructor() {}

  public initialize(): void {
    // listen for 'deviceready' event in case it hasn't
    // already been fired during application bootstrap
    document.addEventListener('deviceready', () => {
      window['isDeviceReady'] = true;
      this.init();
      console.log('deviceready fired after bootstrap finish');
    }, false);

    // check if 'deviceready' has already fired during
    // application bootstrap.
    if (window['isDeviceReady'] === true) {
      this.init();
      console.log('deviceready fired before bootstrap finish');
    }
  }

  protected init(): void {

    // lock initialization
    if (this.hasBegunInitialization) {
      return;
    }

    this.hasBegunInitialization = true;

    // do init stuff here
  }
}
```

Make sure you add a provider for the `CordovaService` class.

### Troubleshooting

- `Error: Cannot read property 'replace' of undefined` run `cd platforms/ios/cordova && npm install ios-sim`
- [Images/assets not showing up?](https://stackoverflow.com/questions/42830752/ionic-2-images-not-displaying-on-device)
- 

Whitescreen of death?

  - Cordova doesn't like `<base href="/"></base>`, instead use `<base href="."></base>` for your cordova distributions. This typically isn't what you want for your web distribution however as it can mess with your routing.
  - If you're having this issue please take a look at the Add Scripts section and take a look at the `--base-href` flags.