JavaScript failing to update variable with new value

Alright, so here's the situation. I'm working on a node.js file where I've got a function set up to search for a user in mongodb using specific fields. The goal is to retrieve their account value and then pass it along for further processing. But for some reason, the account variable keeps turning out null. Here's a snippet of what I have:

function checkIfUserExist (name, lobby, socket) {
    var account_ID = null;
    Clients.findOne({ user_name_perm: name }, function (err, result) {
        if (err) {
            console.log("Can't find user with perm name: checkIfUserNameExist");
        } else {
            if (result == null) {
                ...} else {
                console.log("User perm name is: " + result.user_name_perm);
                console.log("result.account_ID: " + result.account_ID);
                account_ID = result.account_ID;
            }
        }
    });
    console.log("Account ID: " + account_ID);


    if (!account_ID == null) {...} else {
        console.log("User doesn't exist");
    }               
}

And when I log everything, this is what shows up:

Account ID: null
User doesn't exist
User perm name is: Peter
result.account_ID: 15555555555

This whole process is really puzzling me. It seems like the function is going through all the steps except for the database lookup first, which ends up leaving account_ID as null initially for evaluation purposes. Then after that, it jumps into the database and does the evaluation later. This just doesn't make sense to me, why is it behaving this way?!

Answer №1

findOne operates asynchronously, meaning that in order to utilize its outcome, you must incorporate a synchronization technique like utilizing continuations or employing callbacks.

Using Continuations

function verifyUserExistence (name, lobby, socket, callback) {
    var accountID = null;
    Clients.findOne({ user_name_perm: name }, function (err, result) {
        // code snippet
        console.log("Account ID:", accountID);

        if (!accountID == null) {
            callback(null, result);
        } else {
            console.log("User does not exist");
            callback(new Error);
        }  
    });                 
}

In this case, you need to invoke verifyUserExistence with an additional argument - a function that is executed once the query is finished and the result is known.

Using Promises

The MongoDB client being utilized likely also returns promises from asynchronous methods.

function verifyUserExistence (name, lobby, socket) {
    var accountID = null;
    return Clients.findOne({ user_name_perm: name })
      .then(function (result) {
          console.log("Account ID:", result.accountID);
          return result;
      }).catch(function (err) {
          // manage error
      });
}

You are now able to chain .then to the return value of verifyUserExistence. However, you still need to supply a callback to the .then method. It could resemble the following:

verifyUserExistence(name, lobby, socket).then(function (result) {
    response.status(200).json(result);
}).catch(function (err) {
    response.status(500).end(err.message);
});

Answer №2

The reason for this issue lies in the concept of asynchrony.

function checkIfUserExist (name, lobby, socket) {
    var account_ID = null;
    Clients.findOne({ user_name_perm: name }, function (err, result) {
        if (err) {
            console.log("Cannot find user with perm name: checkIfUserNameExist");
        } else {
            if (result == null) {
                ...} else {
                console.log("User perm name is: " + result.user_name_perm);
                console.log("result.account_ID: " + result.account_ID);
                account_ID = result.account_ID;
                console.log("Account ID: " + account_ID);

            }
        }
    });

    if (!account_ID == null) {...} else {
        console.log("User doesn't exist");
    }               
}

The issue arises because the callback in findOne is executed after the console log statements. Asynchronous behavior must be dealt with consistently, and I suggest using https://github.com/caolan/async to handle such situations.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incapability of Rearranging Rows in a Group using Row Drag feature in ag-Grid for Angular

Having some trouble with ag-Grid in my Angular project. Specifically, I'm having issues reordering rows within a group using the row drag feature. If you want to take a look at the code snippet causing problems, it's available on CodeSandbox. I ...

Controller receiving empty object array from FormData

I am encountering an issue with my ajax call to the controller, where I am passing FormData() containing an array of objects and other properties. The list array that I pass seems to have 0 elements in the controller. Can anyone assist me with this problem ...

Is it possible for AngularJS to detect $locationChangeSuccess when the page is refreshed?

In my Angular project, I have set up event listener for $locationChangeSuccess using the following code: $scope.$on('$locationChangeSuccess', function(event) { console.log('Check, 1, 2!'); }); While this works perfectly when navigat ...

