Kevin RED Kevin RED - 3 years ago 124
Node.js Question

angular, title is undefined error

I have the following pieces of a file for a mean stack application.
The server side returns perfect valid data from the MongoDB.

book.ts

export class Book {
isbn: string;
title: string;
author: string;
publisher: string;
price: number;
update_date: Date;
}


book.service.ts

inside this file, I have the following method

showBook(id): Promise<Book> {
return this.http.get('/book/' + id)
.toPromise()
.then(response => response.json() as Book)
.catch(this.handleError);
}


and a component file

book-detail.component.ts

ngOnInit() {
this.getBookDetail(this.route.snapshot.params['id']);
}

// id is passed on via a router.navigate and it is a valid id

getBookDetail(id): void {
console.log('ekgnjk');
this.bookService.showBook(id)
.then(res => {
console.log(res);
this.book = res;
}, (err) => {
console.log(err);
});
}


book-detail.component.html

<div class="container">
<h1>{{book.title}}</h1>
<dl class="list">
<dt>ISBN</dt>
<dd>{{book.isbn}}</dd>
<dt>Title</dt>
<dd>{{book.title}}</dd>
<dt>Author</dt>
<dd>{{book.author}}</dd>
<dt>Publisher</dt>
<dd>{{book.publisher}}</dd>
<dt>Price</dt>
<dd>{{book.price}}</dd>
<dt>Last Updated</dt>
<dd>{{book.updated_at}}</dd>
</dl>
<div class="row">
<div class="col-md-12">
<a [routerLink]="['/books']" class="btn btn-success">Home</a>
</div>
</div>
</div>


My problem is that when I run this app, I get the following error.

cannot read property title of undefined.

Title is the only property that is showing this error.
All other property returns valid data.
Also in the view, I can see my title property.
But in the terminal, I see the above-mentioned error.

But when I change the service code to the following,

book.service.ts

showBook(id): Promise<any> {
return this.http.get('/book/' + id)
.toPromise()
.then(response => response.json())
.catch(this.handleError);
}


My application doesn't show any error.

Why does this happen? And why there is no error showing for other properties.

My MongoDB schema is as shown below;

var mongoose = require('mongoose');

var BookSchema = new mongoose.Schema({
isbn: String,
title: String,
author: String,
publisher: String,
price: Number,
update_date: {
type: Date,
default: Date.now
}
});

module.exports = mongoose.model('Book', BookSchema);

Answer Source

When the view is initialized and tries to show your data binding, you haven't got your book yet, server call works asynchronous, it waits until the call will be back, JS Thread will finish its work and then call the then functions from the event loop to assign the value to your book. At this time (during the above mentioned jobs) your book in undefined. So when it wants to access the property title on the book and because book is undefined, it throws the error

Cannot read property title of undefined

You can use ? safe checking operator in the view or initialize your variable book.

Either <h1>{{book?.title}}</h1> or this.book = new Book(); with appropriate parameters.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download