I'm writing the obligatory blog website using Angular2. My site has a BlogIndex component and a BlogService as shown below. The first time BlogIndex is loaded it works fine. However if I attempt to navigate to different component my app crashes with the error message shown below.
BlogIndex.ngOnDestroy is fired when I attempt to navigate away from BlogIndex.
ngOnInit of the component being navigated to is executed.
A second call to BlogIndex.updateIndex is not made when I attempt to navigate away... however if I remove the line of code in the method my app does not crash.
Error Message:
Unable to get property 'map' of undefined or null reference
Stack trace:
TypeError: Unable to get property 'map' of undefined or null reference
at Tree.prototype.pathFromRoot (eval code:30:50)
at _findUrlSegment (eval code:79:5)
at _findStartingNode (eval code:90:9)
at link (eval code:14:5)
at Router.prototype.createUrlTree (eval code:133:9)
at RouterLink.prototype._updateTargetUrlAndHref (eval code:42:9)
at Anonymous function (eval code:17:81)
at Anonymous function (eval code:122:87)
at ZoneDelegate.prototype.invokeTask (http://localhost:61560/lib/zone.js/dist/zone.js:354:18)
at onInvokeTask (eval code:36:25)
App crashes here (I'm not sure what this is)
SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) {
try {
fn.call(this._context, value);
}
catch (err) {
this.unsubscribe();
throw err; // crashes here
}
};
BlogIndex.ts (some code removed)
export class BlogIndex implements OnInit, OnDestroy {
constructor(private blogService: BlogService, private sessionService: SessionService) {
this.ImageRoot = sessionService.ImageRoot;
}
ngOnInit()
{
this.updateIndex();
}
ngOnDestroy()
{
}
updateIndex()
{
// this line causes the error
this.blogService.GetContentItems(this.sessionService.CurrentSite.ID, this.sessionService.CurrentMenuID, this.sessionService.CurrentGroupID)
.subscribe((x: ContentItem[]) => {
this.ContentItems = x;
});
}
}
BlogService.ts (some code removed)
@Injectable()
export class BlogService {
private serviceURL: string;
constructor(private http: Http) {
}
GetContentItems(siteID: number, menuID: number, groupID: number): Observable<ContentItem[]> {
let url = this.serviceURL + 'GetContentItems?siteID=' + siteID.toString() + '&menuID=' + menuID.toString() + '&groupID=' + groupID;
return this.http.get(url)
.map(response => this.extractData(response))
.catch(this.handleError);
}
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let body = res.json();
return body || [];
}
private handleError(error: any) {
let errorMsg = error.message || 'Server error';
console.error(errorMsg);
return Observable.throw(errorMsg);
}
}
*Note: I posted a question with this same error message earlier this week. I included code that I thought was the source of the error however it was incorrect. I've positively identified the offending line of code as marked above.
Update:
I changed my component and service to use a promise instead of observable and I get the exact same error:
BlogIndex:
this.blogService.GetContentItems(this.sessionService.CurrentSite.ID, this.sessionService.CurrentMenuID, this.sessionService.CurrentGroupID)
.then((x: ContentItem[]) => {
this.ContentItems = x;
});
BlogService:
GetContentItems(siteID: number, menuID: number, groupID: number): Promise<ContentItem[]> {
let url = this.serviceURL + 'GetContentItems?siteID=' + siteID.toString() + '&menuID=' + menuID.toString() + '&groupID=' + groupID;
return this.http.get(url).toPromise()
.then(response => this.extractData(response))
.catch(this.handleError);
}