Reputation: 63
I'm creating a user management page in my App where a list of users against user pool groups is consolidated then rendered. I'm using AWS cognito to host the users and groups.
I'm trying to follow best practice principles whereby code is written once, so I have created a separate file for the AWS api call.
I'm having trouble returning the response to the original function.
Here is the container function file:
import ListUsers from "../../../API/cognito/ListUsers";
import { useState, useEffect } from "react";
export default function ManageUsers() {
let groups = ["admin", "ntig-exec", "tlo-officers", "tlo-users"];
const [users, setUsers] = useState();
//const apiUsers = useRef();
useEffect(() => {
async function getUsers() {
let apiUsers = await ListUsers();
console.log("apiUsers: ", apiUsers);
setUsers(apiUsers);
}
getUsers();
}, []);
return (
<h2>demo page</h2>
);
}
and here is the api call file
import AWS from "aws-sdk";
import { useState, useEffect } from "react";
import awsmobile from "../../aws-exports";
import { Auth } from "aws-amplify";
import { onError } from "../../libs/userFeedback/errorLib";
import { useAuthContext } from "../../libs/context/authenticatedLib";
export default async function ListUsers() {
let idToken = "";
await Auth.currentAuthenticatedUser().then((user) => {
idToken = user.signInUserSession.idToken.getJwtToken();
});
AWS.config.region = awsmobile.aws_cognito_region;
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: awsmobile.aws_cognito_identity_pool_id,
RoleArn: myarn,
Logins: { mylogin: idToken }
});
let cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
let params = {
UserPoolId: awsmobile.aws_user_pools_id
};
cognitoidentityserviceprovider.listUsers(params, function (err, result) {
if (err) {
console.log(err);
onError(err);
return;
}
if (result) {
console.log("result", result);
return result;
}
});
}
This is the console log:
apiUsers: undefined
result Object { Users: (6) […] }
I've tried re-writing the code several ways, including trying to make the api call a promise, rather than a callback but I don't have the experience to get it right.
I'm assuming I need to make a change in the container function to wait for the api call to complete.
How do I get the result object to be returned to the apiUsers variable?
Upvotes: 5
Views: 75
Reputation: 1503
Wrap your code in promise in ListUsers() function for api call file and basically pass the value that you want to return to resolve callback and if you get some error, you can pass that error in reject callback.
below is your updated code.
import awsmobile from "../../aws-exports";
import { Auth } from "aws-amplify";
import { onError } from "../../libs/userFeedback/errorLib";
import { useAuthContext } from "../../libs/context/authenticatedLib";
export default async function ListUsers() {
return new Promise((resolve, reject) => {
let idToken = "";
await Auth.currentAuthenticatedUser().then((user) => {
idToken = user.signInUserSession.idToken.getJwtToken();
});
AWS.config.region = awsmobile.aws_cognito_region;
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: awsmobile.aws_cognito_identity_pool_id,
RoleArn: myarn,
Logins: { mylogin: idToken }
});
let cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
let params = {
UserPoolId: awsmobile.aws_user_pools_id
};
cognitoidentityserviceprovider.listUsers(params, function (err, result) {
if (err) {
console.log(err);
//onError(err);
reject(err);
return;
}
if (result) {
console.log("result", result);
// return result;
resolve(result);
}
});
});
}
and since ListUsers() is returning the promise, you have already correctly used await for calling it in an function marked as async in the container function file.
Upvotes: 2