Reputation: 4013
Newbie to Svelte here but have good knowledge on other languages.
I had an API that returns something like this:
{
"data": [
{
"id": 1997,
"place": 2,
"publisher": 4,
"bookid": "01997",
"title": "法律简史——人类制度文明的深层逻辑",
"author": "桑本谦",
"region": "中国大陆",
"copyrighter": null,
"translated": 0,
"purchdate": "2022-09-29",
"price": 89,
"pubdate": "2022-09-01",
"printdate": "2022-09-01",
"ver": "1.1",
"deco": "普通",
"kword": 490,
"page": 477,
"isbn": "978-7-108-07473-7",
"category": "D909.9",
"location": null,
"intro": "费老推荐。一本好书。",
"instock": 1,
"img": "http://lumen/books/image/01997/桑本谦/法律简史——人类制度文明的深层逻辑/600"
}
]
}
In my Svelte app, I created a Book.ts
to declare the type:
export interface Book {
id: number,
bookid: string,
title: string,
author: string,
img: string,
...
}
And also a BookManager.ts
to retrieve data:
import type {Book} from './Book';
export class BookManager {
private base="http://lumen";
async getLatestBook(count=1) : Promise<Book[]>{
const uri=this.base+'/books/latest/'+count;
const ret=await fetch(uri);
const json=await ret.json();
const data=await json['data'] as Book[];
return data;
}
}
In my LatestBook.svelte
, I try to consume this data like below:
<script lang="ts">
import { BookManager } from "../lib/BookManager";
import type { Book } from "../lib/Book";
import { onMount } from "svelte";
var lb: Book;
onMount(async () =>{
const bm=new BookManager();
let lbs=await bm.getLatestBook(1);
lb=lbs[0];
console.log(lb); // This shows the CORRECT data
})
</script>
<div class="col-md-6 col-lg-4 mb-4 development grid-item">
<a
href="#!"
class="text-white bg-dark position-relative d-block overflow-hidden card-hover-2"
>
<img src="../../static/img/projects/1.jpg" alt="{lb.title}" class="w-100 img-zoom" />
<div
class="card-hover-2-overlay position-absolute start-0 top-0 w-100 h-100 d-flex px-4 py-5 flex-column justify-content-between"
>
<div class="card-hover-2-header w-100">
<div class="card-hover-2-title">
<h5 class="fs-4 mb-2">{lb.title}</h5>
</div>
But the page shows a 500
error and the error message is:
TypeError: Cannot read properties of undefined (reading 'title')
What went wrong here? Thanks for your help.
Upvotes: 1
Views: 54
Reputation: 7699
The initial value var lb: Book;
is undefined
so reading the title like this {lb.title}
gives the error
One way would be to write {lb?.title ?? ''}
( ?. / ?? )
or use an #if
block
<script lang="ts">
import { BookManager } from "../lib/BookManager";
import type { Book } from "../lib/Book";
import { onMount } from "svelte";
var lb: Book;
onMount(async () =>{
const bm=new BookManager();
let lbs=await bm.getLatestBook(1);
lb=lbs[0];
})
</script>
{#if lb}
...
<div>
<h5 class="fs-4 mb-2">{lb.title}</h5>
</div>
{/if}
or an #await
block
<script lang="ts">
import { BookManager } from "../lib/BookManager";
import type { Book } from "../lib/Book";
async function fetchBook(): Promise<Book> {
const bm=new BookManager();
let lbs=await bm.getLatestBook(1);
return lbs[0];
})
</script>
{#await fetchBook() then lb}
...
<div>
<h5 class="fs-4 mb-2">{lb.title}</h5>
</div>
{/await}
Upvotes: 2