Why does my Angular2 control need to be included as a provider?

41 views Asked by At

I am trying to learn Angular and have run into what is probably a very simple problem.

I have written a child component for doing grid paging called "PageSelectorComponent". This component just takes a total record count and calculates and displays page links (no providers are used in this component). I have embedded this component inside another component called "TestComponent".

PageSelectorComponent and Test Component are included in the delarations portion of my app.module.ts file.

My issue is that I get the following error:

ERROR Error: Uncaught (in promise): Error: No provider for PageSelectorComponent!

If I add PageSelectorComponent to the providers section of the app.module.ts everything works fine except now I get two instances of the component. This causes my subscribe not to work.

I have looked over how PageSelectorComponent and TestComponent are declared but don't see a difference.

Why does the app complain about not listing PageSelectorComponent as a provider?

Here is the NgMoudle section of my app.modules.ts:

@NgModule({
  declarations: [
    AppComponent,
    NavigationComponent,
    HomeComponent,
    PageSelectorComponent,
    TestComponent,
  ],
  imports: [
    BrowserModule,
    RoutingModule,
  ],
  providers: [
    PageSelectorComponent // App complains if I leave this out but now I get 2 instances of the component.
  ],
  bootstrap: [AppComponent]
})

Here is the definition for PageSelectorComponent:

@Component({
    moduleId: module.id,
    selector: 'app-page-selector',
    templateUrl: './page-selector.component.html',
    styleUrls: ['./page-selector.component.css'],
})

export class PageSelectorComponent {
  // member variables declared here
     .
     .
  private static instanceNum: number = 0; // TOOD: debugging

  constructor() {
    PageSelectorComponent.instanceNum += 1;
    console.log(`page-selector instance number ${PageSelectorComponent.instanceNum}`)
    this.subject = new Subject();
  }

Like I said, I think there is some really basic Angular thing I missed here. Any suggestions on where to look?

Thanks in advance!

1

There are 1 answers

0
David Chu On

Many thanks to masterpreenz for setting me straight on this.

I will answer this to close the thread with how I understand Angular now. Since I am new to this please let me know if I still have it wrong!

As expected this was a basic misunderstanding of the Subject/Observer pattern. As it turns out I was trying to create a new Subject from within component1 for which I was going to have another component2 observe and react to clicks. To get access to the subject of component1, component2 needed to be instantiated in the constructor.

constructor(private pager: coomponent1) {}

This treats component1 like a service (because it is being injected) which is why I needed to include it in both the declarations and providers sections of the app.module.

The way to do this (I am sure not the only way) is to create a service that handles the logic. component1 can then call the service when it is clicked. component2 can then subscribe to the service.

Effectively this allows component2 to react to clicks from component1.