简体   繁体   English

http.get()失败,因为Promise and Observable

[英]http.get() fails as Promise and Observable

I have two simple services. 我有两个简单的服务。 Both should return the result of a REST API. 两者都应返回REST API的结果。

Originally I've started with a Promise. 最初,我从Promise开始。 I could not figure out, why toPromise() was not found (same problem as here . 我不知道为什么未找到toPromise() (与此处存在相同的问题)。

So I tried to switch to Observable. 所以我试图切换到Observable。 The problem is similar: map() could not be found. 问题相似:找不到map()

Let me give you plenty of code... 让我给你很多代码...

// package.json
{
  "name": "mvc-angular-2",
  "version": "0.0.1",
  "license": "ISC",
  "scripts": {
    "start": "tsc && concurrently \"npm run tsc:w\" ",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings"
  },
  "dependencies": {
    "@angular/common": "2.0.0-rc.4",
    "@angular/compiler": "2.0.0-rc.4",
    "@angular/core": "2.0.0-rc.4",
    "@angular/forms": "0.2.0",
    "@angular/http": "2.0.0-rc.4",
    "@angular/platform-browser": "2.0.0-rc.4",
    "@angular/platform-browser-dynamic": "2.0.0-rc.4",
    "@angular/router": "3.0.0-beta.1",
    "@angular/router-deprecated": "2.0.0-rc.2",
    "@angular/upgrade": "2.0.0-rc.4",
    "bootstrap": "^3.3.6",
    "core-js": "^2.4.0",
    "primeng": "^1.0.0-beta.9",
    "primeui": "^4.1.12",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "systemjs": "0.19.27",
    "zone.js": "^0.6.12"
  },
  "devDependencies": {
    "gulp": "^3.9.1",
    "q": "^1.4.1",
    "rimraf": "^2.5.3",
    "typescript": "^1.8.10",
    "typings": "^1.0.4"
  }
}

// typings.json
{
  "globalDependencies": {
    "core-js": "registry:dt/core-js#0.0.0+20160602141332",
    "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
    "node": "registry:dt/node#6.0.0+20160621231320"
  }
}

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "outDir": "../wwwroot/app/"
  },
  "compileOnSave": true,
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}

// systemjs.config.js
/**
 * System configuration for Angular 2 samples
 * Adjust as necessary for your application needs.
 */
