Cannot find name +'Input'. any Angular 2 - javascript

I am trying to get #Input to work with Typescript in Angular 2. I am getting the following error and I don't understand why.
[ts] Cannot find name 'Input'. any
Below is the code from that component.
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-item',
templateUrl: './app-item.component.html',
styleUrls: ['./app-item.component.css']
})
export class AppItemComponent implements OnInit {
#Input item; //TypeScript complains here.
constructor() { }
ngOnInit() {}
}
The project and component were both created using the Angular CLI. Why can't TypeScript figure out the #Input decoration?

You need to add this,
import {Component, Input} from '#angular/core';

In my case I already had:
import { Component, OnInit } from '#angular/core';
So, when I tried to use:
import {Component, Input} from '#angular/core';
It didn't work.
What I had to do was import like that (Without the word Component)
import { Input } from '#angular/core';
And it worked just fine

#Marcielli, it didn't work because of the double import of Component. If you change the import statement to the following
import { Component, OnInit, Input } from '#angular/core';
You would be just fine. Optionally adding the Input module in a separate import statement is perfectly fine, but you should generally stick with either importing all components from a module in one statement, or each in separate statements.

Related

Angular - How to reuse a component in a different level?

Imagine we have this component structure:
app1
-- app1.component.html
-- app1.component.ts
parent1
parent2
app2
-- app2.component.html
-- app2.component.ts
How could I reuse the app2 component in the app1? For example, reuse a table (both HTML and logic on typescript) instead of copy and paste code.
I have searched for solutions like ng-template, but failed. Also, call the tag didn't work as well.
If the tag didn't work inside app1 I assume that you are importing app2 component inside another module. If we want to use component over multiple modules you need to import app2 ONLY in shared module then import that module to modules where you want to have that component.
Make sure to export that component inside shared module.
Need to use componentFactoryResolver https://angular.io/guide/dynamic-component-loader
For example you want to use ThirdComponent inside FirstComponent
//HTML
<section #firstComp></section>
//TS
import { AfterViewInit, Component, ComponentFactoryResolver, OnInit, ViewChild, ViewContainerRef } from '#angular/core';
import { ThirdComponent } from '../third/third.component';
#Component({
selector: 'app-first',
templateUrl: './first.component.html',
styleUrls: ['./first.component.scss']
})
export class FirstComponent implements OnInit, AfterViewInit {
#ViewChild('firstComp',{read: ViewContainerRef}) firstComp: ViewContainerRef;
constructor(
private componentFactoryResolver: ComponentFactoryResolver
) { }
ngOnInit(): void {
}
ngAfterViewInit() {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(ThirdComponent);
const componentRef = this.firstComp.createComponent<ThirdComponent>(componentFactory);
}
}

Angular Compilation Error on import but method works

I have this external script which is added to the scripts sections of angular-cli.json
I then import it into my component and declare it as a variable.
Here is my component code
declare var radarChart: any;
import { Component, AfterViewInit, ElementRef } from '#angular/core';
import * as d3 from 'd3';
import '../../../libs/radarChart.js'
import './init-outcome-chart.js'
#Component({
selector: 'profile-component',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent {
constructor() {
RadarChart('', '', '');
}
}
The method inside the script I want to use is called RadarChart, so I call that in my constructor which works, however it gives me a syntax error saying its undefined. Doing radarChart.RadarChart get rids of the syntax error but on load of the web page, I get a console error marking radarChart (the variable) undefined.
What am I doing wrong

How to add spaces in the JavaScript import in Clang-Format

Here is the code snippet in my TypeScript/JavaScript file:
import { Component, OnInit } from '#angular/core';
The Clang-Format will format my code into this:
import {Component, OnInit} from '#angular/core';
But I'd like to use Clang-Format format my code into this.
import { Component, OnInit } from '#angular/core';
I want to add one space between { and Component and add one space between OnInit and }, but I couldn't find any Clang-Format Style Options to set that. Is there anyway to configure this?

Normal website body as Angular 2 Componentwithout replacing them

