I’ve developed a function serving as a wrapper for the Fetch API, incorporating additional functionalities. My aim is to initiate an API call to retrieve information about the currently logged-in user for use in various views. Despite successfully reaching the API call and obtaining the requested data, I’m encountering an issue when attempting to access it within the view. Unfortunately, the data is returning as undefined. Any assistance on this matter would be greatly appreciated.
Main Function
function crudHandler(options: IFetchAPIOptions) {
const url = options.url || '';
const contentType = options.contentType || ContentTypes["application/json"];
const failMessage = options.failMessage || '';
const successMessage = options.successMessage || '';
const mode = options.mode || 'cors';
const redirect = options.redirect || 'follow';
const body = options.body || null;
const method = options.method || "GET";
const success = options.success || null
const error = options.error || null
let serverSideMessaging = options.serverSideMessaging || false;
function errorHandler(statusCode: number, errorMessage: string): void {
if (failMessage != null) {
matchBookerAlert('danger', failMessage);
serverSideMessaging = false;
}
if (serverSideMessaging == true) {
matchBookerAlert('danger', statusCode + " - " + errorMessage);
}`
}
function messageHandler(data: IMessageHandler): void {`your text`
if (successMessage.length > 0) {
matchBookerAlert('success', successMessage);
serverSideMessaging = false;
}
if (serverSideMessaging == true && 'SuccessMessage' in data) {
matchBookerAlert('success', data.successMessage);
}
if (serverSideMessaging == true && 'FailMessage' in data) {
matchBookerAlert('danger', data.failMessage);
}
}
await fetch(url, {
method: method,
headers: {
"content-type": contentType
},
mode: mode as RequestMode,
redirect: redirect as RequestRedirect,
body: body,
})
.then(response => {
if (!response.ok) {
if (error !== null) {
error(); //need to know what to pass
}
errorHandler(response.status, response.statusText);
}
return response.json();
})
.then(data => {
if (success !== null) {
success(data);
}
messageHandler(data);
})
.catch(error => {
console.error(error);
});
}
Secondry Function to get the data
function getCurrentUser(){
var data = crudHandler({
url: "/api/AccountApi/GetCurrentUserInfo",
contentType: ContentTypes["application/json"],
});
return data;// I know this is wrong but I don't know how to return the data.
}
Secondary function call
var currentUser = getCurrentUser();
console.log(currentUser);
API Method
[HttpGet]
[Authorize]
[Route("GetCurrentUserInfo")]
public ActionResult GetCurrentUserInfo()
{
var user = UserManager.FindByIdAsync(CurrentUserId).Result;
if (user == null)
return NotFound("User not found");
CurrentUserInfo currentUserInfo = new CurrentUserInfo()
{
FirstName = user.FirstName,
LastName = user.Lastname,
Email = user.Email,
IsAdmin = IsAdmin,
IsBooker = IsBooker,
IsOwner = IsOwner,
};
return Ok(currentUserInfo);
}
I tried to make the call in the index.ts file which is used for the home/index view. FYI I am new to Typescript finished watching tutorials last week.
2
Answers
The problem arose from the asynchronous nature of the fetch method. The currentUser object wasn't being properly set because the getCurrentUser function didn't complete its request before attempting to use the global object. To address this, I eliminated the fetch call from the getCurrentUser function and replaced it with XMLHttpRequest, configuring it to operate synchronously. As a result, the currentUser object is no longer accessed before the getCurrentUser function completes its request.
I am a noobie but I think you have missed
async
keyword before function and you are you usingawait
keyword, if you are usingawait
your function should beasync
.Edit – And
crudhandler
function would returnPromise