(function (global) {
    // map tells the System loader where to look for things
    var map = {
        'app': 'app', // 'dist',
        '@angular': 'lib/@angular',
        'rxjs': 'lib/rxjs',
        'primeng': 'lib/primeng'
    };
    // 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' },
        'primeng': { 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);

// main.ts
/// <reference path="../typings/globals/core-js/index.d.ts" />

import { bootstrap }      from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '@angular/http';

import { AppComponent }         from './components/app.component';
import { appRouterProviders }   from './app.routes';

bootstrap(AppComponent, [
    appRouterProviders,
    HTTP_PROVIDERS,
]);

// app.component.ts
import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';

import './rxjs-operators';

import { PrivilegeService } from '../services/privilege.service';
import { UserService }  from '../services/user.service';

@Component({
    selector: 'my-app',
    templateUrl: "app/app.component.html",
    styleUrls: ["app/app.component.css"],
    directives: [ROUTER_DIRECTIVES],
    providers: [
        PrivilegeService,
        UserService
    ]
})
export class AppComponent {
    title = 'NG App 3.0 Future beta 0.001';
}

// users.components.ts
import { Component, OnInit } from '@angular/core';
import { Router }            from '@angular/router';

import { DataTable, Column } from '../../node_modules/primeng/primeng';

import { User }              from '../models/user';
import { UserService }       from '../services/user.service';

@Component({
    selector: 'my-users',
    templateUrl: 'app/users.component.html',
    providers: [UserService],
    directives: [DataTable, Column]
})
export class UsersComponent implements OnInit {
    users: User[];

    constructor(
        private router: Router,
        private userService: UserService) { }

    getUsers() {
        this.userService
            .getUsers()
            .then(users => this.users = users)
            .catch(error => console.log(error));
    }

    ngOnInit() {
        this.getUsers();
    }

    gotoUserDetails(event) {
        let link = ['/user', event.data.id];
        this.router.navigate(link);
    }
}

// user.service.ts (Promise)
import { Injectable }    from '@angular/core';
import { Headers, Http } from '@angular/http';
import '../rxjs-operators';

import { User } from '../models/user';

@Injectable()
export class UserService {
    private usersUrl = 'http://localhost:25153/users';

    constructor(private http: Http) { }

    getUsers(): Promise<User[]> {
        return this.http.get(this.usersUrl)
            // .toPromise() cannot be found
            .toPromise()
            .then(response => response.json())
            .catch(this.handleError);
    }

    getUser(id: string) {
        return this.getUsers()
            .then(users => users.find(user => user.id === id));
    }

    private handleError(error: any) {
        console.error('An error occurred', error);
        return Promise.reject(error.message || error);
    }
}

// privilege.service.ts (Observable)
import { Injectable }    from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import { Observable }     from 'rxjs/Observable';
import '../rxjs-operators';
import { Privilege } from '../models/privilege';

@Injectable()
export class PrivilegeService {
    private privilegesUrl = 'http://localhost:25153/privileges';

    constructor(private http: Http) { }

    getPrivileges(): Observable<Privilege[]> {
        return this.http.get(this.privilegesUrl)
            // .map() cannot be found, only .forEach(), .lift() and .subscribe() seem to be available
            .map(this.extractData)
            .catch(this.handleError);
    }

    private extractData(res: Response) {
        let body = res.json();
        return body.data || {};
    }

    getPrivilege(id: string) {
        return null;
        //return this.getPrivileges()
        //    .then(privileges => privileges.find(privilege => privilege.id === id));
    }

    private handleError(error: any) {
        console.error('An error occurred', error);
        return Promise.reject(error.message || error);
    }
}

Last but not least: 最后但并非最不重要的:

  • npm -v : 3.10.3 npm -v :3.10.3
  • node -v : v6.3.0 node -v :v6.3.0
  • Visual Studio 2015 Update 3 Visual Studio 2015更新3

I've already deleted the folder node_modules and rebuilt it. 我已经删除了文件夹node_modules并对其进行了重建。 Didn't change a bit. 没改变。

Also, I've tried to build it outside of Visual Studio, but I simply have no idea how to do so. 另外,我尝试在Visual Studio之外构建它,但是我根本不知道如何创建它。 When I enter something like npm run tsc --rootDir .\\app I get the following output: 当我输入类似npm run tsc --rootDir .\\app会得到以下输出:

> mvc-angular-2@0.0.1 tsc C:\Users\Carsten Franke\Documents\Visual Studio 2015\Projects\MVCAngular2\src\Client
> tsc ".\app"

error TS6053: File 'app.ts' not found.

npm ERR! Windows_NT 6.3.9600
npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "run" "tsc" "--rootDir" ".\\app"
npm ERR! node v6.3.0
npm ERR! npm  v3.10.3
npm ERR! code ELIFECYCLE
npm ERR! mvc-angular-2@0.0.1 tsc: `tsc ".\app"`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the mvc-angular-2@0.0.1 tsc script 'tsc ".\app"'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the mvc-angular-2 package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     tsc ".\app"
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs mvc-angular-2
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls mvc-angular-2
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     C:\Users\Carsten Franke\Documents\Visual Studio 2015\Projects\MVCAngular2\src\Client\npm-debug.log

He's perfectly right, there is no file app.ts . 他完全正确,没有文件app.ts That is why I told him to transpile a folder. 这就是为什么我告诉他要转移一个文件夹。 By the way, that's the file and folder structure (stripped by the node_modules' files, the .map files and some Visual Studio specific stuff): 顺便说一下,这就是文件和文件夹结构(由node_modules的文件,.map文件和某些Visual Studio特定的内容剥离):

D:\projects\MVCAngular2\src\Client\
...\app\app.routes.ts
...\app\components
...\app\components\app.component.html
...\app\components\app.component.ts
...\app\components\user-detail.component.html
...\app\components\user-detail.component.ts
...\app\components\users.component.html
...\app\components\users.component.ts
...\app\main.ts
...\app\models
...\app\models\privilege-group.ts
...\app\models\privilege.ts
...\app\models\user.ts
...\app\rxjs-operators.ts
...\app\services
...\app\services\privilege.service.ts
...\app\services\user.service.ts
...\app\tsconfig.json
...\gulpfile.js
...\node_modules\[14.536 node_modules files]
...\package.json
...\Program.cs
...\Startup.cs
...\typings
...\typings.json
...\typings\globals
...\typings\globals\core-js
...\typings\globals\core-js\index.d.ts
...\typings\globals\core-js\typings.json
...\typings\globals\jasmine
...\typings\globals\jasmine\index.d.ts
...\typings\globals\jasmine\typings.json
...\typings\globals\node
...\typings\globals\node\index.d.ts
...\typings\globals\node\typings.json
...\typings\index.d.ts
...\web.config
...\wwwroot
...\wwwroot\app
...\wwwroot\app\app.routes.js
...\wwwroot\app\components
...\wwwroot\app\components\app.component.js
...\wwwroot\app\components\user-detail.component.js
...\wwwroot\app\components\users.component.js
...\wwwroot\app\main.js
...\wwwroot\app\models
...\wwwroot\app\models\privilege-group.js
...\wwwroot\app\models\privilege.js
...\wwwroot\app\models\user.js
...\wwwroot\app\rxjs-operators.js
...\wwwroot\app\services
...\wwwroot\app\services\privilege.service.js
...\wwwroot\app\services\user.service.js
...\wwwroot\images\...
...\wwwroot\index.html
...\wwwroot\lib\[copy of node_modules]
...\wwwroot\scripts\...
...\wwwroot\styles\...
...\wwwroot\systemjs.config.js

I found this nice plnkr which uses exactly the same versions as I do and works like a charm. 我发现了这个不错的plnkr ,它使用的版本与我使用的版本完全相同,并且像魅力一样工作。 The only difference I see is that the scripts are transpiled in the browser. 我看到的唯一区别是脚本是在浏览器中转译的。

Any ideas what's wrong? 任何想法有什么问题吗?

Best regards, Carsten 此致Carsten

Looks like you have wrong import. 看来您输入错误。 With your imports you've imported Observalbe object, but didn't import operators. 使用导入,您已经导入了Observalbe对象,但没有导入运算符。 Try to change in your service files: 尝试更改您的服务文件:

import '../rxjs-operators';

to

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/catch';

or in more general way: 或更一般的方式:

import 'rxjs/Rx';

The problem is, that tsc cannot compile folder. 问题是, tsc无法编译文件夹。 Simply. 只是。 It requires a file to compile. 它需要一个文件来编译。

If you wanna compile all - you must use one of builders, like gulp - https://www.npmjs.com/package/gulp-typescript or better - webpack, I can recommend this starter - https://github.com/AngularClass/angular2-webpack-starter 如果您想全部编译-您必须使用一种构建器,例如gulp- https ://www.npmjs.com/package/gulp-typescript或更好的版本-webpack,我可以推荐此入门工具-https: //github.com/ AngularClass / angular2-webpack-starter

I used it as a base for one of my company project's, which is now in production 我将其用作公司项目之一的基础,该项目现已投入生产

Or, as alternative - smart IDEs, like WebStorm or whatever - can compile 'on-a-fly' all ts files to js 或者,作为替代方案-智能IDE(如WebStorm或其他工具)可以将所有ts文件“即时”编译为js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM