How do I import immutable js into angular 2 (alpha)? - javascript

I've tried:
import {Component, Template, bootstrap} from 'angular2/angular2';
import {Immutable} from 'immutable/immutable';
#Component({
selector: 'my-app'
})
#Template({
inline: '<h1>Hello {{ name }}</h1>'
})
class MyAppComponent {
constructor() {
this.name = 'Alice';
this.wishes = Immutable.List(['a dog', 'a balloon', 'and so much more']);
console.log(this.wishes);
}
}
bootstrap(MyAppComponent);
But then Immutable ends up being undefined.
Then I tried:
import {Component, Template, bootstrap} from 'angular2/angular2';
import {Immutable} from 'immutable/immutable';
#Component({
selector: 'my-app'
})
#Template({
inline: '<h1>Hello {{ name }}</h1>'
})
class MyAppComponent {
constructor(im: Immutable) {
this.name = 'Alice';
this.wishes = im.List(['a dog', 'a balloon', 'and so much more']);
console.log(this.wishes);
}
}
But then I get Cannot resolve all parameters for MyAppComponent. Can anybody help me with this?
And yes I've added the immutable folder to System.paths. Could it be that Immutable just can't be imported in an ES6 kind of way?

It was a small mistake. I had to change
import {Immutable} from 'immutable/immutable';
to
import Immutable from 'immutable/immutable';

Related

Utilizing Imported Functions in Angular for Interpolation