Find information within Observable

Looking to implement a search input that displays results upon keypress. Currently, this is the code I have: mylist: Observable<MyData[]>; term = new FormControl(); ngOnInit() { this.mylist = this.term.valueChanges .d ...

karma - Plugin not located

Attempting to run JS test cases using karma, but consistently receiving a plugin not found error. Oddly enough, the same configuration file works perfectly for one of my co-workers. Below are the logs: $ karma start karma.conf.js 04 10 2016 17:51:24.755 ...

Disable a button during an AJAX request

Whenever a button is clicked, the record is saved to the database without refreshing the page using AJAX. I have implemented the AJAX code successfully. Now I need guidance on how to manage the state of the Submit button - enabling/disabling it dynamicall ...

Issue an api call when the value retrieved from mongoDB is empty

I am currently working on a project where I am utilizing the MEAN stack. My data is stored in MongoDB and I need to make API calls only if a certain value is null. While I have been able to retrieve the data from the database and call the API successfully, ...

Steps for removing an element from an array after unchecking a checkbox:

My issue involves handling multiple locations - when a particular location is checked, it gets added to an array. However, I am unable to remove it from the array when the checkbox is unchecked. handleChange(e){ if(e.target.checked){ let selec ...

Adding an await tag to dispatch causes issues with performing a react state update on an unmounted component

I recently added an await tag to a redux dispatch and now I am encountering the following error message: index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your applica ...

In my quest to create a basic tic tac toe game using HTML and JavaScript

Struggling to create a straightforward tic tac toe game using html and javascript. Essentially, when a button is clicked, it should change its value to "x". However, despite my efforts, nothing seems to happen upon clicking. <!doctype html> <ht ...

How to handle drop down values with question marks in AngularJS?

Here is the html and js code I am using for the angularjs dropdown. JavaScript code: $scope.yearValues=[ { label : "Year 1 - 1/17 - 6/17", code : "Year 1 - 1/17 - 6/17" }, { label : "Year 2 - 6/17 - 9/18", cod ...

Are the functionalities of my code implemented with Node.js and callback functions comparable to Java Threads?

I am unfamiliar with the Node.js concurrency model. Below is an example of creating Java threads and starting them concurrently. package com.main; class MyThread implements Runnable{ private int num = 0; MyThread(int num){ this.num = num; } ...

Fade-in a new, revised text after fading-out the original text in ReactJS

I have a bunch of p elements that I'd like to cycle through, fading in one at a time and then replacing it with the next. Here is the jQuery example on CodePen: https://codepen.io/motion333/pen/EBBGVM Now, I'm attempting to achieve the same effe ...

Identifying Mistakes to Address Promise Failures

I encountered unhandled promise rejection errors and attempted to catch them and log them after each .then statement. Unfortunately, I ran into an 'unexpected token' issue when running the code on my server due to the period before .try. Despit ...

Toggle the font weight in a text area by clicking a button

I need help with creating a button that will change the font-weight to bold when clicked and then revert back to normal when un-clicked. However, I only want the specific part of the text area where the user clicks the button to be bolded, not the entire t ...

How can I position a div in the center of a fullpage.js slide?

I'm currently utilizing the fullPage.js plugin sourced from this link: . I have successfully implemented vertical slides by using the following HTML code: <div class="section" id="section2"> <div class="slide" id="slide1"> ...

Refresh MySQL database using AJAX

In my form, there are both a submit button and a close button. When a user enters information and clicks the submit button, an answer is posted and saved in the database. If the user chooses to click the close button instead, the entry in the database will ...

Keeping track of the toggle state using a cookie

While searching for a way to retain the toggle state, I stumbled upon js-cookie on GitHub. The documentation provides instructions on creating, reading, and deleting a cookie. However, an example would have been really helpful in enhancing my understanding ...

Creating an expo apk using eas buildWould you like a tool for generating

Following an update to Expo, the process of building apk files using expo build:android -t apk is no longer supported. Instead, it now recommends using eas builds with the command eas build -p android --profile preview. However, this resulted in building a ...

Copying information from one website and transferring it to another website

To verify a user's authentication, I first collect their username and check it against the database to determine their authentication method. Depending on the authentication method, I then provide them with the appropriate login window to access their ...