3

currently i'm practice react-ts fetching json data via async fetcher

sample code is below like this

//Test.tsx
import React, { useState, useEffect } from 'react';
import fetcher from 'api/fetcher';

interface Todo {
  userId: number;
  id: number;
  title: string;
  completed: boolean;
}

const Test: React.FC = () => {
  const [data, setData] = useState<Todo[]| Promise<Todo[]>>([{
    userId: 1,
    id: 1234,
    title: "test",
    completed: false
  }]);

  useEffect(() => {
    const result = fetcher("https://jsonplaceholder.typicode.com/todos");
    setData(result);
    console.log(result);
  }, [])
  return (
    <div>
      //error in here
      **{data && data.map()}**
        {/* {data && data.map((item: Todo)=> {
          <div>{item.id}<div>
        })} */}
  </div>
  );
}
export default Test;
//fetcher.ts
async function fetcher(url: RequestInfo) {
  try {
    const res = await fetch(url);
    const json = await res.json();
    console.log("json: ", json);
    return json;
  } catch (e) {
    throw e;
  }
}

export default fetcher;

Error Message : Property 'map' does not exist on type 'Todo[] | Promise'. Property 'map' does not exist on type 'Promise'

i know map method can't using at Promise Object. due to async call, initial data type is set to be Promise type, and switched to Todo[] when fetch resolved.

how to solve this problem to use map method dynamically

4
  • 1
    You'll need to await the call to fetcher in order to get your todo list out of the promise. Try using the method suggested in this answer in your useEffect. Commented Apr 11, 2020 at 14:56
  • Comment 1 is right and should be marked as the answer. Using useState<Todo[]> will fix this specific error. Commented Oct 11, 2020 at 0:16
  • @CameronLittle i had forgotten to reply.. sry and thx all of u Commented Nov 17, 2020 at 1:25
  • 1
    @bastianwegge thx!! Commented Nov 17, 2020 at 1:25

1 Answer 1

8

You should not set the promise to state instead set the result obtained after promise is resolved. To wait for promise to resolve you can make use of async-await or conventional .then method. Also remove Promise as a type from useState value

const Test: React.FC = () => {
  const [data, setData] = useState<Todo[]>([{
    userId: 1,
    id: 1234,
    title: "test",
    completed: false
  }]);

  useEffect(() => {
    fetcher("https://jsonplaceholder.typicode.com/todos").then((result) => {
        setData(result);
    });
  }, [])
  return (
    <div>
        {data && data.map((item: Todo)=> {
          <div>{item.id}<div>
        })}
  </div>
  );
}
export default Test;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.