7
votes

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.

3

3 Answers

7
votes

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

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.

0
votes

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.