I have the below component where I am attempting to utilize a function that I've created called FormatDate that displays the date in a particular way. I was expecting to implement it via interpolation in my html however the function is not recognized. Is there a way to utilize it without wrapping it in a function local to the component? I read through the Angular - Template Syntax documents but nothing jumped out to me.
import { Component } from '#angular/core';
import { FormatDate } from '../shared/commonFunctions';
#Component({
selector: 'my-component',
template: '<h3>{{FormatDate(rightNow)}}</h3',
})
export class myComponent {
rightNow = Date();
}
My workaround is below, but it is unsightly to me so I was hoping to find a way around it.
import { Component } from '#angular/core';
import { FormatDate } from '../shared/commonFunctions';
#Component({
selector: 'my-component',
template: '<h3>{{dateFormat(rightNow)}}</h3',
})
export class myComponent {
rightNow = Date();
dateFormat(date: string): string {
return FormatDate(date);
}
}
import {Pipe, PipeTransform} from "#angular/core";
#Pipe({name: 'transformDatePipe'})
export class TransformDatePipe implements PipeTransform {
transform(date: string, params:any...): any {
return yourFunction();
}
}
import { Component } from '#angular/core';
import { FormatDate } from '../shared/commonFunctions';
#Component({
selector: 'my-component',
template: '<h3>{{rightNow|transformDatePipe:anyAdditionalParamsYouNeed}}</h3',
})
export class myComponent {
rightNow = Date();
}
Don`t forget to add your new Pipe to the module declarations array.
https://angular.io/guide/pipes

Angular2 Routing - Passing data from parent component to a sub-child component

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

In Ionic 2, how do I create a custom directive that uses Ionic components?

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() {
}
}

Class is not injectable if it is defined right after a component with meta annotation

I just started off with Angular2 quick start project. Have a simple application working. I added DataService class, so that the code will have separation of concern.
Initially I've added the DataService class write after the my main component of app which is MyAppComponent like below.
import {Component, View} from 'angular2/core';
import {NgFor} from 'angular2/common';
import {bootstrap} from 'angular2/platform/browser';
#Component({
'selector': 'my-app',
template: `<div *ngFor="#item of items">{{item}}</div>`,
directives: [NgFor],
providers: [DataService] //taking service as injectable
})
export class MyAppComponent {
items: Array<number>;
constructor(service: DataService) {
this.items = service.getItems(); //retrieving list to bind on the UI.
}
}
//created service, but its after the component which has meta annotation
export class DataService {
items: Array<number>;
constructor() {
this.items = [1, 2, 3, 4];
}
getItems() {
return this.items; //return the items list
}
}
bootstrap(MyAppComponent)
Above code compiles correctly, but at run-time it throws below error.
EXCEPTION: Cannot resolve all parameters for
MyAppComponent(undefined). Make sure they all have valid type or
annotations.
After 2 hours playing with the code, I shifted the DataService just above the MyAppComponent which got worked. I'm really glad that issue solved.
But I'm very curious to know that, why it wasn't working if I placed DataService class right after the class with MetaAnnotation over it?
Edit
I tried solution give by #Günter Zöchbauer like below,
import {Component, View, Inject, forwardRef} from 'angular2/core';
import {NgFor} from 'angular2/common';
import {bootstrap} from 'angular2/platform/browser';
#Component({
'selector': 'my-app',
template: `<div *ngFor="#item of items">{{item}}</div>`,
directives: [NgFor],
providers: [DataService] //tried commenting this still throws error.
})
export class MyAppComponent {
items: Array<number>;
constructor(#Inject(forwardRef(() => DataService)) service: DataService) {
this.items = service.getItems();
}
}
but still getting error in console. which looks wiered
EXCEPTION: TypeError: Cannot read property 'toString' of undefined
JavaScript doesn't hoist classes. Either use forwardRef, move DataService to it's own file or move DataService class above MyAppComponent
#Component({
'selector': 'my-app',
template: `<div *ngFor="#item of items">{{item}}</div>`,
directives: [NgFor],
providers: [forwardRef(() => DataService)] //taking service as injectable
})
export class MyAppComponent {
items: Array<number>;
constructor(#Inject(forwardRef(() => DataService)) service: DataService) {
this.items = service.getItems(); //retrieving list to bind on the UI.
}
}
See also
- Angular 2 error:
- http://blog.thoughtram.io/angular/2015/09/03/forward-references-in-angular-2.html

How to create object which can be modified by multiple angular2 component?

How to create object which can be modified by multiple angular2 component.
Eg.
PeopleService.ts
//a simple service
import {Injectable} from 'angular2/angular2'
#Injectable()
export class PeopleService {
constructor() {
this.people = [
{id: 1, name: 'Brad'},
{id: 2, name: 'Jules'},
{id: 3, name: 'Jeff'}
];
}
changeBrad(){
this.people[0].name = "Brad_Changed";
}
}
App.ts
import {Component, View} from 'angular2/angular2';
import {PeopleService} from './peopleService';
#Component({
selector: 'my-app',
bindings: [PeopleService]
})
#View({
template: '{{appval}}',
})
export class App{
appval:string;
constructor(public peopleService:PeopleService){
peopleService.changeBrad();
this.appval = peopleService.people[0].name; // result : Brad_Changed
}
}
Home.ts
import {Component, View} from 'angular2/angular2';
import {PeopleService} from './peopleService';
#Component({
selector: 'my-home',
bindings: [PeopleService]
})
#View({
template: '{{homeval}}',
})
export class Home{
homeval:string;
constructor(public peopleService:PeopleService){
this.homeval = peopleService.people[0].name; // result : Brad
}
}
In Home.ts result is " Brad" which is not modified by App.ts I want result to be "Brad_Changed" which was modified by App.ts. How do I write my PeopleService.ts and how to pass it by reference to other component in angular2?
Just remove PeopleService from Home component bindings. By adding this binding, you're creating new instance of PeopleService for Home component and all its children:
import {Component, View, Host} from 'angular2/angular2';
import {PeopleService} from './peopleService';
#Component({
selector: 'home',
// Adding this you're creating new instance of PeopleService for
// Home component and all its children
// bindings: [PeopleService]
})
#View({
template: '<p>{{homeval}}</p>',
})
export class Home{
homeval:string;
constructor(peopleService:PeopleService){
this.homeval = peopleService.people[0].name; // result : Brad
}
}
See this plunker

Categories

Resources