1

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);
}
  • By the error it looks like this is the offending snippet: .map(response => this.extractData(response)). Please console.log the output of this.http.get(url) – omerts Jun 08 '16 at 13:50
  • Thx omerts, Not sure how to log output but I will try if you can tell me how. The first time the code runs the service runs correctly i.e. http.get(url) returns data I want. When I attempt to navigate away from the control it crashes and it does call the service again (at least no breakpoints are hit). –  Jun 08 '16 at 14:13
  • var test = this.http.get(url); console.log(test); test.map... Also make sure the url is valid. – omerts Jun 08 '16 at 14:16
  • See if this helps: http://stackoverflow.com/questions/34515173/angular-2-http-get-with-typescript-error-http-get-map-is-not-a-function-in?rq=1 – omerts Jun 08 '16 at 14:19
  • I added the log statement and the first time the method is called it produces an object which contains an array containing the data I requested. As stated previously I am unable to log subsequent calls because the app crashes before the method is called. –  Jun 08 '16 at 14:26
  • @omerts added both import statements per the link you posted. no joy :(. –  Jun 08 '16 at 14:34

0 Answers0