I want to make my website modern with some cool features.
For this I used jQuery and self made things. But that's slow and everything I developed is easier in Angular.
So I started to implement the Angular 2 code into my normal website.
The things (app.component, main.ts, app.module) work. I have the angular functionality on my page.
That's the first try.
Now I found out that I can't use second and third components (this ones which are not in bootstrap array) not within the selector.
So the bootstrapped component is the root-element for everything I think.
The next step was to replace the whole body as a component.
For example with angular 1 it was easy: ng-controller="app" and finish.
I can do this with <body> and everything.
Now with Angular 2 I must define a template for the component. else I get this error Uncaught Error: No template specified for component AppComponent
So the questions are...
Is it possible to use the as selector for the app so that I can use components within the app without bootstrapping them?
Or is there a way to use the components flexible?
The main reason is:
I want to define components globally which must not exist on each page. So I can have a component which is called test-component which is only used on test.html and a about-component which is only used on about.html
You understand?
Currently the problem is that I get this error: app.js:116448EXCEPTION: Error in :0:0 caused by: The selector "my-app" did not match any elements and ORIGINAL EXCEPTION: The selector "my-app" did not match any elements
If I define them both it works. But if one component is missing then I get this error.
Current scripts:
main.ts
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
app.component.ts
import { Component } from '#angular/core';
import {Http} from "#angular/http";
#Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1> <a (click)="test()">:)</a>`
})
export class AppComponent {
constructor (private http: Http) {}
name = 'Angular';
test() {
alert('Yay');
return this.http.get('/asd/aaa/test').subscribe((a) => {
console.log('A', a);
}, (b) => {
console.log('B', b);
});
}
}
app.module.ts
import {NgModule} from '#angular/core';
import {BrowserModule} from '#angular/platform-browser';
import {AppComponent} from './app.component';
import {JsonpModule, HttpModule} from "#angular/http";
import {FormsModule} from "#angular/forms";
import {TestComponent} from "./test.component";
#NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
JsonpModule
],
declarations: [
AppComponent,
TestComponent
],
bootstrap: [
AppComponent,
// TestComponent // this shouldnt be a bootstrap because else the component MUST exist on the page!
]
})
export class AppModule {
}
test.component.ts
import { Component } from '#angular/core';
import {Http} from "#angular/http";
#Component({
selector: 'test-app',
template: `<h1>Hello {{name}}</h1> <a (click)="test()">:)</a>`
})
export class TestComponent {
constructor (private http: Http) {}
name = 'Angular !!!!!!!!!!!!';
test() {
alert('yyyyy');
return this.http.get('/asd/aaa/test').subscribe((a) => {
console.log('A', a);
}, (b) => {
console.log('B', b);
});
}
}
As I said if I want to use the body as root element it replaces everything of the body. And this is not for my use case.
It's only a normal website. Multiple HTML (background = PHP) pages.
I could implement this platformBrowserDynamic().bootstrapModule(AppModule); on each page where I need something. Then I could write a module for each page. I think this could solve the problem, too. But it's bad... Having a lot of modules...

No provider for service error in angular2, why do I need to inject it in it's parent component?

I have a pages.service.ts
import { Injectable } from '#angular/core';
import { ApiService } from '../../apiService/api.service';
import { Playlists } from '../shared/playlists.model';
#Injectable()
export class PagesService {
private currentPlaylists: Subject<Playlists> = new BehaviorSubject<Playlists>(new Playlists());
constructor(private service: ApiService) {
}
}
This pages service needs another service called ApiService, I inject the way as shown above, it works.
I bootstrap ApiService in main.ts
import { ApiService } from './apiService/api.service';
import { AppComponent } from './app.component';
bootstrap(AppComponent,[
disableDeprecatedForms(),
provideForms(),
HTTP_PROVIDERS,
ROUTER_PROVIDERS,
ApiService
]).catch((err: any) => console.error(err));;
But When I try to inject the PagesService to another component, it gives me error, No Provider for PagesService.
I write that component like this.
import { Component, ViewChild, ElementRef, Input, Output, EventEmitter } from '#angular/core';
import { CORE_DIRECTIVES } from '#angular/common';
import { MODAL_DIRECTVES, BS_VIEW_PROVIDERS } from 'ng2-bootstrap/ng2-bootstrap';
import { ApiService } from '../../apiService/api.service';
import { PagesService } from '../../pages/shared/pages.service';
#Component({
selector: 'assign-playlist-modal',
exportAs: 'assignModal',
providers: [ PagesService ],
directives: [MODAL_DIRECTVES, CORE_DIRECTIVES, FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES ],
viewProviders: [BS_VIEW_PROVIDERS],
styleUrls: ['app/channel/shared/assignPlaylist.css'],
templateUrl: 'app/channel/modals/assignPlaylistModal.html'
})
export class AssignPlaylistModalComponent {
constructor(private apiService: ApiService, private pageService: PagesService, fb: FormBuilder) {
}
}
Update: this is my file structure
channel/
--channel.component.ts
--shared/
----assignPlaylist.modal.ts
----addPlaylist.modal.ts
pages/
--shared/
----pages.service.ts
--pages.component.ts
Channel component is the parent of addPlaylist, addPlaylist is the parent of assignPlaylist. This structure will not work
ChannelComponent
|
AddPlaylistComponent
|
AssignPlaylistComponent ----PagesService----ApiService
I found one solution but don't know why I need to do that,
I add the provider 'PagesService' to ChannelComponent, and also the AssignPlaylistComponent, it will work, no errors.
Even this will work
ChannelComponent ----PagesService-------------
|
AddPlaylistComponent
|
AssignPlaylistComponent ----ApiService---------------
However, I just want to use PagesService in AssignPlaylistComponent, so I think it not make sense to import PagesService in channelcomponent.ts and make a providers array in it.
It is a bit strange, but only components can configure dependency injection in Angular (well, and bootstrap()). I.e., only components can specify providers.
Each component in the component tree will get an associated "injector" if the component has a providers array specified. We can think of this like an injector tree, that is (normally much) sparser than the component tree. When a dependency needs to be resolved (by a component OR a service), this injector tree is consulted. The first injector that can satisfy the dependency does so. The injector tree is walked up, toward the root component/injector.
So, in order for your PagesService to inject a ApiService dependency, that ApiService object first has to be registered with an injector. I.e., in a component's providers array. This registration must occur somewhere at or above the component where you want to use/inject the ApiService .
Your service should then be able to inject the registered ApiService object, because it will find it in the injector tree.
See also Angular 2 - Including a provider in a service.

Categories

Resources