Zahra Talebi
Zahra Talebi

Reputation: 805

how to get value from a fulfilled promise in react

I have an API that return my expected results in a react project.

I wrote this function to call API and get the results:

async function getUsers() {
  const token = store.getState().token;
  const data = { token };
  await MyApi.getUsers(data)
    .then((result) => {
      console.log(result);
      return result;
    })
    .catch((error) => {
      console.log(error);
      return null;
    });
}

const userList = getUsers();

When I console.log the result in the then section of the function, it printed the expected list of users (that is a json array). But when I console.log the userList it is a promise like bellow image:

enter image description here

that means the returned value of getUsers function is a Promise.

1- How can I get the results from this promise?

2- why the PromiseResult is undefined while the result in then section is a json array?

** these codes are not in the react component

the expected result is:

[
 {
  id: 1,
  name: "user1",
  role: "student"
 },
{
  id: 2,
  name: "user2",
  role: "student"
 },
{
  id: 3,
  name: "user3",
  role: "student"
 },
]

and I want to use userList array to create user card:

<div>
{userList ? (
 userList.map((user) =>
 {
  <Card>
    <h1> user.name </h1>
  </Card>
 }
):
(<h1>user list is empty </h1>)
}

Upvotes: 5

Views: 17395

Answers (3)

Drew Reese
Drew Reese

Reputation: 203587

Issue

why the PromiseResult is undefined while the result in then section is a json array?

getUsers is an async function, so it implicitly returns a Promise but you don't return any resolved value, it simply awaits the MyApi.getUsers promise to resolve and returns nothing, i.e. a void return, or undefined.

In other words, it looks something like the following, logically:

async function getUsers() {
  const token = store.getState().token;
  const data = { token };
  await MyApi.getUsers(data)
    .then((result) => {
      console.log(result);
      return result;
    })
    .catch((error) => {
      console.log(error);
      return null;
    });
  return undefined;
}

Solution

Return the MyApi.getUsers promise.

async function getUsers() {
  const token = store.getState().token;
  const data = { token };
  return MyApi.getUsers(data)
    .then((result) => {
      console.log(result);
      return result;
    })
    .catch((error) => {
      console.log(error);
      return null;
    });
}

Now in your react code you will likely have some useEffect hook calling this function to set some loaded state.

const [userList, setUserList] = useState([]);

useEffect(() => {
  getusers()
    .then(userList => setUserList(userList))
    .catch(error => {
      // handle any error state, rejected promises, etc..
    });
}, []);

Or

const [userList, setUserList] = useState([]);

useEffect(() => {
  const loadUserList = async () => {
    try {
      const userList = await getusers();
      setUserList(userList)
    } catch(error) {
      // handle any error state, rejected promises, etc..
    }
  };

  loadUserList();
}, []);

Upvotes: 6

Mohammed Said Elattar
Mohammed Said Elattar

Reputation: 377

Here is a code snippet it might help you understand it better

//Api response simulation
function fetchUsers() 
{
return Promise.resolve({'name' :'tom'});
}

//async will always return promise
async function getUsers() { 
  const response = await fetchUsers();
  return response;
}

getUsers().then((users) => console.log(users)
 // here you can fill the usersList 
 );

and I think reading this link will help you understand async await deeply https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await

Upvotes: 1

yairmea
yairmea

Reputation: 260

Why do you get Promise {pending} ? The promise will always log pending as long as its results are not resolved yet. Thus, You must call .then() in order to capture the results. If the function in the .then() handler returns a value, then the Promise resolves with that value to the "userList", however in your case .then() returns another promise, thus the next .then() handler will always contain the value you wish to get.

async function getUsers() {
  const token = store.getState().token;
  const data = { token };
  await MyApi.getUsers(data)
    .then((result) => {
      console.log(result);
      return result;
    })
    .catch((error) => {
      console.log(error);
      return null;
    });
}

const userList =getUsers();
console.log(userList ); // Promise  <pending> 
userList.then((result)=> {
console.log(result) // "Some desired value"
})

another option is just to add await getUsers()

async function getUsers() {
  const token = store.getState().token;
  const data = { token };
  await MyApi.getUsers(data)
    .then((result) => {
      console.log(result);
      return result;
    })
    .catch((error) => {
      console.log(error);
      return null;
    });
}

const userList =await getUsers();
console.log(userList ); // "Some desired value"

Upvotes: 1

Related Questions