I'm trying to import the moment.js library in angular2.
I found the following solution as:
import {Component} from 'angular2/core';
import * as moment from 'moment';
#Component({
selector: 'app',
template: require('./app.component.html')
})
export class AppComponent {
moment:any = moment;
constructor() {}
}
However, I do not want to import this to every component I have. Is there a way to inject it globally so I can use it in all my components?
From what I read here, I can provide the momentjs library when bootstrap the whole application like this:
import * as moment from 'moment';
import {provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
bootstrap(App, [
provide("moment", {useValue:moment})
])
Then I can use it in my own component by using DI, like this:
import {Component, OnInit, Inject} from 'angular2/core';
#Component({
selector: 'app',
template: require('./app.component.html')
})
export class AppComponent {
constructor(#Inject("moment") private moment) {}
}
Derive your components from a common base type that imports moment.
Parent
import * as moment from 'moment';
export class MomentAwareClass {
moment:any = moment;
constructor() {}
}
Child
import {Component} from 'angular2/core';
#Component({
selector: 'app',
template: require('./app.component.html')
})
export class AppComponent extends MomentAwareClass {
constructor() {}
}
Update
A better way is to use Dependency Injection to write a service with the Injectable() decorator, this is better as composition is preferred over inheritance.
import { Injectable } from '#angular/core';
import * as moment from 'moment';
#Injectable()
export class SomeClass {
public moment: any = moment;
}
Related
I've created a service that I use in 2 separate components from the same module.
The service has a few imports and is somewhat normal.
import { CdkPortal } from "#angular/cdk/portal";
import { ElementRef, Injectable } from "#angular/core";
import { Subject, Subscription } from "rxjs";
#Injectable()
export class TestService {...}
I've added the service into the module into the providers array as well as both components where the service is needed.
The first component uses the service with no issue.
import { FlyoutService } from "../flyout.service";
#Component({
selector: "test-uno",
templateUrl: "./test-uno.component.html",
styleUrls: ["./test-uno.component.scss"],
})
export class TestUnoComponent implements OnInit, OnDestroy, AfterViewInit {
constructor(private flyoutService: FlyoutService) {...}
}
The second component, that uses the service in what I think is the same way, fails.
import { FlyoutService } from "./../flyout.service";
#Component({
selector: "test-dos",
templateUrl: "./test-dos.component.html",
styleUrls: ["./test-dos.component.scss"],
animations: [...],
})
export class TestDosComponent implements OnInit, OnChanges, OnDestroy {
constructor(private flyoutService: FlyoutService) { }
}
The second component fails in the browser with the error:
Export of name 'CdkPortal' not found.
This only happens when buildOptimizer is set to true on the build. Any idea what's going on?
I added OpenRouteService to my Stackbliz application but cant get it working.
the Component looks like:
import { Component, OnInit } from '#angular/core';
import {Location} from '#angular/common';
import {Openrouteservice} from '/openrouteservice-js/dist/ors-js-client';
#Component({
selector: 'app-event-plan',
templateUrl: './event-plan.component.html',
styleUrls: ['./event-plan.component.scss']
})
export class EventPlanComponent implements OnInit {
constructor(private _location: Location) {
console.log("++++")
console.log(Openrouteservice)
}
ngOnInit() {
}
backClicked() {
this._location.back();
}
}
My problem is that it just doesnt get loaded. I added it as a dependency in the dependency section.
I made the project public here is the url - https://stackblitz.com/edit/angular-micwge?file=src%2Fapp%2Fevent-plan%2Fevent-plan.component.ts
You will have to change the way you import the library. The current way you import is looking for a named export from the library.
If you have allowSyntheticImports and esModuleInterop in your tsconfig.json use this:
import Openrouteservice from 'openrouteservice-js';
otherwise:
import * as Openrouteservice from 'openrouteservice-js';
Find your forked stacknlitz
I am trying to pass a simple string object from a parent component to a sub-child component. I have tried doing it the following way:
parent.ts
import {Component} from 'angular2/core';
import {Router,ROUTER_DIRECTIVES,ROUTER_PROVIDERS,RouteConfig} from 'angular2/router';
import {ChildCmp} from "./child";
import {bootstrap} from 'angular2/platform/browser';
#Component({
selector: 'app',
template:`
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES]
})
export class ParentCmp{
public data = "Some data from parent.";
constructor (private _router:Router){
var config = [];
if(!this._router.registry.hasRoute("Child",ParentCmp))
config.push({path: "/child/...",component:ChildCmp,name: 'Child',useAsDefault:true, data: {"data": this.data}});
this._router.config(config);
}
}
bootstrap(ParentCmp,[
ROUTER_PROVIDERS
]);
child.ts
import {Component} from 'angular2/core';
import {RouteData,Router,ROUTER_DIRECTIVES,RouteConfig} from 'angular2/router';
import {SubChildCmp} from "./sub_child";
#Component({
selector: 'child',
template: `<router-outlet></router-outlet>`,
directives: [ROUTER_DIRECTIVES]
})
#RouteConfig([
])
export class ChildCmp{
public data:Object;
constructor(private _data:RouteData,private _router:Router){
this.data = this._data.get("data");
var config = [];
if(!this._router.registry.hasRoute("SubChild",ChildCmp))
config.push({path:"/sub_child",component: SubChildCmp,name:"SubChild", useAsDefault:true, data:{"data":this.data}});
this._router.config(config);
}
}
sub_child.ts
import {Component} from 'angular2/core';
import {RouteData} from 'angular2/router';
#Component({
selector: "sub-child",
template: `Data from parent is -->
{{data}}
`
})
export class SubChildCmp{
public data:Object;
constructor(private _data:RouteData){
this.data = this._data.get("data");
}
}
But I am getting a blank page. It looks like the routing configuration in child.ts is not being configured properly. How can I achieve this? I just want to pass some data from parent component to sub-child component. I re-produced the problem here on plunker
Usually a service is used for this use case
#Injectable
export class SharedData {
data;
}
#Component({
selector: 'app',
providers: [SharedData],
template:`
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES]
})
export class ParentCmp{
public data = "Some data from parent.";
constructor (private _router:Router, private _sharedData:SharedData){
var config = [];
if(!this._router.registry.hasRoute("Child",ParentCmp))
_sharedData.data = this.data;
}
}
}
export class SubChildCmp{
public data:Object;
constructor(_sharedData:SharedData){
this.data = _sharedData.data;
}
}
Using Observable or BehaviorSubject with subscribe() might be necessary if there are timing issues, for example when SubChildCmp reads the value before the ParentCmp has set it.
For more details see https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
I'm unable to inject a (global) service into another service.
boot.ts
import {bootstrap} from 'angular2/platform/browser';
import {ROUTER_PROVIDERS} from 'angular2/router';
import {HTTP_PROVIDERS} from 'angular2/http';
import {AppComponent} from './app.component';
import {GlobalService} from './common/global.service';
bootstrap(AppComponent, [
GlobalService,
ROUTER_PROVIDERS,
HTTP_PROVIDERS
]);
global.service.ts
import {Injectable} from 'angular2/core';
#Injectable()
export class GlobalService {
api_url: string = 'hello';
}
api.service.ts
import {Injectable, Inject} from 'angular2/core';
import {GlobalService} from '../common/global.service';
#Injectable()
export class ApiService {
//constructor(#Inject(GlobalService) globalService: GlobalService) { // doesnt work
//constructor(#Inject(GlobalService) public globalService: GlobalService) { // doesnt work
constructor(public globalService: GlobalService) { // doesnt work
console.log(globalService); // undefined
console.log(this.globalService); // undefined
}
}
It works fine when injecting GlobalService into an Component.
Thank you in advance!
You need to add ApiService to bootstrap as well
bootstrap(AppComponent, [
ApiService,
GlobalService,
ROUTER_PROVIDERS,
HTTP_PROVIDERS
]);
Creating a basic directive is simple:
import {Component} from 'angular2/core';
#Component({
selector: 'my-component',
template: '<div>Hello!</div>'
})
export class MyComponent {
constructor() {
}
}
This works as expected. However, if I want to use Ionic components in my directive things blow up.
import {Component} from 'angular2/core';
#Component({
selector: 'my-component',
template: '<ion-list><ion-item>I am an item</ion-item></ion-list>'
})
export class MyComponent {
constructor() {
}
}
The directive is rendered, but Ionic components are not transformed, and so wont look/work properly.
I can't find any examples on this. How should I do this?
Found the answer here:
You have to import the Ionic components and register them as
'directives'
So my second example becomes:
import {Component} from 'angular2/core';
import {List, Item} from 'ionic/ionic';
#Component({
selector: 'my-component',
directives: [List, Item],
template: '<ion-list><ion-item>I am an item</ion-item></ion-list>'
})
export class MyComponent {
constructor() {
}
}