I have been following the tour of heroes tutorial on the angular2 website step by step but I have come across a little snag when I got to the http section of the tutorial. Why do I keep getting these errors in the console?
"GET http://localhost:3000/app/rxjs-extensions.js 404 (Not Found)"
AND
"Error: Error: XHR error (404 Not Found) loading http://localhost:3000/app/rxjs-extensions.js(…)"
This is my systemjs.config.js:
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'app', // 'dist',
'@angular': 'node_modules/@angular',
'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
'rxjs': 'node_modules/rxjs'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
};
var ngPackageNames = [
'common',
'compiler',
'core',
'forms',
'http',
'platform-browser',
'platform-browser-dynamic',
'router',
'router-deprecated',
'upgrade',
];
// Individual files (~300 requests):
function packIndex(pkgName) {
packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
}
// Bundled (~40 requests):
function packUmd(pkgName) {
packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
}
// Most environments should use UMD; some (Karma) need the individual index files
var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
// Add package entries for angular packages
ngPackageNames.forEach(setPackageConfig);
var config = {
map: map,
packages: packages
};
System.config(config);
})(this);
my app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
// Imports for loading & configuring the in-memory web api
import { HttpModule, XHRBackend } from '@angular/http';
import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { HeroesComponent } from './heroes.component';
import { DashboardComponent } from './dashboard.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroSearchComponent } from './hero-search.component';
import { HeroService } from './hero.service';
@NgModule({
imports: [
BrowserModule,
FormsModule,
routing,
HttpModule
],
declarations: [
AppComponent,
HeroesComponent,
DashboardComponent,
HeroDetailComponent,
HeroSearchComponent
],
providers: [
HeroService,
{ provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
{ provide: SEED_DATA, useClass: InMemoryDataService } // in-mem server data
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
my hero.service.ts:
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() {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[])
.catch(this.handleError);
}
getHero(id: number) {
return this.getHeroes()
.then(heroes => heroes.find(hero => hero.id === id));
}
save(hero: Hero): Promise<Hero> {
if (hero.id) {
return this.put(hero);
}
return this.post(hero);
}
delete(hero: Hero) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let url = `${this.heroesUrl}/${hero.id}`;
return this.http
.delete(url, {headers: headers})
.toPromise()
.catch(this.handleError);
}
// Add new Hero
private post(hero: Hero): Promise<Hero> {
let headers = new Headers({
'Content-Type': 'application/json'});
return this.http
.post(this.heroesUrl, JSON.stringify(hero), {headers: headers})
.toPromise()
.then(res => res.json().data)
.catch(this.handleError);
}
// Update existing Hero
private put(hero: Hero) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let url = `${this.heroesUrl}/${hero.id}`;
return this.http
.put(url, JSON.stringify(hero), {headers: headers})
.toPromise()
.then(() => hero)
.catch(this.handleError);
}
private handleError(error: any) {
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
}
my hero-search.component.ts:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { HeroSearchService } from './hero-search.service';
import { Hero } from './hero';
@Component({
selector: 'hero-search',
templateUrl: 'app/hero-search.component.html',
styleUrls: ['app/hero-search.component.css'],
providers: [HeroSearchService]
})
export class HeroSearchComponent implements OnInit {
heroes: Observable<Hero[]>;
private searchTerms = new Subject<string>();
constructor(
private heroSearchService: HeroSearchService,
private router: Router) {}
// Push a search term into the observable stream.
search(term: string) { this.searchTerms.next(term); }
ngOnInit() {
this.heroes = this.searchTerms
.debounceTime(300) // wait for 300ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time
// return the http search observable
? this.heroSearchService.search(term)
// or the observable of empty heroes if no search term
: Observable.of<Hero[]>([]))
.catch(error => {
// TODO: real error handling
console.log(error);
return Observable.of<Hero[]>([]);
});
}
gotoDetail(hero: Hero) {
let link = ['/detail', hero.id];
this.router.navigate(link);
}
}
my main.ts:
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
import "rxjs/Rx";
platformBrowserDynamic().bootstrapModule(AppModule);
and finally my index.html:
<html>
<head>
<base href="/">
<title>Angular 2 QuickStart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
Add rxjs-extensions.ts file in your app folder. Content of this file looks like below-
// Observable class extensions
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/throw';
// Observable operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
and in your app/app.component.ts, import like this-
import './rxjs-extensions';
See if this helps.
I have had the same issue. Looking at John Papas completed code here-
https://github.com/johnpapa/angular2-tour-of-heroes/blob/master/app/hero-detail.component.ts
He doesn't import it at all. I have just tried commenting it out and it still seems to be working.
Having just completed the routes section, and this is the case. You don't need to import the rxjs as far as i can see.
来源:https://stackoverflow.com/questions/38941329/why-am-i-getting-a-error-loading-rxjs-extensions-in-angular-2