Angular 2: component with more than one dependency - javascript

The following code:
...
#Component({
selector: 'sitelink',
properties: ['route: route, title: title, isHome: home, href: href']
})
#View({
template: ''
})
export class SiteLink {
constructor(#Optional() #Host() #SkipSelf() parentFrame: AppFrame, #Optional() #Host() #SkipSelf() parentLink: SiteLink) {
}
...
gives me the following error during the translation from TypeScript to JavaScript
at line 32, file app-frame.ts Argument of type 'typeof SiteLink' is not assignable to parameter of type 'Type'.
Component({
selector: 'sitelink',
properties: ['route: route, title: title, isHome: home, href: href']
})
at line 36, file app-frame.ts Argument of type 'typeof SiteLink' is not assignable to parameter of type 'Type'.
View({
template: ''
})
Using only one constructor parameter works as expected. When removing the annotations from the parameter list, it does not work, too. After removing the #Component and #View annotations, the code compiles. So the error must be related to the #Component annotation.
Edit: Even if I replace the SiteLink parameter with another type (for example AppFrame), I get the same error.
I'm using alpha 36 and the latest d.ts files from the DefinitelyTyped repository.

Its possible to inject an instance of the class itself in the constructor by using a forward reference:
constructor(#Inject(forwardRef(() => SiteLink)) siteLink) {
this.name = nameService.getName();
}
See here for more details.

As Jesse Good wrote, this is an issue with angular's d.ts file, see https://github.com/angular/angular/issues/3972.
Replacing
interface Type extends Function {
new(args: any): any;
}
with
interface Type extends Function {
new(...args): any;
}
fixed it for me.

Related

Type {...} is missing the following properties from type 'any[]': length,pop,push,concat, and 28 more

I have this error:
Type {...} is missing the following properties from type 'any[]': length,pop,push,concat, and 28 more
I'm assigning album variable to the albumData array. Here is the code:
import { Component, OnInit } from '#angular/core';
import albumData from '../data/SearchResultsAlbum.json';
#Component({
selector: 'app-album-component',
templateUrl: './album-component.component.html',
styleUrls: ['./album-component.component.css']
})
export class AlbumComponentComponent implements OnInit {
album:Array<any>=[];
constructor() { }
ngOnInit(): void {
this.album=albumData;
}
}
What am I doing wrong? Thank you in advanvce!
album:any=[];
use this code instead of the code you have added
By default, Angular doesn't read the JSON file in the application. So we need to do some extra stuff for that. So we will create a file named 'json-typings.d.ts' inside the app folder of the project.
declare module "*.json" {
const value: any;
export default value;
}
source: https://jsonworld.com/demo/how-to-read-local-json-file-in-angular

How can I fix my 2 errors in this Angular component?

I'm building an application using angular that keeps track of composers and lists them. However, I keep getting these same two errors every time I try to build and run it. The errors are being found in my composer-details.component.ts file.
I'm fairly new to Angular so any advice would help a ton thank you!
composer-details.component.ts:23:3 - error TS2564: Property 'composer' has no initializer and is not definitely assigned in the constructor.
composer-details.component.ts:26:32 - error TS2345: Argument of type 'string | null' is not assignable to parameter of type 'string'.
composer-details.component.ts
import { Component, OnInit } from '#angular/core';
import { IComposer } from '../composer.interface';
import { ComposerService } from '../composer.service'
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-composer-details',
templateUrl: './composer-details.component.html',
styleUrls: ['./composer-details.component.css']
})
export class ComposerDetailsComponent implements OnInit {
composerId: number;
composer: IComposer;
constructor(private route: ActivatedRoute, private composerService: ComposerService) {
this.composerId = parseInt(this.route.snapshot.paramMap.get('composerId'), 10);
if (this.composerId) {
this.composer = this.composerService.getComposer(this.composerId);
}
}
ngOnInit(): void {
}
}
Try to use ! operator when initializing properties:
composerId!: number;
composer!: IComposer;

Unable to pass props using #Input() in angular

