Ionic Serve for Applications with Native Plugins

December 22nd 2017 Ionic 2/3 Cordova

Ionic serve can be a very useful tool for tweaking the design of pages in Ionic applications, as long as you keep in mind that the web view on the phone might render the page differently and you still need to do the testing on actual devices. However, if your application is using native plugins, some of them might fail with Ionic serve.

For example, you could be using Diagnostic plugin to change the application behavior depending on the availability of a specific sensor:

this.diagnostic.isLocationEnabled().then(enabled => {
  // change the behavior based on the response
});

The above call will not even report that location is not available when in Ionic serve. It will just throw an error instead and break the application:

Error: Uncaught (in promise): cordova_not_available

To avoid this issue, the plugin needs to be mocked when the application is running in Ionic serve. To implement the mock, you can simply extend the Diagnostic class and override the methods, which are failing for you:

@Injectable()
export class DiagnosticMock extends Diagnostic {

  isLocationEnabled(): Promise<any> {
    return Promise.resolve(true);
  }
}

Configuring the dependency injection to instantiate the mock instead of the real class in Ionic serve is a bit more challenging. You will need a factory to provide one or the other implementation conditionally:

export function DiagnosticFactory(platform: Platform) {
  if (platform.is('cordova')) {
    return new Diagnostic();
  } else {
    return new DiagnosticMock();
  }
}

Checking for cordova platform is a good way to detect when the application is running in Ionic serve. Now, this factory needs to be registered with @NgModule instead of Diagnostic directly. Since the factory depends on Platform, it also eeds to be explicitly declared in the entry:

@NgModule({
  // ...
  providers: [
    // ...
    { provide: Diagnostic, useFactory: DiagnosticFactory, deps: [Platform] }
  ]
})

This will fix the problem in Ionic serve, while the application will still work the same on native devices.

Copyright
Creative Commons License