skip to Main Content

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


  1. Chosen as BEST ANSWER

    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.

    let currentUser: ICurrentUser;
    
    function getCurrentUser(): ICurrentUser | void {
        const xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                currentUser =  <ICurrentUser> JSON.parse(this.response);
            }
        }
        xhttp.open("GET", "some request", false);
        xhttp.send();
    }
    
    console.log(currentUser);


  2. I am a noobie but I think you have missed async keyword before function and you are you using await keyword, if you are using await your function should be async.

    Edit – And crudhandler function would return Promise

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search