James
James

Reputation: 2860

Angular 2 error: Unhandled Promise rejection: Template parse errors: More than one component:

I developed a an Angular2 application using the old beta a few months back> I am currently moving this other to a fresh build of the newest (RC5 version) so far with no hitches. That was until I have been getting the following error:

zone.js:484 Unhandled Promise rejection: Template parse errors:
More than one component: ProductComponent,OverlayComponent ("'noscroll': hideBody}">

I have a sub-component product-component which is included as a sub-component of app-component. I include both of these in the app.module.ts fle.

I am not sure what this error means and can find no support for this yet online. Here are the relevant files:

app.module.ts

import './rxjs-extensions';

import { NgModule }       from '@angular/core';
import { BrowserModule }  from '@angular/platform-browser';
import { HttpModule }     from '@angular/http';

import { AppComponent }   from './app.component';
import { ProductComponent }   from './components/product.component';
import { OverlayComponent }   from './components/overlay-component';

import { ProductService }   from './services/product.service';
import { CategoryService }   from './services/category.service';
import { Breadcrumb} from "./directives/breadcrumb";
import { CategoryTree } from "./directives/category-tree";
import { Files } from "./directives/files";
import { Gallery } from "./directives/gallery";
import { OrderInformation } from "./directives/order-information";




@NgModule({
    imports:      [
        BrowserModule,
        HttpModule
    ],
    declarations: [
        AppComponent,
        ProductComponent,
        OverlayComponent,
        Breadcrumb,
        CategoryTree,
        Files,
        Gallery,
        OrderInformation
    ],
    providers: [
        ProductService,
        CategoryService
    ],
    bootstrap:    [ AppComponent ]

})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';
import { Product } from "./classes/Product";
import { ProductService } from "./services/product.service";
import { Category } from "./classes/Category";
import { CategoryService } from "./services/category.service";

@Component({
    selector: 'product-display',
    templateUrl: './app/views/main-view.html'
})

export class AppComponent {
    title = `St. David's Poultry Supplies`;
    menuLoaded = false;
    hideBody = false;
    productsLoaded = false;
    categories = [];
    selectedCategory = null;
    selectedProduct = Product;
    breadcrumbCategories = [];
    products = [];
    APIError = [];

    constructor(
        private _productService: ProductService,
        private _categoryService: CategoryService
    ) {

    }

    getProducts(categoryId = 0) {
        var payload = {
            order           : 'asc',
            order_by        : 'title',
            category_id     : categoryId,
            resize          : true,
            imgHeight       : 200,
            imgWidth        : 200
        };

        this._productService.getProducts(payload)
            .subscribe(
                products => {this.products = products},
                error    => {this.APIError = error},
                ()       => {this.productsLoaded = true}
            );
    }

    getCategories() {
        this.productsLoaded = false;
        this._categoryService.getCategories({
            order           : 'asc',
            order_by        : 'name',
            parent_id       : 0,
            //sub_cats        : true,
            //group_by_parent : true
        })
            .subscribe(
                categories => {this.categories = categories},
                error      => {this.APIError = error},
                ()         => {
                    this.menuLoaded = true,
                        this.productsLoaded = true
                }
            );
    }

    selectCategory(category: Category) {
        this.selectedCategory = category;
        this.breadcrumbCategories.push(category);
    }
    resetFilters() {
        this.getProducts();
        this.getCategories();
        this.selectedCategory = null;
        this.selectedProduct = null;
    }
    private changeCategory(category: Category):void {
        this.productsLoaded = false;
        this.selectCategory(category);
        this.getProducts(category.id);
    }

    ngOnInit() {
        this.getCategories();
        this.getProducts();
    }
}

product.component.ts

import { Component, Input } from '@angular/core';

import { Product } from "../classes/Product";
import { Category } from "../classes/Category";
import { ProductService } from "../services/product.service";

@Component({
    selector: 'product-view',
    templateUrl: './app/views/product-view.html'
})

export class ProductComponent {
    @Input() products: Product[];
    @Input() selectedCategory: Category;
    selectedProduct: Product;
    contentLoaded = false;
    title = "product viewer";
    APIError = [];

    constructor(
        private _productService: ProductService
    ) {
        _productService.emitter.subscribe(
            product  => {
                this.selectedProduct = product;
                this.contentLoaded = true
            }
        );
    }

    selectProduct(product) {
        this.selectedProduct = product;
        this._productService.emitProduct(this.selectedProduct);
    }

    ngAfterContentInit() {
        this.contentLoaded = true;
    }

    private changeSelectedProduct(product, callback) {
        this.selectedProduct = product;
    }
}

There was no problem with this before and I am stumped as to why this error is occurring. Can anyone point me in the right direction?

Thanks

Upvotes: 5

Views: 21005

Answers (3)

Edu Martin
Edu Martin

Reputation: 11

I had this same issue but my problem was a wrong reference of html template

Example:

@Component({
    selector: 'myComponent-form',

    templateUrl: './component/form/index.html', 
    // this doesn't work cause not found the html. I receive template parse error 

    templateUrl: 'index.html', 
    //this work for me cause I have index.html in the same folder

})

Upvotes: 0

Darryl Wagoner WA1GON
Darryl Wagoner WA1GON

Reputation: 1029

I had this problem and my problem was the templateURL didn't match the file name for the HTML file.

Upvotes: 0

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657108

You either need to make the selectors of ProductComponent, OverlayComponent more specific so they don't both apply, or to split your application into several modules so you only have the declarations registered that should actually be applied to the templates in the current module.

If you only have one module, then all components, directives, and pipes of all directives are applied to all components.

Upvotes: 7

Related Questions