5

I am trying to complete the famous tour of heroes tutorial for Angular (not js!) but using angular-cli to create the project. Everything was fine until the section to use the angular-in-memory-web-api. Yes I did use the command "npm install angular-in-memory-web-api --save" and the dependency is now in my package.json.

There is no error at all when running the app. No compilation error. No run time error in the js console. Nothing is happening. Like if there was no response from the "api server".

I even added some console.debug to be sure that "createDb()" and my "getHeroes()" function are executed.

Any idea where to look at? Here is some of my files.

package.json:

{
"name": "angular-tour-of-heroe",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/router": "^4.0.0",
    "angular-in-memory-web-api": "latest",
    "core-js": "^2.4.1",
    "rxjs": "^5.1.0",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "1.0.6",
    "@angular/compiler-cli": "^4.0.0",
    "@types/jasmine": "2.5.38",
    "@types/node": "~6.0.60",
    "codelyzer": "~2.0.0",
    "jasmine-core": "~2.5.2",
    "jasmine-spec-reporter": "~3.2.0",
    "karma": "~1.4.1",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-coverage-istanbul-reporter": "^0.2.0",
    "protractor": "~5.1.0",
    "ts-node": "~2.0.0",
    "tslint": "~4.5.0",
    "typescript": "~2.2.0"
  }
}

app.module.ts:

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

import {AppRoutingModule} from "./app-routing/app-routing.module";

// Imports for loading & configuring the in-memory web api
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
// import { InMemoryWebApiModule } from 'angular-in-memory-web-api/in-memory-web-api.module';
import {InMemoryDataService} from "./in-memory-data.service";

import { AppComponent } from './app.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
import { HeroesComponent } from './heroes/heroes.component';
import { HeroService } from "./hero.service";
import { DashboardComponent } from './dashboard/dashboard.component';



@NgModule({
  declarations: [
    AppComponent,
    HeroDetailComponent,
    HeroesComponent,
    DashboardComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule,
    HttpModule,
    InMemoryWebApiModule.forRoot(InMemoryDataService)
  ],
  providers: [HeroService],
  bootstrap: [AppComponent]
})
export class AppModule { }

in-memory-data.service.ts:

import { InMemoryDbService } from 'angular-in-memory-web-api';
// import { InMemoryDbService } from 'angular-in-memory-web-api/in-memory-backend.service';

export class InMemoryDataService implements InMemoryDbService {
  createDb() {

    console.debug("createDb");

    let heroes = [
      {id: 11, name: 'Mr. Nice'},
      {id: 12, name: 'Narco'},
      {id: 13, name: 'Bombasto'},
      {id: 14, name: 'Celeritas'},
      {id: 15, name: 'Magneta'},
      {id: 16, name: 'RubberMan'},
      {id: 17, name: 'Dynama'},
      {id: 18, name: 'Dr IQ'},
      {id: 19, name: 'Magma'},
      {id: 20, name: 'Tornado'}
    ];
    return {heroes};
  }
}

hero.service.ts:

import { Injectable } from '@angular/core';
import {Hero} from "./hero";
import {Http} from "@angular/http";
import "rxjs/add/operator/toPromise";

@Injectable()
export class HeroService {

  private heroesUrl = 'api/heroes';  // URL to web api

  constructor(private http: Http) { }

  getHeroes(): Promise<Hero[]> {

    console.debug("getHeroes method");

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

  getHero(id: number): Promise<Hero> {

    return this.getHeroes()
      .then(heroes => heroes.find( hero => hero.id === id));
  }

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

5 Answers 5

1

The problem was caused by my IDE (IntelliJ) that replace the "return this.http..." by a "return new Promise(..."!!

My getHeroes function should be:

getHeroes(): Promise<Hero[]> {

    console.debug("getHeroes method");

    return this.http.get(this.heroesUrl)
      .toPromise()
      .then(response => response.json() as Hero[])
      .catch(this.handleError);
  } 
Sign up to request clarification or add additional context in comments.

Comments

1

I too faced the same issue but due to a different reason.

Initially my workspace did not have the "angular-in-memory-web-api" and I installed it using the "npm install angular-in-memory-web-api --save" command. This installed the angular-in-memory-web-api module version 0.5.0.

When running the app, there was no compilation error neither any error in the console. Even I could see the http.get function invoked in debug mode and returning the control without any error. But the response did not contain data from InMemoryDBService.

After going through a lot of solutions in the web, I tried a weird thing.

  1. I downgraded the version of angular-in-memory-web-api from version 0.5.0 to 0.3.0 in the package.json.
  2. Deleted the existing angular-in-memory-web-api folder from node_modules and issued the command npm install angular-in-memory-web-api. This created a new
    folder with name angular-in-memory-web-api inside node_modules.

And miracle happened, I was able to see the data in the browser screen. :)

Comments

1

The tutorial as of today is a bit confusing on this. in-memory-web-api introduced a breaking change with version 0.5.0 (https://github.com/angular/in-memory-web-api/blob/master/CHANGELOG.md/#050-2017-10-05). The Api result is not wrapped anymore, so every response.json().data must be changed to response.json().

Alternatively the old behaviour of the api can be restored with a parameter.

InMemoryWebApiModule.forRoot(InMemoryDataService, { dataEncapsulation: true }),

Comments

1

use "angular-in-memory-web-api": "~0.5.0" in your package.json.

remove angular-in-memory-web-api from node_modules.

do npm install angular-in-memory-web-api

run your project.

Comments

0

In your HeroService the line

private heroesUrl = 'api/heroes';

should be changed to

private heroesUrl = 'http://localhost:8080/api/heroes';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.