#How can you destructure the SWR data variable?

25 messages · Page 1 of 1 (latest)

finite ermine
#

I have a snippet of code

const fetcher2 : Fetcher<Data,string> = async(...args) => await fetch(...args).then(r=>r.json())

  const {data:{name}} = useSWR("http://localhost:3000/my_api/name", fetcher2)

and with it Data's type:

type Data = {
  name: string,
  vegetable: {
    potato: string
  }
}

You can definitely see that name is there and I can destructure it, but it gives me an error under data saying:
Property 'name' does not exist on type 'Data | undefined'.ts(2339)

Are you not allowed to destructure the data variable received from SWR?

#

!helper

feral falconBOT
#

:warning: Please wait a bit longer. You can ping helpers <t:1689897381:R>.

ashen mica
#

I would guess that probably the type of useSWR declares the data property to be T | undefined

#

if so you have to narrow the type first with a check against undefined before destructuring

#

Yup, it does

#

So then the correct usage is

const {data} = useSWR("http://localhost:3000/my_api/name", fetcher2)
if (data !== undefined) {
  const { name } = data;
}

for instance

#

or just

#
data?.name
finite ermine
#

Is there no way to check if it's undefined on Type declaration instead of using Javascript?

ashen mica
#

Uh, well if the type declares a union with undefined normally that implies that undefined is a potential value for that property and it needs to be handled

#

In this case I would guess it could be undefined when your request is still in flight

#

you could force it away with a typecast but that would be ill advised

finite ermine
ashen mica
#

yes

finite ermine
ashen mica
#

Your application still being in the loading stage is a valid state for your application to be in and needs to be handled properly.

#

Even the first example in the tutorial for that library handles this case, albeit with a check on isLoading instead of data:

#
import useSWR from 'swr'
 
function Profile () {
  const { data, error, isLoading } = useSWR('/api/user/123', fetcher)
 
  if (error) return <div>failed to load</div>
  if (isLoading) return <div>loading...</div>
 
  // render data
  return <div>hello {data.name}!</div>
}
finite ermine
finite ermine
ashen mica
#

did you maybe forget the const in the second destructuring?

#

Because that looks like an error you would get if you are trying to access the global name, i.e. window.name

finite ermine
#

I even tried declaring another const like:

const {data} = useSWR("http://localhost:3000/xxxxx", fetcher2)
const {name} = data