代码之家  ›  专栏  ›  技术社区  ›  Jim

/map等的角度6/rxjs中的导入不正确

  •  2
  • Jim  · 技术社区  · 7 年前

    我得到以下错误,试图更新一个角度6的解决方案。

    ERROR in ../app/AuthService.ts
          TS2339: Property 'of' does not exist on type 'typeof Observable'.
    ERROR in ../app/AuthService.ts
          TS2339: Property 'map' does not exist on type 'Observable<any>'.
    ERROR in ../app/AuthService.ts
          TS2339: Property 'map' does not exist on type 'Observable<boolean>'.
    ERROR in       TS2339: Property 'map' does not exist on type 'Observable<any>'.
    

    我正在使用最新版本的rxjs,并且导入(至少在纸上)看起来是正确的?

    "rxjs": "^6.2.0",
    

    我的档案如下:

    import { Injectable } from "@angular/core";
    import { NGXLogger } from "ngx-logger";
    import { CanActivate, Router } from "@angular/router";
    import { HttpClient, HttpHeaders } from "@angular/common/http";
    import { Observable } from "rxjs";
    import { StorageService } from "./lib/storage/StorageService";
    import { map, catchError } from "rxjs/operators";
    import { of } from "rxjs";
    import * as _ from "lodash";
    
    /**
     * class that represents the access token
     * returned from /connect/token (IdentityServer 4)
     */
    export class Token {
        // ReSharper disable once InconsistentNaming
        access_token: string;
    
        // the user email.
        email: string;
    }
    
    @Injectable()
    export class AuthService {
        /**
         * the access token.
         */
        token: Token;
    
        constructor(
            private readonly http: HttpClient,
            private readonly logger: NGXLogger,
            private readonly storage: StorageService
        ) {
        }
    
        /**
         * return true if the user has a valid token.
         */
        isLoggedIn(): Observable<boolean> {
            return this
                .loadToken()
                .map(_ => this.token && this.token.access_token.length > 0)
                .catch(e => {
                    this.logger.debug(e);
                    this.token = null;
                    return Observable.of(false);
                });
        }
    
        logout() {
            this.logger.info("logging out");
            this.storage.clear("token");
        }
    
        /**
         * login, using the supplied email and password.
         * @param email the email address.
         * @param password the password.
         */
        login(email: string, password: string): Promise<Token> {
            this.logger.info(`user ${email} attempting login`);
            const login = {
                username: email,
                password: password,
                grant_type: "password",
                scope: "api",
                client_id: "api",
                client_secret: "secret"
            };
            const headers: HttpHeaders = new HttpHeaders().set("Content-Type", "application/x-www-form-urlencoded");
            const post = this.http.post<Token>(
                "connect/token",
                this.encodeObjectToParams(login),
                { headers: headers });
            return post
                .toPromise()
                .then((_: Token) => this.token = this.saveToken(_));
        }
    
        register(email: string, password: string, confirmPassword: string): Observable<any> {
            this.logger.info(`user ${email || "<null>"} registration request`);
            const uri = "api/register";
            const registration = {
                email,
                password,
                confirmPassword
            };
            return this.http
                .post<any>(
                    uri,
                    registration)
                .map(_ => _)
                .catch(e => {
                    this.logger.debug(`exception :: ${uri} :: `, e);
                    return Observable.throw(e.error);
                });
        }
    
        /**
         * encode the supplied object to a set of form variables.
         * @param instance the object to encode.
         */
        private encodeObjectToParams(instance: any): string {
            return Object.keys(instance)
                .map(key => encodeURIComponent(key) + "=" + encodeURIComponent(instance[key]))
                .join("&");
        }
    
        /**
         * save the supplied token
         */
        private saveToken = (token: Token): Token => this.storage.save("token", token);
    
        /**
         * attempt to load the token from local storage,
         * and test that it is valid.
         */
        private loadToken() {
            this.logger.debug("loading 'token'");
            const token = this.storage.load<Token>("token");
            return this.testToken(token)
                .map(_ => this.token = token);
        }
    
        /**
         * test that the supplied login token works.
         * @param token the token to test.
         */
        isTokenEmailValid = token => this.http
                .get<any>("api/user")
                .map((response: any) => response !== null && response.isAuthenticated);
        testTokenThrottle = _.throttle(token => {
            this.logger.info(`testing token :: ${JSON.stringify(token)}`);
            return this.isTokenEmailValid(token);
        }, 300000);
        private testToken(token: Token): Observable<boolean> {
            const valid = this.testTokenThrottle(token) || this.isTokenEmailValid(token);
            return valid;
        }
    }
    
    /**
     * Authorisation guard, to ensure that a user
     * not logged in is redirected to the login page.
     */
    @Injectable()
    export class AuthGuard implements CanActivate {
    
        constructor(
            private readonly authService: AuthService,
            private readonly logger: NGXLogger,
            private readonly router: Router) { }
    
        canActivate(): Observable<boolean> {
            this.logger.debug("authorisation guard testing login status");
            return this.authService.isLoggedIn().map(_ => {
                this.logger.info(`authorisation guard :: login status ${_}`);
                if (_)
                    return true;
                this.router.navigate(["login"]);
                return false;
            }).catch(_ => {
                this.logger.info(`authorisation guard :: login error ${_}`);
                this.router.navigate(["login"]);
                return Observable.of(false);
            });
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Ritwick Dey    7 年前

    RxJs 6.0你必须使用 pipe() 运算符,它接受将应用 Observable .

    错误消息 Property 'map' does not exist on type 'Observable<any>' 是有意义的, map 不存在于 可观察的 .

    你不能锁链 Observable.map(...).catch(...) .

    新语法是 Observable.pipe( map(...), catchError(...) )

    例子:

    import { map, catchError } from "rxjs/operators";
    import { of } from "rxjs";
    
    
    isLoggedIn(): Observable<boolean> {
        return this
           .loadToken()
           .pipe(
               map(_ => this.token && this.token.access_token.length > 0),
               catchError(e => {
                   this.logger.debug(e);
                   this.token = null;
                   return of(false);
                 })
            )
     }
    

    一个参考: https://www.academind.com/learn/javascript/rxjs-6-what-changed/#operators-update-path

        2
  •  1
  •   Lia    7 年前
    // rxjs 5    
    import 'rxjs/add/observable/of';
    import 'rxjs/add/operator/map'
    

    import { of } from 'rxjs/observable/of';
    import { map } from 'rxjs/operator/map'
    

    // rxjs 6 alpha
    import { Observable } from 'rxjs';
    import { of } from 'rxjs';
    import { map } from 'rxjs/operators';