terrabyte
terrabyte

Reputation: 375

Property does not exist on type 'never' on JSON array

I'm just trying to fetch some JSON data from a url. The JSON data is formatted like so (reduced to two entries for simplicity):

[
  {
    "id": 1
    "name": "Brett",
    "gender": "male"
   },
  {
    "id": 2
    "name": "Sandra",
    "gender": "female"  
  }
]

I can print profiles using console.log(profiles) and see all the entries in the console, but when i try to access the .name field i get the error

Property 'name' does not exist on type 'never'.

Here is the code for the app:

const URL = 'someurl'

function App() {
    const [curId, setId] = useState(0);
    //const [curProfile, setCurProfile] = useState(undefined);
    const [profiles, setProfiles] = useState([])

    useEffect(() => {
        fetch(URL)
            .then((response) => {
                if (response.ok) {
                    return response.json();
                } else {
                    throw new Error("Something went wrong!");
                }
            })
            .then(
                (response) => {
                    setProfiles(response);
                    setId(1);
                    //setCurProfile(profiles[curId - 1]);
            })
            .catch((error) => {
                console.log(error)
            })
    }, []);

    return (
    <div className="App">
        <p>
            {profiles[curId].name}
        </p>
    </div>
  );
}

export default App;

Also as a side question, I'm having some problems storing the current profile in the curProfile variable. Could someone point me in the right direction for that? Thanks!

Upvotes: 1

Views: 848

Answers (2)

wangdev87
wangdev87

Reputation: 8751

The initial state of profiles is empty array and curId is 0, so profiles[curId] should be undefined thus profiles[curId].name would be error as initial rendering.

You should always check if profiles is empty or not.

return (
    <div className="App">
        {profiles.length > 0 &&
           <p>
            {profiles[curId].name}
           </p>
        }
    </div>
)

Upvotes: 1

cbdeveloper
cbdeveloper

Reputation: 31485

You've got to type your state, otherwise Typescript won't know what to expect. You also need to type the response.

Something like:

type Profile = {
  id: number,
  name: string,
  gender: string
}

const [profiles, setProfiles] = useState <Profile[]> ([]);

(...)

setProfiles(response as Profile[]);

Upvotes: 1

Related Questions