'Ionic - Change import library based on IsDebugMode

Can I use IsDebugMode to switch out import libraries?

Can I do:

if (IsDebugMode) {
    import { SQLiteMock, SQLiteObject } from '../mocks/SQLiteMock';
}
else {
    import { SQLite, SQLiteDatabaseConfig, SQLiteObject } from '@ionic-native/sqlite';
}


Solution 1:[1]

Even though some plugins may work when running the app on the browser (when using ionic serve), I like to inject a mock version of the plugin to avoid warnings in the console (or errors being thrown because of cordova.js not being found).

The easiest way I found to do this is by using factories, to decide which implementation of the plugin should be injected. I'll show you a demo using the Keyboard cordova plugin just to keep this short, but the same can be done with any cordova plugin (even if it's not part of Ionic Native).

In my providers folder, I have a custom folder named plugins and inside of that folder I've added a file with the name keyboard.provider.ts. Inside of that file, I've defined the following:

// Ionic
import { Platform } from 'ionic-angular';

// RxJS
import { Observable } from 'rxjs/Observable';

// Ionic native
import { Keyboard } from '@ionic-native/keyboard';

// Browser implementation
export class BrowserKeyboardProvider extends Keyboard {

    public hideKeyboardAccessoryBar(hide: boolean): void {
        console.log(`[Keyboard Browser]: hideKeyboardAccessoryBar set to ${hide}`);
    }

    public show(): void {
        console.log(`[Keyboard Browser]: show`);
    }

    public close(): void {
        console.log(`[Keyboard Browser]: close`);
    }

    public disableScroll(disable: boolean): void {
        console.log(`[Keyboard Browser]: disableScroll set to ${disable}`);
    }

    public onKeyboardShow(): Observable<any> {
        console.log(`[Keyboard Browser]: onKeyboardShow`);
        return Observable.of(true);
    }

    public onKeyboardHide(): Observable<any> {
        console.log(`[Keyboard Browser]: onKeyboardHide`);
        return Observable.of(true);
    }

}

// Mobile implementation
export class MobileKeyboardProvider extends Keyboard { }

// --------------------------------------------------------
// Keyboard factory
//    parameters: dependencies of the target service
//    returns: instance of the service (for real devices or the browser)
// --------------------------------------------------------
export function keyboardFactory(platform: Platform) {
    return platform.is('cordova') ? new MobileKeyboardProvider() : new BrowserKeyboardProvider();
}

// keyboardProvider: used to import the service in the NgModule declaration
export let keyboardProvider =
    {
        provide: Keyboard,
        useFactory: keyboardFactory,
        deps: [Platform]
    };

Like you can see there, I'm just creating two classes that extend the Keyboard class, and in the browser implementation I just write a few things in the console, and return a mocked response. You can do whatever you want inside of those methods.

To know what methods you should mock, you can inspect the index.d.ts file of that plugin.

The mobile implementation does not define anything, so the method from the super class (the Keyboard plugin) will be used.

The most important part of the code is the last part:

export function keyboardFactory(platform: Platform) {
    return platform.is('cordova') ? new MobileKeyboardProvider() : new BrowserKeyboardProvider();
}

// keyboardProvider: used to import the service in the NgModule declaration
export let keyboardProvider =
    {
        provide: Keyboard,
        useFactory: keyboardFactory,
        deps: [Platform]
    };

The keyboardFactory gets an instance of the Platform and we use that instance to check if te app is being executed in the browser, or in a cordova device. Based on that, we return the browser implementation, or the mobile one.

The keyboardProvider just tells angular that it should use the keyboardFactory factory to create instances of the Keyboard class, and that the factory depends on an instance of the Platform to work properly.

Now the only thing left to be done is to tell the main module (the one in the app.module.tsfile) to use our custom provider.

// Cordova plugins providers
import { keyboardProvider } from '../providers/plugins/keyboard.provider';

@NgModule({
    declarations: [
        MyApp,
        // ...
    ],
    imports: [
        // ...
    ],
    bootstrap: [IonicApp],
    entryComponents: [
        //...
    ],
    providers: [
        // Cordova plugins
        keyboardProvider,  // <-- Use the provider instead of just Keyboard

        // ...
        { provide: ErrorHandler, useClass: IonicErrorHandler }
    ]
})
export class AppModule { }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1