Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making moment injectable in angular2

I would like to make moment to be injectable through out my app.
I just started learning ng2 and couldn't find this type of usage in the docs.
Here is what I have in my app.module.ts:

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';
import {AppComponent} from './app.component';
import * as moment from 'moment';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [{provide: 'moment', useValue: moment}],
  bootstrap: [AppComponent]
})
export class AppModule {
}

and here is the component:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass']
})


export class AppComponent {
  title = 'app works!';

  constructor(private moment) {
    this.title += this.moment;
  }
}

there is this error:

Uncaught Error: Can't resolve all parameters for AppComponent:

How should this be done correctly?

UPDATED MODULE

const moment = new OpaqueToken('moment');

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [{provide: moment, useValue: moment}],
  bootstrap: [AppComponent]
})

export class AppModule {
}

UPDATED COMPONENT

import { Component } from '@angular/core';
import * as moment from 'moment';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass']
})


export class AppComponent {
  title = 'app works!';

  constructor(private moment: moment) {
    this.title += this.moment()
  }
}

There is an error on this line constructor(private moment: moment) which tells that: Cannot find name 'moment'.

like image 730
vlio20 Avatar asked Mar 12 '23 00:03

vlio20


2 Answers

Moment by itself is not an injectable for Angular2. However it can be wrapped inside one.

Plunker Demo

moment.service.ts

import { Injectable } from '@angular/core';
import * as m from 'moment';
@Injectable()
export class MomentService {
    moment = m;
}

app.module.ts

import { MomentService } from './moment.service';

@NgModule({
    providers: [MomentService]
    ...

app.component.ts

import { MomentService } from './moment.service';

export class AppComponent {
    constructor(private ms: MomentService){
        console.log('Moment:' + this.ms.moment("20111031", "YYYYMMDD").toString());
    }
}

Not perfect, but works.

like image 200
John Siu Avatar answered Mar 21 '23 07:03

John Siu


You need to use OpaqueToken which will allowed you to create a string based token. I'd just suggest you to change the name of moment to avoid thr collision with moment variable of library.

// You can place this is some file, so that you can export it.
export const Moment = new OpaqueToken('moment');

and then you could use

providers: [{provide: MomentStatic, useClass: moment}],

You can go through this article for more details

While using dependency include it in a Component constructor.

constructor(private moment: MomentStatic)
like image 21
Pankaj Parkar Avatar answered Mar 21 '23 06:03

Pankaj Parkar