Deepu Deepu - 2 months ago 19
Javascript Question

What is the correct way to convert an Angular 1 provider to Angular 2

There are lot of documentation and examples on how to convert Angular 1 services and factories to Angular2 but I couldnt find anything on how to convert a ng1 provider to something equivalent in ng2.

Example provider

function AlertService () {
this.toast = false;

this.$get = getService;

this.showAsToast = function(isToast) {
this.toast = isToast;
};

getService.$inject = ['$timeout', '$sce'];

function getService ($timeout, $sce) {
var toast = this.toast,
alertId = 0, // unique id for each alert. Starts from 0.
alerts = []

return {
factory: factory,
add: addAlert
};

function factory(alertOptions) {
var alert = {
type: alertOptions.type,
msg: $sce.trustAsHtml(alertOptions.msg),
id: alertOptions.alertId,
toast: alertOptions.toast
};
alerts.push(alert);

return alert;
}

function addAlert(alertOptions) {
alertOptions.alertId = alertId++;
var alert = this.factory(alertOptions);

return alert;
}

}


}

angular
.module('angularApp', [])
.provider('AlertService', AlertService);


What would be the correct equivalent for this in Angular 2?

Answer

Ok so finally we figured it out thanks to https://github.com/jhipster/generator-jhipster/issues/3664#issuecomment-251902173

Here is the Service in NG2

import {Injectable, Sanitizer, SecurityContext} from '@angular/core';

@Injectable()
export class AlertService {

    private alertId: number;
    private alerts: any[];

    constructor(private sanitizer: Sanitizer, private toast: boolean) {
        this.alertId = 0; // unique id for each alert. Starts from 0.
        this.alerts = [];
    }

    factory(alertOptions): any {
        var alert = {
            type: alertOptions.type,
            msg: this.sanitizer.sanitize(SecurityContext.HTML, alertOptions.msg),
            id: alertOptions.alertId,
            toast: alertOptions.toast
        };
        this.alerts.push(alert);
        return alert;
    }

    addAlert(alertOptions, extAlerts): any {
        alertOptions.alertId = this.alertId++;
        var alert = this.factory(alertOptions);
        return alert;
    }

    isToast(): boolean {
        return this.toast;
    }
}

and here is the provider for the service

import { Sanitizer } from '@angular/core';
import { AlertService } from './alert.service';

export function alertServiceProvider(toast?: boolean) {
    // set below to true to make alerts look like toast
    let isToast = toast ? toast : false;
    return {
        provide: AlertService,
        useFactory: (sanitizer: Sanitizer) => new AlertService(sanitizer, isToast),
        deps: [Sanitizer]
    }
}

Now you need to call the alertServiceProvider method in the provider declaration of your module.

@NgModule({
    imports: [
        ...
    ],
    declarations: [
        ...
    ],
    providers: [
        ...
        alertServiceProvider()
    ],
    exports: [
        ...
    ]
})
export class SharedCommonModule {}

The code is part of the JHipster project and you can browse actual templates here