Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error TS2339: Property 'handleError' does not exist on type 'HeroService' with Angular

Alright guys, sorry about this question, as I know there are several already about Typescript when it compiles, but I'm encountering a flavor of this issue that I can't connect the dots with.

I'm trying to follow the Angular Tour of Heroes app, and am trying to finish it up with the chapter on Http, but my hero.service.ts file outputs this error:

error TS2339: Property 'handleError' does not exist on type 'HeroService'

I know from the other questions on here that this most likely has something to do with how Typescript is configured, but there does not seem to be a consistent cause of this issue.

I'm not familiar enough with the idiosyncrasies of Typescript (or Angular) to troubleshoot the issue on my own.

My code right now reads like this:

CODE:

import { Injectable }      from '@angular/core';
import { Headers, Http }   from '@angular/http';

import 'rxjs/add/operator/toPromise';

import { Hero }            from './hero';


@Injectable()
export class HeroService {
private heroesUrl: 'app/heroes'; //URL to web api

constructor(private http: Http) { }

getHeroes(): Promise<Hero[]> {
    return this.http.get(this.heroesUrl)
        .toPromise()
        .then(response => response.json().data as Hero[])
        .catch(this.handleError);
}

getHeroesSlowly(): Promise<Hero[]> {
    return new Promise<Hero[]>(resolve =>
        setTimeout(resolve, 2000))
        .then(() => this.getHeroes());
}

getHero(id: number): Promise<Hero> {
    return this.getHeroes()
        .then(heroes => heroes.find(hero => hero.id === id));
  }
}

I am a bit puzzled by the fact that the error message says it can't find the property on 'HeroService' which is a class created within the program and is not a part of Typescript itself.

My systemjs.config.js file looks like this:

SYSTEMJS.CONFIG:

/**
* System configuration for Angular 2 samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
paths: {
  // paths serve as alias
  'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
  // our app is within the app folder
  app: 'app',
  // angular bundles
  '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
  '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
  '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
  '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
  '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
  '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
  '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
  '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
  // other libraries
  'rxjs':                       'npm:rxjs',
  'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
  app: {
    main: './main.js',
    defaultExtension: 'js'
  },
  rxjs: {
    defaultExtension: 'js'
  },
  'angular2-in-memory-web-api': {
    main: './index.js',
    defaultExtension: 'js'
  }
}
});
})(this);

My package.json file reads like this:

PACKAGE.JSON:

{
"name": "angular2-quickstart",
"version": "1.0.0",
"scripts": {
"start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
"lite": "lite-server",
"postinstall": "typings install",
"tsc": "tsc",
"tsc:w": "tsc -w",
"typings": "typings"
},
"license": "ISC",
"dependencies": {
"@angular/common": "2.0.0",
"@angular/compiler": "2.0.0",
"@angular/core": "2.0.0",
"@angular/forms": "2.0.0",
"@angular/http": "2.0.0",
"@angular/platform-browser": "2.0.0",
"@angular/platform-browser-dynamic": "2.0.0",
"@angular/router": "3.0.0",
"@angular/upgrade": "2.0.0",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.12",
"systemjs": "0.19.27",
"zone.js": "^0.6.23",
"angular2-in-memory-web-api": "0.0.20",
"bootstrap": "^3.3.6"
},
"devDependencies": {
"concurrently": "^2.2.0",
"lite-server": "^2.2.2",
"typescript": "^2.0.2",
"typings":"^1.3.2"
}
}

If this question is a duplicate of some other version of this question that I'm not seeing feel free to direct me to it.

Thank you.

like image 862
Jonathan Bechtel Avatar asked Oct 06 '16 12:10

Jonathan Bechtel


3 Answers

It was somewhat "mentioned" in the ToH tutorial, under the "Error Handling" part in the HTTP chapter. But it wasn't really clear that you needed to add this code part to your "hero.service.ts" file (at least if you tend to not fully read through text):

private handleError(error: any): Promise<any> {
    console.error('An error occurred', error); // for demo purposes only
    return Promise.reject(error.message || error);
 }

I just added it to the bottom inside the HeroService class and all worked. Hope it works for you as well :).

like image 148
voestberg Avatar answered Nov 13 '22 03:11

voestberg


Property 'handleError' does not exist on type 'HeroService'

Functions are properties also.

getHeroes(): Promise<Hero[]> {
    return this.http.get(this.heroesUrl)
        .toPromise()
        .then(response => response.json().data as Hero[])
        .catch(this.handleError);  <=== Where is this? Not in HeroService
}

You need to define a handleError method in the HeroService class

handleError(error) {
  // do something with error
}

Looks like you missed this part of the tutorial :-)

like image 33
Paul Samsotha Avatar answered Nov 13 '22 03:11

Paul Samsotha


From the tutorial itself, you should add the following method to hero.service.ts

private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.error(error);
      this.log(`${operation} failed: ${error.message}`);
      return of(result as T);
    }
}
like image 1
Adarsh V C Avatar answered Nov 13 '22 02:11

Adarsh V C