【问题标题】:SVELTE : Uncaught (in promise) TypeError: Cannot read property 'profile'SVELTE:未捕获(承诺)类型错误:无法读取属性“配置文件”
【发布时间】:2021-01-07 17:25:39
【问题描述】:

我使用 Svelte 一周,在我的应用程序上使用 cidaas-sdk 进行身份验证后,几秒钟后不显示配置文件数据。页面卡在“...等待”,控制台出现这个错误Uncaught (in promise) TypeError: Cannot read property 'profile' of undefined at Array.create_if_block$1 at create_then_block$2

这里的问题是我必须刷新页面才能显示数据。

我的问题是我无法在登录后直接获取{userInfo.profile.given_name},所以重新加载页面以显示数据是没有用的。 但是当页面重新加载时,一切正常,控制台中没有错误消息。

import cidaas from './helpers/cidaas';
import Profile from './components/profile.svelte';
import { onMount } from 'svelte';
export let title;

$ : isAuth = false;
$ : isLoaded = false;

let promiseHome = Promise.resolve([]);

onMount(async () => {
    promiseHome = cidaas.getUserInfo();
        promiseHome.then(userInfo => {
        
    if(!userInfo) {
        // if you are logged
        if (window.location.href.includes("grant_type=login")) {
            cidaas.loginCallback();
            window.history.replaceState("", "", "/");
            isAuth = true;
            isLoaded = true;
            return;
        }

    }
  isAuth = !!userInfo;
  isLoaded = true;
  return;               
  })        
});

HTML 部分:

{#await promiseHome}
    <div class="mt-5">...Waiting</div>
{:then userInfo} 
    {#if isAuth == true}


    <div class="jumbotron col-md-8 mx-auto">
        
    <div class="hello mt-5 mb-3">Hello {userInfo.profile.given_name}!</div>
    <p>isAuth : {isAuth}</p>
    <p>isLoaded : {isLoaded}</p>
    </div> 
    <Profile/>

    
        {:else}
        <h1 class="mt-5">Bienvenue sur {title}</h1>
        <p>isAuth : {isAuth}</p>
        <p>isLoaded : {isLoaded}</p>
        <button class="btn btn-primary btn-mdir" on:click={loginTo}>Se connecter</button>
        <button class="btn btn-primary btn-mdir" on:click={register}>S'inscrire</button>
    
    {/if}
        {:catch error}
        <p>{error.message}</p>
{/await}

【问题讨论】:

  • 您能否在Svelte REPL 中进行最小限度的复制?我不确定cidaas.getUserInfo() 会返回什么。

标签: javascript promise svelte


【解决方案1】:

我不喜欢 Svelte,但在看了你的描述之后 - 你能检查你的 cidaas.loginCallback() 方法的实现吗?这是一个 Promise 方法,需要await。可能是一个原因,第一次不工作,刷新后工作。

【讨论】:

    【解决方案2】:

    这是没用的:

    $: isAuth = false;
    

    当反应性块包含的任何变量发生变化时,都会重新计算反应性块,但不需要在反应性块中声明变量即可。

    任何顶级let 变量都是反应式的。

    <script>
      let a   // reactive
      const b = 0 // not reactive
      {
        let c // not reactive
      }
      function foo() {
        let d // not reactive
      }
    </script>
    

    所以,只需 let isAuth = false 就足够了,并且仍然是响应式的(并且为 Svelte 节省了一些工作,因为响应式块是比仅仅跟踪单个变量更复杂的机制)。

    现在,你的问题...

    当 Promise 解析为 undefined 时,崩溃发生在您的 then 块中:userInfo.profile.given_name

    我不了解您的全部加载逻辑,因此,如果我现在必须修复此代码,我会替换此代码:

    {:then userInfo} 
        {#if isAuth == true}
    

    用这个:

    {:then userInfo} 
        {#if userInfo && isAuth == true}
    

    【讨论】:

      【解决方案3】:

      我的应用现在正在使用:

      <script>
      import cidaas from './helpers/cidaas';
      import Profile from './components/profile.svelte';
      import { onMount } from 'svelte';
      
      export let title;
      
      let state = {
          isAuth: false,
          isLoaded: false,
          sUserProfile: {}
      }
      
      onMount(async () => {   
              
          cidaas.getUserInfo()
              .then(userInfo => {
                      
                  if(!userInfo) {
                      // if you are logged out
                      if (!window.location.href.includes("grant_type") && window.location.href.includes("state")) {
                          cidaas.logoutCallback();
                          window.history.replaceState("", "", "/");
                          state.isAuth = false;
                      }
                      // if you are logged
                      if (window.location.href.includes("grant_type=login")) {
                          cidaas.loginCallback()
                              .then(response => {
                                  state.sUserProfile = response.profile;          
                                  state.isAuth = true;
                                  window.history.replaceState("", "", "/");
                              });
                      }
                  } else {
                      state.sUserProfile = userInfo.profile;
                      state.isAuth = true
                  }
      
                  state.isLoaded = true;      
          })
      }); 
      
      
      function logout() {
          cidaas.logout();
      }
      
      function loginTo() {
          cidaas.loginWithBrowser();
      }
      
      function register() {
          cidaas.registerWithBrowser();
      }
      
      </script>
      

      HTML:

      <header>
          <nav class="navbar navbar-inverse">
              <div class="container-fluid">
                  <div class="navbar-header">
                      <a class="navbar-brand text-white" href="http://localhost:5000"><img class="logo" src="mdir-white.png" alt="mdir_logo"></a>
                  </div>
                  <ul class="nav navbar-nav">
                      
                  </ul>
                  {#if state.isAuth == true}
                  <ul class="nav navbar-nav navbar-right">
                      <li><button class="btn btn-primary btn-mdir" on:click={logout}>Logout</button></li>
                  </ul>
                  {/if}
              </div>
            </nav>
      </header>
       
      
      <main>
          {#if state.isLoaded}
              {#if !state.isAuth}
                  <h1 class="mt-5">Bienvenue sur {title}</h1>
                  <p>isAuth : {state.isAuth}</p>
                  <p>isLoaded : {state.isLoaded}</p>
                  <button class="btn btn-primary btn-mdir" on:click={loginTo}>Se connecter</button>
                  <button class="btn btn-primary btn-mdir" on:click={register}>S'inscrire</button>
      
              {:else}
              
                  <div class="jumbotron col-md-8 mx-auto">
                                  
                      <div class="hello mt-5 mb-3">Hello {state.sUserProfile.given_name}!</div>
                      <p>isAuth : {state.isAuth}</p>
                      <p>isLoaded : {state.isLoaded}</p>
                  </div> 
                  <Profile/>
              {/if}
              
          {:else}
              <div>...PROBLEM AUTH</div>
          {/if}
      </main>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-17
        • 1970-01-01
        • 1970-01-01
        • 2021-09-25
        • 2018-10-29
        • 2020-12-15
        • 2017-08-12
        • 1970-01-01
        相关资源
        最近更新 更多