Nested components in Angular CLI not accessible after first level - javascript

I'm new in Angular CLI and I'm trying to make my first web based on an older one I've made.
Until now, I'm able to nest and show components inside the root component, but from that point onwards I can't refer to any component in the HTML.
Here's my code:
index.html
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Testing Angular</title>
<base href="/">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FirstComponent } from './first/first.component';
#NgModule({
declarations: [AppComponent, FirstComponent],
imports: [BrowserModule, AppRoutingModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ["./app.component.css"]
})
export class AppComponent {}
app.component.html
<section id="container">
<app-first></app-first>
</section>
<router-outlet></router-outlet>
first.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { SecondComponent } from './second/second.component';
#NgModule({
declarations: [SecondComponent],
imports: [CommonModule]
})
export class FirstModule { }
first.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-first',
templateUrl: './first.component.html',
styleUrls: ["./first.component.css"]
})
export class FirstComponent {}
first.component.html
<div id="first">
<app-second></app-second> <!-- This gives an error: it doesn't know whats Second Component -->
</div>
second.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
#NgModule({
imports: [CommonModule],
declarations: []
})
export class SecondModule { }
second.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-second',
templateUrl: './second.component.html',
styleUrls: ["./second.component.css"]
})
export class SecondComponent {}
second.component.html
<div id="second">
<span>I'm second component!</span>
</div>
The <app-second></app-second> reference gives an error. In Visual Studio Code is not even in the list of suggestions.

You have to include your modules somewhere, angular don't know anything about your SecondComponent, add FirstModule or SecondModule to your AppModule.
Take a look at Angular docs to get more strategies https://angular.io/docs
imports: [BrowserModule, AppRoutingModule, FirstModule],
Modify your FirstModule with adding exports with components which you want to share for others modules.
exports: [SecondComponent]

Related

Angular: my app.component.html is not injecting into index.html <app-root>

This is my first Angular project, and I'm hoping to get some help with some simple data I'm trying to display.
I have a component (AuthorsComponent) that is referenced in my app.modules.ts file in the declarations property and imported into the file. In the modules file, I am also instantiating an AuthorsService class in the providers property to then inject into my AuthorsComponent constructor as a dependency.
// app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AuthorsComponent } from './authors/authors.component';
import { AuthorsService } from './authors.service';
#NgModule({
declarations: [
AppComponent,
AuthorsComponent
],
imports: [
BrowserModule,
AppRoutingModule,
],
providers: [
AuthorsService
],
bootstrap: [AppComponent]
})
export class AppModule { }
// authors.service.ts
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class AuthorsService {
getAuthors() {
return ["author1", "author2", "author3"];
}
}
I use the dependency to invoke a bunk data service array and set it to the authors property in the AuthorsComponent class.
// authors.component.ts
import { Component, OnInit } from '#angular/core';
import { AuthorsService } from '../authors.service';
#Component({
selector: 'authors',
templateUrl: './authors.component.html',
styleUrls: ['./authors.component.css']
})
export class AuthorsComponent implements OnInit {
authors;
constructor(service: AuthorsService) {
this.authors = service.getAuthors();
}
ngOnInit(): void {
}
}
The 'selected' html contains a simple header and a <ul><li></li></ul>. In my <li> I use a *ngFor directive to map? the authors array of strings to the list items.
<h2>{{ authors.length }} Authors</h2>
<ul>
<li *ngFor="let author of authors">
{{ author }}
</li>
</ul>
In the app component I declare a header, which doesn't even load, and my custom component <authors>.
<h1>Angular</h1>
<authors></authors>
Really, this is probably more info than anyone needs, as I cant even get the header <h1>Angular</h1> to render from app.component.html. However, I think it shows that I've done quite a bit of sifting through docs and understanding Angular at a high level (Watch it still be a simple mistake!) Here's the app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
}
and finally, index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>HelloWorld</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
To recap, there is something preventing my index.html <app-root> from receiving my app.component.html. If anyone can spot what might be causing this, it would be greatly appreciated. Thank you for your time!
I just put all of the above code into a Stackblitz and it worked fine.
Check it out here: https://stackblitz.com/edit/angular-simple-app-deborahk
Is it possible the issue is somewhere else in the code?
A few suggestions (though none of these should prevent at least your header from appearing)
Remove this from your module:
providers: [
AuthorsService
],
With the current version of Angular, you should be registering your service using the #Injectable decorator, which you are also doing.
Also, the common pattern for injecting and calling services in a component looks more like this:
authors: string[] = [];
constructor(private service: AuthorsService) { }
ngOnInit(): void {
this.authors = this.service.getAuthors();
}
It's a good idea to strongly type your data.
Using an accessor keyword (such as private) will create a class-level service variable you can access anywhere in the class.
Load your data in ngOnInit instead of the constructor.

Angular component is not rendering | angular 9.1.3

I am not able to render component header in my application. I don't get any error also. In browser, It shows the header tag also but text present in header.component.html is not shown.
app.modules.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
#NgModule({
imports: [ BrowserModule, FormsModule ],
bootstrap: [ AppComponent ],
declarations: [HeaderComponent]
})
export class AppModule { }
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'project',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Project';
}
app.component.html
<header></header>
<p>
Hello World
</p>
header.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent{
}
Please help me. :'(

Custom components are not known elements in Angular CLI app

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.

Directive cannot be used as an entry component in Angular 2

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

Directive not working in application

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.

Categories

Resources