Svelte 中未执行 Async Axios 调用:尝试使用结果引发 TypeError:无法将未定义或 null 转换为对象;Fetch API 正常工作
摘要
-
上下文
-
实际行为(问题)
-
预期行为
-
最小、可测试、可执行示例
-
数据
-
来源
-
-
注释
-
线索
上下文
我正尝试在 Svelt Webapp 中使用 Axios 从 URL
http://localhost:1337/restaurants
获取 JSON 对象列表。此调用预计在初始化 Svelte 组件时执行,类似于 Svelte 教程:
https://svelte.dev/tutorial/await-blocks
。
实际行为(问题)
当我打开包含 Svelte 组件的网页时,我没有在 Chromium 开发工具网络面板中看到网络调用。
我可以在网页中看到此错误(显然要归功于我的
{:catch
):
TypeError: Cannot convert undefined or null to object
预期行为
当我打开包含 Svelte 组件的网页时,我应该在我的 Chromium 开发工具网络面板中看到网络调用,并且它应该在列表项中显示每个 JSON 对象。
当然,以下不能引发错误:
TypeError: Cannot convert undefined or null to object
最小、可测试、可执行示例
数据
此示例使用 (Strapi) URL
http://localhost:1337/restaurants
,它返回以下 JSON 对象数组:
[{"id":1,"name":"Biscotte Restaurant","description":"Welcome to Biscotte restaurant! Restaurant Biscotte offers a cuisine based on fresh, quality products, often local, organic when possible, and always produced by passionate producers.","published_at":"2021-10-02T20:04:26.780Z","created_at":"2021-10-02T19:40:30.378Z","updated_at":"2021-10-02T20:04:26.816Z","categories":[{"id":2,"name":"Brunch","published_at":"2021-10-02T20:04:03.395Z","created_at":"2021-10-02T19:41:15.186Z","updated_at":"2021-10-02T20:04:03.437Z"}]}]
来源
<script>
import axios from 'axios';
async function getRestaurants() {
return await axios.get('http://localhost:1337/restaurants');
}
let restaurants_promise = getRestaurants();
</script>
<main>
{#await restaurants_promise}
<p>wait...</p>
{:then restaurants}
<p>The restaurants are:</p>
{#each restaurants.data as restaurant}
<li>
{restaurant.name}
</li>
{/each}
{:catch error}
<p style="color: red">{error}</p>
{/await}
</main>
注释
我不想使用 Strapi 的教程
onMount
和
then/catch
块,因为我更喜欢遵循 ​​Svelte 的教程(请参阅 Strapi 的教程:
Strapi 教程
)(“Strapi”是因为实际上
http://localhost:1337/restaurants
是一个 Strapi URL)。我真的尽量坚持使用
https://svelte.dev/tutorial/await-blocks
。
线索
-
使用 Postman,我实际上可以获取 JSON 对象的 URL 列表,以便网络调用可以正常工作。 所以,问题显然出在我的 Svelte 代码上。
-
使用 Fetch API 而不是 Axios,我的代码可以正常工作。我再也看不到“TypeError:无法将未定义或 null 转换为对象”的错误了。
将用户的配置与 axios 的 defaultConfig 合并的代码中似乎存在错误(不知何故 defaultConfig 是
undefined
)。
该问题是在 v0.21.2 中引入的,因此降级到最新的 v0.21.1 暂时应该可以解决问题。
我曾见过 Svelte 在 #await 块中使用 #each 抛出奇怪的错误。我通过在 {#each 之前添加 {#if} 解决了这个问题。
<main>
{#await restaurants_promise}
<p>wait...</p>
{:then restaurants}
<p>The restaurants are:</p>
{#if restaurants.data}
{#each restaurants.data as restaurant}
<li>
{restaurant.name}
</li>
{/each}
{/if}
{:catch error}
<p style="color: red">{error}</p>
{/await}
</main>
此错误已在 Axios v0.26.1 中修复( 变更日志在此处 )