【问题标题】:Angular get - map inside mapAngular get - 地图内的地图
【发布时间】:2019-11-10 19:53:09
【问题描述】:

我正在尝试在地图中调用 API 方法,但从未进行过第二次 API 调用。没有控制台错误。

//This method is not being called - Not hitting the API method
this.getUserPermissions(localStorage.getItem('user_ref'));

只是想知道我是否不能在地图内调用地图?

下面是我的代码。

  public isAuthenticated() {

    if (!this.loggedIn)
      this.redirectToLogin();

    return this.httpClient.get<boolean>(`${this.settings.getApiSettings('uri')}/api/auth/IsTokenValid`, {
      params: { token: this.getToken }
    }).map( /// <<<=== use `map` here
      (response) => {

        if (response !== null) {

          var receivedToken = response["securityStamp"];
          var availableToken = localStorage.getItem('access_token');

           //Check if received a refreshed token. (tokens are refreshed every 15 minutes)
          if (receivedToken && receivedToken !== availableToken) {

            localStorage.removeItem('access_token');
            localStorage.setItem('access_token', response["securityStamp"]);

          }

           this.user_permissions = this.getUserPermissions(localStorage.getItem('user_ref'));


        }

        let data = response;
        if (data == null)
          return false;
        else
          return true;

      }
    );

  }

  getUserPermissions(user_ref) {

    if (!this.loggedIn)
      this.redirectToLogin();

    const httpParams: HttpParamsOptions = { userRef: "44C4D2F7-76A0-4714-B8CA-3123F607AC5A" } as HttpParamsOptions;

    const httpOptions = {
      params: new HttpParams(httpParams),
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + this.getToken
      })
    };

    return this.httpClient.get<Array<any>>(`${this.settings.getApiSettings('uri')}/api/auth/GetUserPermissions`, httpOptions).map( /// <<<=== use `map` here
      (response) => {

        if (response["status"] == 401) {
          this.redirectToLogin();
        }
        else if (response["status"] < 200 || response["status"] >= 300) {
          throw new Error('This request has failed ' + response["status"]);
        }

        this.user_permissions = response;
        return response;
      }
    );

  }

【问题讨论】:

  • 你真的在这里使用 Angular7 吗?因为如果你是,你不应该直接使用像 .map 这样的 RxJS 运算符,就像你已经完成的那样,将它链接到 Observable。只是确保我可以提出解决方案。

标签: angular asp.net-web-api angular7


【解决方案1】:

当然,您可以在地图中调用地图,但这里您没有调用 API 的问题是因为您的方法“getUserPermissions”返回的是 Observable,而不是用户的数据。

我建议您按照响应式方法更改这部分的设计。

您可以阅读此link

希望对你有帮助