I'm working with very basic angular project. I want to pass props between two angular components. The properties of a component are working fine when directly rendering them in the relevant HTML file. When passing it to another component it shows error.
HTML file of the parent component
<app-todo-item *ngFor="let todo of todos" [todo]="todo">
</app-todo-item>
The child component:
import { Component, OnInit,Input } from '#angular/core';
import { Todo } from 'src/app/models/Todo';
#Component({
selector: 'app-todo-item',
templateUrl: './todo-item.component.html',
styleUrls: ['./todo-item.component.css']
})
export class TodoItemComponent implements OnInit {
#Input() todo:Todo;
constructor() {
}
ngOnInit(): void {
}
}
The error I got:
Error: src/app/components/todo-item/todo-item.component.ts:11:12 - error TS2564: Property 'todo' has no initializer and is not definitely assigned in the constructor.
That comes from the new Ts compiler. Can fix with:
#Input() todo?: Todo;
What tells compiler this property is optional. Or:
#Input() todo!: Todo;
What tells compiler this property will not be unassigned

Is there an option to NOT use a theme in formly?

I want to use tailwind to do all my styling and don't want to add extra libraries to my code.
Here is a simple example of what I've come up with:
https://stackblitz.com/edit/angular-ivy-uxrxrc?file=src%2Fapp%2Fformly-component%2Fformly-component.ts
What I've done:
Created a simple component with formly inside of it with a basic input field. Angular seems to compile fine, but the formly doesn't seem to display any fields. It errors out with a Error: [Formly Error] There is no type by the name of "input".
I also can't seem to find any examples in the documentation that doesn't have a theme.
Formly provide a set of themes out of the box such material, bootstrap.. but that not prevent you to create your own theme, the only required is step is to define custom field type as documented in https://formly.dev/guide/custom-formly-field
to summarize here are the steps:
Create a custom field type with name input:
import { Component } from '#angular/core';
import { FieldType } from '#ngx-formly/core';
#Component({
selector: 'formly-datetimepicker',
template: `
<input [formControl]="formControl"></input>
`,
})
export class InputFieldType extends FieldType {}
define your field type through the NgModule declaration:
#NgModule({
declarations: [InputFieldType],
imports: [
....
FormlyModule.forRoot({
types: [
{ name: 'input', component: InputFieldType },
],
}),
],
})
export class AppModule {}
set type to type in your field config:
fields = [
{
key: 'name',
type: 'input',
},
]
still confused check Formly UI source code https://github.com/ngx-formly/ngx-formly/tree/master/src/ui

Angular 2. Pass parameter to a component

I would like to pass a string parameter to my component. Depending on passing parameter i will pass different parameters for services in my component. I do next: In index.html call my component, passing parameter.
<top [mode]="tree">Loading...</top>
In my component i include Input from angular2/core
import {Input, Component, OnInit} from 'angular2/core';
In my component`s class i declare an input
#Input() mode: string;
And with console.log() i try to catch my passing parameter of 'tree', but it`s undefined.
console.log(this, this.mode);
The full code of a component file:
import {Http, HTTP_PROVIDERS} from 'angular2/http';
import {Input, Component, OnInit} from 'angular2/core';
import {ParticipantService} from '../services/participant.service';
import {orderBy} from '../pipes/orderby.pipe';
#Component({
selector: 'top',
templateUrl: 'dev/templates/top.html',
pipes: [orderBy],
providers: [HTTP_PROVIDERS, ParticipantService]
})
export class AppTopComponent implements OnInit {
constructor (private _participantService: ParticipantService) {}
errorMessage: string;
participants: any[];
#Input() mode: string;
ngOnInit() {
console.log(this, this.mode);
this.getParticipants('top3');
var self = this;
setInterval(function() {
self.getParticipants('top3');
}, 3000);
}
getParticipants(public mode: string) {
this._participantService.getParticipants(mode)
.then(
participants => this.participants = participants,
error => this.errorMessage = <any>error
);
}
}
When you use [...], the value you provide corresponds to an expression that can be evaluated.
So tree must be something that exists in the parent component and correspond to a string.
If you want to use the string tree, use this:
<top mode="tree">Loading...</top>
You can notice that such parameters can't be used for root component. See this question for more details:
Angular 2 input parameters on root directive
As a workaround for the limitation Thierry explained you can use
constructor(private _participantService: ParticipantService,
elRef:ElementRef) {
this.mode=elRef.nativeElement.getAttribute('mode');
}
you need to wait until template is bound to DOM. in order to do this, you have to implement AfterViewInit
export class AppTopComponent implements AfterViewInit{
public ngAfterViewInit() {
console.log(this, this.mode);
this.getParticipants('top3');
var self = this;
setInterval(function() {
self.getParticipants('top3');
}, 3000);
}
}

Categories

Resources