Danijel Boksan
Danijel Boksan

Reputation: 789

TypeError: Cannot read property 'name' of undefined TypeError: Cannot read property 'name' of undefined

I'm working with AngularJS and .net core. Generally idea is with angular I'm presenting data and call WebAPI from .net core. Presenting data it is not a problem, for posting data currently I didn't finish because I have problem with showing form from where I should post.

app.module.ts

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './components/app/app.component'
import { HomeComponent } from './components/home/home.component';
import { HeaderComponent } from './components/shared/header/header.component';
import { SpareTypeListComponent } from './components/spareType/spare-type-list/spare-type-list.component';
import { SpareTypeSummaryComponent } from './components/spareType/spare-type-summary/spare-type-summary.component';
import { SpareTypeService } from "./components/shared/spare-type.service";
import { SpareTypeFormComponent } from './components/spareType/spare-type-form/spare-type-form.component';



export const sharedConfig: NgModule = {
    bootstrap: [ AppComponent ],
    declarations: [
        AppComponent,
        HeaderComponent,
        HomeComponent,
        SpareTypeListComponent,
        SpareTypeSummaryComponent,
        SpareTypeFormComponent
    ],
    imports: [
        BrowserModule,
        ReactiveFormsModule,
        FormsModule,
        HttpModule,
        RouterModule.forRoot([
            { path: '', redirectTo: 'home', pathMatch: 'full' },
            { path: 'home', component: HomeComponent },
            { path: 'spares', component: SpareTypeListComponent },
            { path: '**', redirectTo: 'home' }
        ])
    ],
    providers: [ SpareTypeService ]
};

spare-type-form.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { SpareType } from "../../shared/spare-type.type";
import { SpareTypeService } from '../../shared/spare-type.service';

@Component({
    selector: 'spare-form',
    templateUrl: './spare-type-form.component.html'

})

export class SpareTypeFormComponent implements OnInit {

    @Input() spareType: SpareType

    constructor(private spareTypeService: SpareTypeService) { }

    ngOnInit() {

    }

    onSubmit() {

    }
}

spare-type-form.component.html

<form (ngSubmit)="onSubmit()" #spareTypeForm="ngForm">

        <label for="name">Name:</label>
        <input type="text" class="form-control" name="name" [(ngModel)]="spareType.name" required #name="ngModel" />
        <br />
        <button type="submit" class="btn btn-success btn-lg">Add</button>
</form>

Error

If i from input tag remove [(ngModel)]="spareType.name" required #name="ngModel" form is shown on page without any problem. Where am I made mistake ?

I have follow this example: https://github.com/Vintharas/angular2-step-by-step-05-forms-and-validation/tree/master/src/app/person-details

Where he initialize empty object ?

Parent component

import { Component, OnInit, Input} from '@angular/core';
import { SpareType } from '../../shared/spare-type.type';
import { SpareTypeService } from "../../shared/spare-type.service";

spare-type-list.component.ts

@Component({
    selector: 'spare-type-list',
    templateUrl: './spare-type-list.component.html',
    providers: [SpareTypeService]

})

export class SpareTypeListComponent implements OnInit {


    @Input() spareType: SpareType;

    spareTypes: SpareType[];

    constructor(private spareTypeService: SpareTypeService ) {

    }

    ngOnInit() {
        this.spareTypeService.getSpareTypes()
            .then(types => this.spareTypes = types);
    }
}

spare-type-list.component.html

<spare-form></spare-form>
<h1>Spare Types List</h1>
<p *ngIf="!spareTypes">No Spare Types Found.</p>
<spare-type-summary *ngFor="let spareType of spareTypes" [spareType]="spareType"></spare-type-summary>

Showing data from database is working, only I have problem with form.

Upvotes: 0

Views: 1819

Answers (1)

Define your variable spareType as below, it seems your view render while your object value is null hence not able to access property name of object spareType

@Input() spareType: SpareType = new SpareType();

You can also update object ngOnChange event.

ngOnChanges(changes: any) {
    if (changes.spareType != null && changes.spareType.currentValue == null) {
          this.spareType=new SpareType();
    }       
}

Note: As suggested @AJT_82: "do it in the parent component" is the best approach

Upvotes: 3

Related Questions