Noone
Noone

Reputation: 425

Angular2 component not rendering

I created a plunker, but I don't seem to be able to make it work, when looking in chrome console, there is an error I can't figure out why...

EXCEPTION: TypeError: Cannot read property 'toString' of undefined

https://plnkr.co/edit/a7F616WCoKbSGXzlYGsM?p=preview

Anyway, my question was not about plunker, it was to create the exemple of my bug.

I have a component I want to use in another component, I imported it and added it to the directives: [] of the component decorator and it does not render...

The component is line-list.component, its selector is gb-line-list and I'm trying to use it in this file app/area-list.component.ts.

I feel I'm not clear at all, but I can't make my plunker exemple work properly.

area-detail.component.ts

import {Component, Input, OnInit} from 'angular2/core';
import {RouteParams} from 'angular2/router';

import {LineListComponent} from './line-list.component';
import {Area} from './area.interface';
import {LineService} from './lines.service';

@Component({
    selector: '[gb-area-detail]',
    directives: [LineListComponent],
    template: `
        <div *ngIf="area">
            <h2>{{area.name}} area</h2>
            <gb-line-list [areaId]="area.id"></gb-line-list>
        </div>
    `
})
export class AreaDetailComponent implements OnInit {
    private area: Area;

    constructor(
        private _lineService: LineService,
        private _routeParams: RouteParams){}

    ngOnInit() {
        let id = +this._routeParams.get('id');

        this._lineService.getArea(id)
            .then(area => this.area = area);
    }

}

line-list.component.ts

import {Component, OnInit, Input} from 'angular2/core';

import {LineService} from './lines.service';
import {Line} from './line.interface';

@Component({
    selector: '[gb-line-list]',
    template: `
        <ul>
            <li *ngFor="#line of lines">{{line.name}}</li>
        </ul>
    `
})
export class LineListComponent implements OnInit {
   @Input() areaId: number;

   private lines: Line[];

   constructor (
       private _lineService: LineService) {}

   getLines() {
       this._lineService.getLines(this.areaId)
        .then(lines => this.lines = lines);
   }

   ngOnInit() {
       this.getLines();
   }
}

edit: the real problem is define in there Component not rendering properly

Upvotes: 1

Views: 4338

Answers (1)

Eric Martinez
Eric Martinez

Reputation: 31777

You have an issue in your imports. In the plnkr, in every file where you import LineService you import it from ./lines.service, but that file contains a Component, not a service, therefore you're importing something undefined.

This line for example

import {LineService} from './lines.service';

And in your lines.service.ts file you have this

export class LineListComponent implements OnInit {}

You have no LineService in that file.

The error is not really helpful because of an error in the error message itself (yes, kind of confusing). The error message should actually look like this

ORIGINAL EXCEPTION: Invalid provider - only instances of Provider and Type are allowed, got: undefined

There's a pull request to fix that problem and make the error message to be more helpful.

When you fix that, you'll see that you'll get this error message

Route config should contain exactly one "component", "loader", or "redirectTo" property.

That's because of the same above. You confused your classes in your imports. For example you have this import

import {AreaListComponent} from './area-list.component';

But in area-list.component you defined the AreaDetailComponent class.

You're just importing the classes from the incorrect files, you defined class A in file B, and class B in file A.

Here's your plnkr with the original error reported fixed.

Upvotes: 2

Related Questions