【讨论】:

    【解决方案2】:

    您使用的是哪个版本的 Angular(更重要的是 rxjs)?

    请记住,HttpClient 返回和 Observable(一个惰性的 observable,在您订阅它之前不会做任何事情)。

    https://angular.io/guide/http

    当您的 isAuthenticated 方法返回一个 HttpClient Get 方法时,您的 isAuthenticated 返回一个等待订阅的可观察对象。

    订阅 HttpClient observable 将进行 http 调用,在收到响应时调用观察者的下一个处理程序,如果提供,还会调用 on complete 处理程序。我建议在这里阅读 Observables。 https://www.learnrxjs.io/

    // Doing this will not do anything as the observable has not been subscribed to.
    this.httpClient.get<boolean>(`...`);
    
    // Subscribing to the HttpClient will make the request
    this.httpClient.get<boolean>(`...`)
        .subscribe((response) => {
    
          // do something with the response
    
    });
    
    

    正如您所说的第一个 HttpCall 已创建,我假设您在调用时订阅了 isAuthenticated 方法?即

    isAuthenticated().subscribe( (response) => {
     //
    })
    

    请注意,您的 getUserPermissions 还返回一个 HttpClient 方法(一个可观察的),但是当您调用它时 this.getUserPermissions(localStorage.getItem('user_ref')); 它永远不会被订阅,因此永远不会被调用。

    要发起第二个请求,您必须订阅 getUserPermissions 调用,如下所示。

    public isAuthenticated() {
    
        // ...
    
        return this.httpClient.get<boolean>('...').map(
          (response) => {
    
               // Subscribe to the second Http call
    
               this.getUserPermissions(localStorage.getItem('user_ref'))
                 .subscribe( (response) => {
                   // do something with the second
               })
           })
    }
    

    一些旁注; 从 rxjs v6 开始,您链接到 httpClient.get 方法的 map 运算符已被弃用,取而代之的是管道运算符。

    见:https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md

    所以这个

    this.httpClient.get<boolean>('...')
        .map( ... )
        .subscribe(...)
    

    现在应该这样写:

    this.httpClient.get<boolean>('...')
      .pipe(        // <- Pipe the operators
        map( ... ),
        map( ... )
      )
      .subscribe( ...)
    

    尽管在最初的问题之外,我会考虑重构您的代码并使用可用的 rxjs/operators 来实现更好的流控制。

    this.httpClient.get<boolean>('...')
        .pipe(       
          map(( response ) => {
            // some logic
            return something;
          }),
          map( (something) => localStorage.getItem('user_ref')),
          switchMap( (userRef) => this.getUserPermissions(userRef)), // <- switchMap to a new observable
        )
        .subscribe( (responseFromGetUserPermissions) => {
           // This value is now the return of getUserPermissions because of switchMap
    
        })
    

    rxjs / observable 是一种非常强大的模式,我强烈建议您花大量时间学习如何充分利用它们。

    问候 城野

    【讨论】:

      【解决方案3】:

      这是因为.map() 函数不返回订阅,而是返回可观察对象。 如果您需要与来自 HttpClient 的 api 调用的响应进行交互,那么您需要订阅您正在调用的 .get().post() 方法。

      这可能会满足您的需求,或者至少在控制台中记录以防请求失败。

      firstUrl = `${this.settings.getApiSettings('uri')}/api/auth/IsTokenValid`;
      secondUrl = `${this.settings.getApiSettings('uri')}/api/auth/GetUserPermissions`;
      
      public isAuthenticated() {
      
          if (!this.loggedIn) this.redirectToLogin();
          return this.httpClient.get<boolean>(this.firstUrl, {params: {token: this.getToken}}).subscribe(
              (response) => {
                  if (response !== null) {
                      let receivedToken = response["securityStamp"];
                      let availableToken = localStorage.getItem('access_token');
                      if (receivedToken && receivedToken !== availableToken) {
                          localStorage.removeItem('access_token');
                          localStorage.setItem('access_token', response["securityStamp"]);
                      }
                      this.user_permissions = this.getUserPermissions(localStorage.getItem('user_ref'));
                  }
                  return response != null;
              },
              (error) => console.log(error)
          );
      }
      
      getUserPermissions(user_ref) {
          if (!this.loggedIn) this.redirectToLogin();
          const httpParams: HttpParamsOptions = {userRef: "44C4D2F7-76A0-4714-B8CA-3123F607AC5A"} as HttpParamsOptions;
          const httpOptions = {
              params: new HttpParams(httpParams),
              headers: new HttpHeaders({
                  'Content-Type': 'application/json',
                  'Authorization': 'Bearer ' + this.getToken
              })
          };
          return this.httpClient.get<Array<any>>(this.secondUrl, httpOptions).subscribe(
              (response) => {
                  if (response["status"] == 401) {
                      this.redirectToLogin();
                  } else if (response["status"] < 200 || response["status"] >= 300) {
                      throw new Error('This request has failed ' + response["status"]);
                  }
                  this.user_permissions = response;
                  return response;
              },
              (error) => console.log(error)
          );
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-14
        • 2012-08-06
        • 2011-03-16
        • 1970-01-01
        • 1970-01-01
        • 2019-11-08
        • 2020-10-03
        • 1970-01-01
        相关资源
        最近更新 更多