Angular Component Constructor Called Twice

12,818

Solution 1

Your problem is that in the app.module you bootstrap both parent and child component:

bootstrap:    [ ParentItemComponent, ChildItemsComponent ]

It has to be

  bootstrap:    [ ParentItemComponent]

Solution 2

child-items is not closed properly. Probably because of this error

This

<child-items [parentItemId]="parentItemId">Loading...</<child-items>

should be:

<child-items [parentItemId]="parentItemId">Loading...</child-items>
Share:
12,818

Related videos on Youtube

rwdial
Author by

rwdial

Updated on June 04, 2022

Comments

  • rwdial
    rwdial almost 2 years

    I am new to Angular and am running into an issue with the constructor on a child component being called twice, and the second time it is called it is clearing the properties set the first time.

    This is the parent component:

    @Component({
        selector: 'parent-item',
        templateUrl: '...',
        providers: [ItemService]
    })
    export class ParentItemComponent {
        public parentItemId;
        public model: ParentItem;
    
        constructor(itemService: ItemService, elm: ElementRef) {
            this.parentItemId = elm.nativeElement.getAttribute('parentItemId'); 
            itemService.getParentItem(this.parentItemId).subscribe(data => this.model = data);
        }
    }
    

    And in the template the child component is referenced:

    <child-items [parentItemId]="parentItemId">Loading...</<child-items>
    

    This is the child component:

    @Component({
        selector: 'child-items',
        templateUrl: '...',
        providers: [ItemService]
    })
    export class ChildItemsComponent {
        @Input() public parentItemId: number;
        public items: Observable<ChildItem[]>;
    
        constructor(private itemService: ItemService) {
            console.log("constructor");
        }
    
        ngOnInit() {
            if (this.parentItemId) {
                this.items = this.itemService.getChildItems(this.parentItemId);
            }  
            else {
                console.log("Parent Id not set!");
            }
        }
    }
    

    And finally the child component template:

    <tr *ngFor="let item of items | async">
        <td>...</td>
    </tr>
    

    The child components constructor is being called twice, and the second time it is called the parentItemId is set to null and the items property is cleared. If I hardcode the parentId instead of using the input the data is being properly received and displayed in the template, but using the input value the template shows no results.

    I have created a plunker which shows the same behavior here: http://embed.plnkr.co/xaJtfNgbWCUPap2RCJUA/

    • smnbbrv
      smnbbrv over 7 years
      <child-items [parentItemId]="parentItemId">Loading...</<child-items> is the </< intentionally done that way?
  • John
    John over 5 years
    I used platformBrowserDynamic().bootstrapModule(AppModule) in both main.ts and app.module.ts. Removing the line from app.module.ts made it work in my case.