I have recently moved to Angular2 RC5 from RC4. Since then I have encountered couple of problems. I'm not sure whether these problems are my because of fault or transitional. My app component looks like this :
import {Component, OnInit} from "#angular/core";
import {SetLocationService} from "./auth/set-location.service";
#Component({
selector : "my-app",
template: `
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
`
})
export class AppComponent implements OnInit{
constructor(
private _setLocationService : SetLocationService
){}
ngOnInit() {
this._setLocationService.setLocation();
}
}
routing :
import {Routes, RouterModule} from '#angular/router';
import {SearchBoxComponent} from "./search/searchBox.component";
import {SearchResultComponent} from "./search/search-result.component";
import {LoginComponent} from "./auth/login.component";
import {SignupComponent} from "./auth/signup.component";
import {LogoutComponent} from "./auth/logout.component";
import {RecoverPasswordComponent} from "./auth/recover-password.component";
import {ProfileComponent} from "./auth/profile.component"
import {AccountComponent} from "./auth/account.component"
const appRoutes: Routes = [
{path : '', component: SearchBoxComponent},
{path : 'login', component: LoginComponent},
{path : 'signup', component: SignupComponent},
{path : 'logout', component: LogoutComponent},
{path : 'profile', component: ProfileComponent},
{path : 'account', component: AccountComponent},
{path : 'user/:uname', component: SearchBoxComponent},
{path : 'recover-password', component: RecoverPasswordComponent},
{path : 'search/:params', component: SearchResultComponent},
{path : '**', component : SearchBoxComponent}
];
export const routing = RouterModule.forRoot(appRoutes);
app module :
// #Modules -> Modules
import {BrowserModule} from '#angular/platform-browser';
import {FormsModule} from '#angular/forms';
import {HttpModule} from '#angular/http';
import {LocationStrategy, HashLocationStrategy} from '#angular/common';
import {NgModule} from '#angular/core';
// import {RouterModule} from '#angular/router';
// #Routes -> routes
import {routing} from "./app.routes";
// #Components - > Components
import {AccountComponent} from "./auth/account.component";
import {AppComponent} from './app.component';
import {ChatBoxComponent} from "./chat/chat-box.component";
import {ChatBoxDirective} from "./chat/chat-box.directive";
import {FooterComponent} from "./layout/footer.component";
import {HeaderComponent} from "./layout/header.component";
import {LoginComponent} from "./auth/login.component";
import {LogoutComponent} from "./auth/logout.component";
import {ProfileComponent} from "./auth/profile.component";
import {RecoverPasswordComponent} from "./auth/recover-password.component";
import {SearchBoxComponent} from "./search/searchBox.component";
import {SearchResultComponent} from "./search/search-result.component";
import {SignupComponent} from "./auth/signup.component";
// #providers - > services
import {AuthService} from "./auth/auth.service";
import {SetLocationService} from "./auth/set-location.service";
import {SearchService} from "./search/search.service";
#NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
routing
],
declarations: [
AccountComponent,
AppComponent,
ChatBoxComponent,
ChatBoxDirective,
FooterComponent,
HeaderComponent,
LoginComponent,
LogoutComponent,
ProfileComponent,
RecoverPasswordComponent,
SearchBoxComponent,
SearchResultComponent,
SignupComponent
],
providers : [
AuthService,
SetLocationService,
SearchService,
{provide: LocationStrategy, useClass: HashLocationStrategy}
],
bootstrap: [
AppComponent,
HeaderComponent,
FooterComponent
]
})
export class AppModule {}
My first problem is if I do not add 1.HeaderComponent, 2.FooterComponent in bootstrap of app.module, none of them(1.HeaderComponent, 2.FooterComponent) get loaded when root route is active (localhost:3000), but the SearchBoxComponent. I am kind of confused, since I did not see adding multiple components in bootstrap this in the official document.
My second problem is almost same as the first one. If I embed a component (seachBoxConmponent) in another component like the following code, seachBoxConmponent component does not get loaded but the other parts.
#Component({
selector: "search-result",
template : `
<seachBox></searchBox>
<div class="tag_list">
<p *ngFor = "let tag of result.obj.tags" class = "tag-li" >
<a [routerLink] = "['/search', tag]" (click) = "onSearchCliked($event, tag)"> {{tag}} </a>
</p>
</div>
`
})
I was wondering , can anyone please help me, I have been working on this problem for last couple of days, still I am stuck here.
Make sure the module that declares a component exports it. Otherwise this component will not be visible to other components trying to use it.
I would suggest creating separate modules for discrete concerns such as search, signup, chat, etc. and following the pattern below to share their components.
I've noticed that Angular2 fails silently when a component being used is not in scope. You'll add a component to the template and it'll just not render, no error. Before RC5 it usually meant you did not specify the desired component in the directives:[] array. With RC5, it probably means you're not exporting the component from the module that declares it and/or importing it in the module that wants to use it.
FooModule declares and exports FooComponent, exposing it for use by other components (potentially in other modules):
#NgModule({
declarations: [FooComponent],
imports: [BrowserModule, FormsModule],
exports: [FooComponent]
})
export class FooModule {}
FooComponent:
#Component({
selector: 'foo',
template: `FOO`
})
export class FooComponent {}
BarModule imports FooModule, gaining access to the components it exposes (namely FooComponent):
#NgModule({
declarations: [BarComponent],
imports: [FooModule, FormsModule],
exports: [BarComponent]
})
export class BarModule {}
BarComponent can access FooComponent and use it in the template:
#Component({
selector: 'bar',
template: `<foo></foo>BAR`
})
export class BarComponent {}
I'm having all sorts of trouble migrating to RC5 too, but only AppComponent should be in your bootstrap. If you only get to a component via the router, then that component should not be in declarations. But that component should use export default class ComponentName.
the way I've been attacking this is commenting everything out and adding components and services one at a time.
Thank you guys for helping me. Finally, I solved the problem. I was actually including ROUTER_DIRECTIVES in HeaderComponent and FooterComponenet. These are the places where conflicts occur. It is because "RouterModule" implicitly provides ROUTER_DIRECTIVES. So, we do not have to include the directive again in any component. I removed this directive and that fixes my problem after almost a week later. I also had to change the old fashioned routerLike style according to the docs.
#Alex Sartan : Thanks very much for explaining the details of the problem. I fix the problem without creating separate modules for discrete concerns. But this is better to keep all the concerns separate. I appreciate your help.
Related
I have two components. Component A and Component B. I want to create a navigation system in component A that on click will load the appropriate element in component B.
I know within the same component we can use routerLink and router-outlet. But how can i achieve the same in my case ??
for example:
Component A
<a routerLink="/userHome"></a>
Component B
<router-outlet></router-outlet>
And my routing module is :
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import {RouterModule, Routes} from '#angular/router';
import {UserHomeMainBodyComponent} from './components/user-home-
main-body/user-home-main-body.component';
import {UserNotificationsBodyComponent} from './components/user-
notifications-body/user-notifications-body.component';
const routes: Routes = [
{ path: 'userHome', component: UserHomeMainBodyComponent},
{path: 'userNotifications', component:UserNotificationsBodyComponent}
];
#NgModule({
declarations: [],
imports: [
CommonModule,
RouterModule.forRoot(routes)
],
exports: [RouterModule]
})
export class AppRoutingModule { }
It is first time To use Angular Now I'm learning angular 7:
- I create a new custom component in
- |src folder
---| app
----|| server (name of my component)
then I added in app.component.html the name of component
I see in the tutorial show in browser
the server component
even if he add it empty element
I do all steps in
server.component.ts file
import { Component } from '#angular/core';
#Component({
selector:'app-server',
templateUrl: './server.component.html'
})
export class ServerComponent {
}
& app.module.ts file
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { ServerComponent } from './server/server.component';
#NgModule({
declarations: [
AppComponent,
ServerComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Have you define your <app-server></app-server> somewhere?
For instance in the app.component.html
<app-navbar></app-navbar>
<app-server></app-server>
<app-footer></app-footer>
Also you will find an example here : https://angular.io/tutorial/toh-pt1
In your app.component.html add :
<app-server></app-server>
Thus you'll see its HTML.
What you did is in fact kind of import it and make it visible to other components declared in AppModule, but you didnt call it actually.
Currently I'm new to Angular. I was learning routing topic but seems to stuck at a point where I want to load new route in main route. My app.module looks like
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import {HttpModule} from '#angular/http';
import {RouterModule, Routes} from '#angular/router';
// COMPONENTS
import {AppProduct} from './product.compnent';
import {AppFamily} from './family.component';
const appRoutes: Routes = [
{path: 'Family', component: AppFamily},
{path: 'Product', component: AppProduct}
]
#NgModule({
imports: [ BrowserModule, HttpModule, RouterModule.forRoot(appRoutes)],
declarations: [ AppComponent, AppFamily, AppProduct],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component
import { Component } from '#angular/core';
import {IProducts} from './IProduct';
import {ProductService} from './products.service'
// FAMILY IMPORTS
import {IFamily} from './IFamily'
import {familyService} from './family.service'
#Component({
selector: 'hello-world-app',
templateUrl: "app/app.component.html",
providers: [ProductService, familyService]
})
export class AppComponent {
iproducts: IProducts[];
familyMembers: IFamily[];
constructor(
private _product: ProductService,
private _family: familyService){
}
ngOnInit():void{
this._family.getAllFamilyMembers()
.subscribe(_successLog => {
this.familyMembers = _successLog;
})
}
}
app.component.html
<ul>
<li>
<a [routerLink]="['/Product']">
Product
</a>
</li>
<li>
<a [routerLink]="['/Family']">
Family
</a>
</li>
</ul>
<router-outlet>
</router-outlet>
Now when I serve my server all goes good except for my /Product and /Family route is loaded in <router-outlet></router-outlet> but I don't want navigation menu to appear when I visit /Product in other words I want that my route should load in parent route no child routing.
Any help would be appreciated !
You should define your children module in your appRoutes constant as this:
{ path: '/childPath',
component: ChildComponent,
children: [
{path: 'about',
loadChildren: './path/to/children.module#ModuleName'}
]
}
The answer by Mr. Deer is correct for lazy loading - however, you don't always want to do that. If you want to just have child components, you should do:
{ path: '/childPath',
component: ChildComponent,
children: [
{path: 'about',
component: SecondChildComponent
]
}
That said, lazy loading is generally preferred.
first of all let me start by saying I'm fully aware that there are a few similar posts related to this console error.
Normally I would refer to those but I have been using Angular2 from scratch for a total of 5 days and this is the first JS framework that I have ever used so trying to relate my problem to another is proving more difficult. Please bear than in mind before tearing me to shreds!
Now moving on to my problem, I have managed to cobble together a very basic scaffold for a site and I've created several components that I'm basically treating as each "page" of the site (in this case, 'home', 'contact', 'navbar', 'footer'). I have started to try and implement routing so that when the URL = '' you get redirected home, or if you put a specific in, it directs you accordingly.
The problem I'm getting is as soon as the site loads I get this console error: "Error: Error in ./HomeComponent class HomeComponent - inline template:1:20 caused by: Maximum call stack size exceeded".
My search so far has told me that somewhere I've got a recurring function, I tried to eliminate the variables (so far all of my classes contain almost 0 code) but I'm still getting this error.
Here is my app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import {HomeComponent} from './home/home.component';
import {ContactComponent} from './contact/contact.component';
// import {ProjectListComponent} from './projectlist/projectlist.component';
// import {ProjectDetailComponent} from './projectdetail/projectdetail.component';
// import {ProjectComponent} from './project/project.component';
import {NavbarComponent} from './navbar/navbar.component';
import {FooterComponent} from './footer/footer.component';
const appRoutes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'contact', component: ContactComponent },
// { path: 'project/:id', component: ProjectDetailComponent },
// {
// path: 'projects',
// component: ProjectListComponent,
// data: { title: 'Projects List' }
// },
{ path: '',
redirectTo: '/home',
pathMatch: 'full'
},
// { path: '**', component: PageNotFoundComponent }
];
#NgModule({
declarations: [
AppComponent,
HomeComponent,
ContactComponent,
// ProjectListComponent,
// ProjectDetailComponent,
// ProjectComponent,
NavbarComponent,
FooterComponent
],
imports: [
RouterModule.forRoot(appRoutes),
BrowserModule,
FormsModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.ts
import { Component } from '#angular/core';
import {HomeComponent} from './home/home.component';
import {ContactComponent} from './contact/contact.component';
// import {ProjectListComponent} from './projectlist/projectlist.component';
// import {ProjectDetailComponent} from './projectdetail/projectdetail.component';
// import {ProjectComponent} from './project/project.component';
import {NavbarComponent} from './navbar/navbar.component';
import {FooterComponent} from './footer/footer.component';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
export class AppComponent {
}
home.component.ts
import {Component} from '#angular/core';
import {HomeService} from './home.service';
#Component({
selector: 'home',
templateUrl: './home.component.html',
providers: [HomeService]
})
export class HomeComponent {
private title;
constructor(homeService: HomeService) {
this.title = homeService.getContent();
}
}
I'm not sure if you need my HTML but here is app.component.html
<navigation></navigation>
<router-outlet></router-outlet>
<footer class="footer"></footer>
and home.component.html (like I said it's basic at the moment)
<home>
<h1>{{title}}</h1>
</home>
I'm pretty baffled so far, I realise there is alot to take in and I'm trying to follow a couple of online courses (it's not being made easy by the changes from beta, most courses seem to be quite old at the moment).
Anyway I really do appreciate any help you can offer me and I most definitely appreciate you taking the time to help this noob be a little less noob.
The problem is that your home.component.html has a <home> tag in it. This cause it to infinitely create new home components which results in your maximum call stack size exceeded error.
Angular is trying to render something like:
<home>
<home>
<home>
...
</home>
</home>
</home>
I have an app module and single component application (made to demonstrate my problem), and getting following error:
Error in ./AppComponent class AppComponent_Host - inline template:0:0 caused by: No provider for UserService! ; Zone: <root> ; Task: Promise.then ; Value:
code for AppModule:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { UserService } from './components/common/userservice';
#NgModule({
imports: [
BrowserModule,
],
declarations: [
AppComponent
],
providers: [UserService],
bootstrap: [AppComponent],
entryComponents: []
})
export class AppModule {
}
Code for my AppComponent:
import { Component} from '#angular/core';
import { UserService} from './userservice';
#Component({
selector: 'App',
template: `<h3>App component</h3>
user name: {{userName}}
`,
providers: []
})
export class AppComponent {
userName: string;
constructor(userService: UserService) {
this.userName = userService.userName;
}
}
My UserService Code:
import { Injectable, EventEmitter } from '#angular/core';
#Injectable()
export class UserService {
obs$: EventEmitter<any> = new EventEmitter<any>()
userName = 'Sherlock Holmes';
}
Now if i add UserService as provider to AppComponent, it will solve the issue. but i dont want to, because i want only one instance of my service in whole application. Even in subModules(feature modules).
according to my understanding, if i add service as provider on module level, then i can just inject it to any component under module.
here is am example i was watching.
Plunker
am using angular2 version: "2.0.0"
The import path is wrong: you use /Common in one and /common right below.
Visual Studio and WebStorm will not show IntelliSense errors for case-sensitivity of paths.
Furthermore, if using Angular 5's AoT template compilation, you can get a "This component is not part of a module" error, even though it is, because the import path is incorrect. Without AoT this will work, so you'll get a surprise when converting to AoT.
Remove your service: UserService from app.module.ts, then add in component:
#Component({
selector: 'App',
template: `<h3>App component</h3>
user name: {{userName}}
`,
providers: [UserService]
})
Hope this will help you.
An additional reason for getting this error - I duplicated a service to a different directory and was updating each file individually. Even though the first file still existed I got this error until I updated app.module.ts.