I am doing an Angular 2 demo with injection and get an error that my CustomDirective can't be used as an entry element.
So, my NgModule
import {platformBrowserDynamic} from '#angular/platform-browser-dynamic';
import AppComponent from './app.component';
import {NgModule} from "#angular/core";
#NgModule({
declarations: [AppComponent],
bootstrap:[AppComponent]
})
export class AppModule{}
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
AppComponent:
import {Component} from '#angular/core';
import {TIMER_DIRECTIVES} from './timer/timer';
import {TASK_DIRECTIVES} from './tasks/tasks';
import {SHARED_PROVIDERS} from './shared/shared';
#Component({
selector: 'tomato-app',
entryComponents: [TIMER_DIRECTIVES,TASK_DIRECTIVES],
providers: [SHARED_PROVIDERS],
template: `
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<strong class="navbar-brand">Tomato App</strong>
</div>
</div>
</nav>
<tomato-timer-widget></tomato-timer-widget>
<tomato-tasks></tomato-tasks>`
})
export default class AppComponent{}
And the custom directive itself:
import {Task} from '../shared/shared'
import {Input, HostListener, Directive} from '#angular/core';
#Directive({
selector: '[task]'
})
export default class TaskTooltipDirective {
private defaultTooltipText: string;
#Input() task: Task;
#Input() taskTooltip: any;
#HostListener('mouseover')
onMouseOver() {
if (!this.defaultTooltipText && this.taskTooltip) {
this.defaultTooltipText = this.taskTooltip.innerText;
}
this.taskTooltip.innerText = this.task.name;
}
#HostListener('mouseout')
onMouseOut() {
if (this.taskTooltip) {
this.taskTooltip.innerText = this.defaultTooltipText;
}
}
}
The problem is that I am using entryComponents in AppComponent incorrectly. How do I need to link a custom directive?
entryComponents: list of components that are dynamically inserted into the view of this component
How do I need to link a custom directive?
Put your all directive, pipe, component in declarations array at NgModule level:
#NgModule({
declarations: [AppComponent, TIMER_DIRECTIVES, TASK_DIRECTIVES],
bootstrap:[AppComponent]
})
export class AppModule{}
note that, if you declare provider at Component level:
#Component({
selector: 'tomato-app',
providers: [SHARED_PROVIDERS],
//...
})
it will create new instance for all instances of this component. in other word, if you have 2 different Component, with 2 declare providers: [SHARED_PROVIDERS], then the SHARED_PROVIDERS of 2 component are different. you need declare in NgModule level to use same instance in all component of this NgModule.
#NgModule({
declarations: [AppComponent, TIMER_DIRECTIVES, TASK_DIRECTIVES],
providers: [SHARED_PROVIDERS],
entryComponents: [TIMER_DIRECTIVES, TASK_DIRECTIVES],
bootstrap:[AppComponent]
})
export class AppModule{}
Related
This is my standalone component
import { Component } from '#angular/core';
import { CommonModule } from '#angular/common';
#Component({
selector: 'app-navbar',
standalone: true,
imports: [CommonModule],
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.scss']
})
export class NavbarComponent {
}
and this is where i have imported it (in admin module)
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { AdminRoutingModule } from './admin-routing.module';
import { UsersComponent } from './users/users.component';
import { NavbarComponent } from '../components/navbar/navbar.component';
#NgModule({
declarations: [
UsersComponent
],
imports: [
CommonModule,
AdminRoutingModule,
NavbarComponent,
]
})
export class AdminModule { }
In my usercomponent.html template i did
<p>users works!</p>
<app-navbar></app-navbar>
When I run ng serve I got
`error NG8001: 'app-navbar' is not a known element:
If 'app-navbar' is an Angular component, then verify that it is part of this module.
If 'app-navbar' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
2 `
I would like to know why I have this error and how to fix it
Thanks !
If NavbarComponent is part of another module, on that module you have to export the component using exports[], and then import the module, not the component on AdminModule.
If it is not part of other module, you have to include the component on declarations[] not on imports[].
First is the path in my app routing module
Then the home component
Next is the app component
Lastly the html for button creation
path in the app.routing.module.ts
{
path: 'about-us',
pathMatch: 'full',
data: { type: '', breadcrumb: '' },
component: AboutUsComponent,
},
default constructor and ngOnInit in home.component.ts only router variable in constructor
import { Component, OnInit } from '#angular/core';
import {Router} from '#angular/router';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'],
})
export class HomeComponent implements OnInit {
constructor(private router : Router) {}
ngOnInit(): void {}
}
default imports in app.module.ts only
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AboutUsComponent } from './about-us/about-us.component';
import { LoginComponent } from './login/login.component';
import { LogoutComponent } from './logout/logout.component';
import { SocialMediaComponent } from './social-media/social-media.component';
import { LoggedInHomeComponent } from './logged-in-home/logged-in-home.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
#NgModule({
declarations: [
AppComponent,
HomeComponent,
AboutUsComponent,
LoginComponent,
LogoutComponent,
SocialMediaComponent,
LoggedInHomeComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
**button creation code home.component.html**
<div class="about-us">
<button class="button-box" type="button">
<a [routerLink]="'about-us'" [routerLinkActive]="['active']">about-us</a>
</button>
</div>
*My objectives are:
i. Redirect to about us component on click
ii. Open about us component when path is mentioned in url
But neither is working!*
You are missing to import RouterModule from import { RouterModule } from '#angular/router';
Hope you have include RoutingModule in AppRoutingModule. If so try the following code
<a [routerLink]="['about-us']" [routerLinkActive]="['active']">about-us</a>
Have you added router-outlet in
app.component.html file.
Add only above tag & remove everything else from app.component.html if added
Try this & let me know
I am looking at learning Angular 8 with the Angular CLI.
I have added two new components to a core module which i have then imported to the app module.
When I try to render the components in my app html the 'not known element' error is thrown in the console.
I am unsure as to why?
Here is my app.module.ts
import { BrowserModule } from "#angular/platform-browser";
import { NgModule } from "#angular/core";
import { AppComponent } from "./app.component";
import { NoopAnimationsModule } from "#angular/platform-browser/animations";
import { CoreModule } from "./core/core.module";
#NgModule({
declarations: [AppComponent],
imports: [BrowserModule, NoopAnimationsModule, CoreModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
My core.module.ts
import { NgModule } from "#angular/core";
import { CommonModule } from "#angular/common";
import { InputComponent } from "../input/input.component";
import { GraphComponent } from "../graph/graph.component";
#NgModule({
declarations: [InputComponent, GraphComponent],
imports: [CommonModule],
exports: [InputComponent, GraphComponent]
})
export class CoreModule {}
app.component.html
<div>
<InputComponent></InputComponent>
<GraphComponent></GraphComponent>
</div>
And an example of one of the custom components:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-input',
templateUrl: './input.component.html',
styleUrls: ['./input.component.scss']
})
export class InputComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
I just realised that I am not referring to the components with the correct selectors!
I should be using: app-input & app-graph in the app.component.html.
I can't figure out how to get directives working in my app. I want to apply a directive to a component, this is it in it's simplest form.
import {Directive, HostBinding} from '#angular/core';
#Directive({
selector: '[directiveSelector]'
})
export class FirstDirective {
#HostBinding() innerText = 'not working';
}
...
import {Component} from '#angular/core';
#Component({
selector: 'home',
template: `
<h1 directiveSelector>Test</h1>`
})
export class HomeComponent {
}
...
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { HomeModule } from "./home/home.module";
import { FirstDirective } from './directives/first.directive';
#NgModule({
imports: [
BrowserModule,
HomeModule
],
declarations: [
AppComponent,
FirstDirective
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Does anyone know what I am missing here? Home renders fine, and is a component wrapped in a module. Also, I cannot get a debugger or alert to fire off in the directive - may be a problem with the template binding?
Declare the FirstDirective in your HomeModule, that should take care of it. Here I assume that your HomeComponent is part of homemodule.
Tried leaving it out myself from a module, and it produced no error but also didn't work.
I've just installed a fresh install of Angular 2. But when I try to inject a service called TestService into a login component like this:
LoginComponent:
import {Component, Inject} from '#angular/core';
#Component({
selector: 'app-login',
template: `
{{ test.test }}
`,
styles: []
})
export class LoginComponent {
constructor(#Inject('test') private test){};
}
App
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 { LoginComponent } from './login/login.component';
import {TestService} from "./test.service";
#NgModule({
declarations: [
AppComponent,
LoginComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
providers: [{provide: 'test', useClass:TestService}],
bootstrap: [AppComponent]
})
export class AppModule { }
TestService
import { Injectable } from '#angular/core';
#Injectable()
export class TestService {
test = 'test';
constructor() { }
}
I receive an error:
error_handler.js:47EXCEPTION: Error in ./AppComponent class AppComponent - inline template:1:25 caused by: Cannot read property 'name' of undefined
What am I doing wrong?
On view you should be using Elvis Operator. Just to make sure test property will ask on test. Currently when initial change detection occurs test.test tries to evaluate binding on view. Since initially test is undefined test.test fails.
{{ test?.test }}