javascript - 吞下消息 : Error: Uncaught (in promise): [object Undefined]

标签 javascript angular promise angular-promise keycloak

我的登录组件在被有关 promise 中 undefined object 的错误消息删除之前短暂显示。

这是 promise 定义:

  static init(): Promise<any> {
    KeycloakClientService.auth.loggedIn = false;
    return new Promise((resolve, reject) => {
      const keycloakConfig = {
      url: environment.KEYCLOAK_URL,
      realm: environment.KEYCLOAK_REALM,
      clientId: environment.KEYCLOAK_CLIENTID,
      'ssl-required': 'external',
      'public-client': true
      };
      const keycloakAuth: any = new Keycloak(keycloakConfig);

      keycloakAuth.init({onLoad: 'check-sso'})
        .success(() => {
          KeycloakClientService.auth.loggedIn = true;
          KeycloakClientService.auth.authz = keycloakAuth;
          KeycloakClientService.auth.logoutUrl = environment.KEYCLOAK_URL
          + '/realms/' + environment.KEYCLOAK_REALM + '/protocol/openid-connect/logout?redirect_uri='
          + document.baseURI;
          console.log('=======>> The keycloak client has been initiated successfully');
          resolve('Succeeded in initiating the keycloak client');
        })
        .error(() => {
          reject('Failed to initiate the keycloak client');
        });
    });
  }

调用者:

KeycloakClientService.init()
  .then(
    () => {
      console.log('The keycloak client has been initialized');
    }
  )
  .catch(
    (error) => {
      console.log(error);
      window.location.reload();
    }
  );

控制台显示两条消息:

The keycloak client has been initiated successfully
The keycloak client has been initialized

我正在使用 Angular 6.0.4 并尝试遵循此 blog

有什么方法可以解决此错误以保持显示我的登录表单?

更新:我尝试使用 observable 而不是 promise,但问题仍然存在:

  public init(): Observable<any> {
    KeycloakClientService.auth.loggedIn = false;
    return new Observable((observer) => {
      const keycloakConfig = {
        'url': environment.KEYCLOAK_URL,
        'realm': environment.KEYCLOAK_REALM,
        'clientId': environment.KEYCLOAK_CLIENTID,
        'ssl-required': 'external',
        'public-client': true
      };
      const keycloakAuth: any = new Keycloak(keycloakConfig);

      keycloakAuth.init({ 'onLoad': 'check-sso' })
        .success(() => {
          KeycloakClientService.auth.loggedIn = true;
          KeycloakClientService.auth.authz = keycloakAuth;
          KeycloakClientService.auth.logoutUrl = environment.KEYCLOAK_URL
            + '/realms/' + environment.KEYCLOAK_REALM + '/protocol/openid-connect/logout?redirect_uri='
            + document.baseURI;
          console.log('The keycloak auth has been initialized');
          observer.next('Succeeded in initiating the keycloak client');
          observer.complete();
        })
        .error(() => {
          console.log('The keycloak client could not be initiated');
          observer.error('Failed to initiate the keycloak client');
        });
    });
  }

完整的源代码可以在 GitHub 上找到。

更新:按照下面的回答,我还尝试使用 then()catch() 关键字,但错误仍然完全相同:

keycloakAuth.init({ 'onLoad': 'check-sso' })
        .then(() => {
          KeycloakClientService.auth.loggedIn = true;
          KeycloakClientService.auth.authz = keycloakAuth;
          KeycloakClientService.auth.logoutUrl = environment.KEYCLOAK_URL
            + '/realms/' + environment.KEYCLOAK_REALM + '/protocol/openid-connect/logout?redirect_uri='
            + document.baseURI;
          console.log('The keycloak auth has been initialized');
          observer.next('Succeeded in initiating the keycloak client');
          observer.complete();
        })
        .catch(() => {
          console.log('The keycloak client could not be initiated');
          observer.error('Failed to initiate the keycloak client');
        });

最佳答案

这是一个大胆的猜测,但可能与 Angular 的区域有冲突。由于这是一个安全库,它可能不喜欢 Angular 用代理替换核心功能。例如,NgZone 修改了 window.setTimeout 和 HTTP 方法。

因此您可以尝试在区域外运行此代码。这里唯一的问题是您使用的是 static 函数,并且必须将其设为可注入(inject)服务,以便您可以访问 NgZone

@Injectable()
export class KeycloakClientService {
    public constructor(private zone: NgZone) {
    }

    public init(): Promise<any> {
        KeycloakClientService.auth.loggedIn = false;
        return new Promise((resolve, reject) => {
            this.zone.runOutsideAngular(() => {
                const keycloakConfig = {
                     url: environment.KEYCLOAK_URL,
                     realm: environment.KEYCLOAK_REALM,
                     clientId: environment.KEYCLOAK_CLIENTID,
                     'ssl-required': 'external',
                     'public-client': true
                };

                const keycloakAuth: any = new Keycloak(keycloakConfig);

                keycloakAuth.init({onLoad: 'check-sso'})
                    .success(() => {
                        KeycloakClientService.auth.loggedIn = true;
                        KeycloakClientService.auth.authz = keycloakAuth;
                        KeycloakClientService.auth.logoutUrl = environment.KEYCLOAK_URL
                            + '/realms/' + environment.KEYCLOAK_REALM + '/protocol/openid-connect/logout?redirect_uri='
                            + document.baseURI;
                        console.log('=======>> The keycloak client has been initiated successfully');
                        resolve('Succeeded in initiating the keycloak client');
                    })
                    .error(() => {
                        reject('Failed to initiate the keycloak client');
                    });
            });
        }
    }
}

这里的变化是使用zone.runOutsideAngular

关于javascript - 吞下消息 : Error: Uncaught (in promise): [object Undefined],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50005495/

相关文章:

javascript - zXml使用问题

javascript - 如何在 JavaScript 中获取和设置 Cosmos Db 延续 token

javascript - Angularjs 自定义过滤器不触发

Angular 8.x e2e 测试无法运行

angular - 如何将 Summernote 编辑器包含到 Angular 2 Webpack 中?

javascript - 如何知道异步 for 循环何时完成?

javascript - 为什么 Promise 构造函数如此冗长?

javascript - 将 promise 添加到我的 Kendo 网格的循环中

angular - 以 Angular 形式使用 rxjs 主题的优点

jquery - 延迟 Angular 的状态?