Function undefined when assigned to variable - javascript

I'm working on some authentication in React using Firebase as the backend.
I have a function to check if a user exists that works as I expect:
checkIfUserExists(uid) {
ref.child('users').child(uid).once('value', function(snapshot) {
if (snapshot.exists()) {
console.log("User exists");
return true;
} else {
console.log("User does not exist");
return false;
}
});
}
When I call it passing a uid, it will write to the console if the user exists or not.
this.checkIfUserExists(userId);
I want to just get a boolean representation of whether the user is logged in or not, but trying to do something like this will always print "No user".
if (this.checkIfUserExists(userId)) {
console.log('The user does really exist');
} else {
console.log('No user');
}
If i try to
console.log(this.checkIfUserExists(userId));
The console outputs "undefined".
Am i approaching this the wrong way? Why is it undefined?

The return statement inside the inner function will not return the value through the outer function. Instead try sending a function like this
checkIfUserExists(uid, callback) {
ref.child('users').child(uid).once('value', function(snapshot) {
callback.call(null, snapshot.exists());
});
};
checkIfUserExists(uid, function(exists){
if(exists){
console.log("User exists");
}else{
console.log("User does not exist");
}
});
More on .call() here in documentation

Related

AsyncStorage undefined check

How do I determine if asyncstorage is in
Error rejection
if (await AsyncStorage.getItem("id") == undefined){
alert("yes");
}
If you are trying to check for a failed getItem call (happened to me on simulator, had to reinstall the app for it to work again), you can try to wrap your code in a try-catch, this way :
try {
if (await AsyncStorage.getItem("id") == undefined){
alert("item not found ");
}
} catch(error) {
console.log("getItem function failed", error)
}
A more elegant way of achieving this would be:
const id = await AsyncStorage.getItem("id") // Get the item reference of ID if exists
if (id) {
// Do what you want if ID is actually there
} else {
// Do what you want if ID is not there
}

Promise handling - update db entry if exists

I am stuck with new challenge on Promises.
Goal: Update the DB entry only if P_KEY exists.
current db is exposed through module and module has get and put method for db. Both returning Promise.
Approach:
API calls for update method handler on node js with ID and Set of values (json)
In handler for post method call to get method of db module check if value on promise success is empty or not if yes return false else true.
If true; data exists call to put method of db module.
but somehow data it always returns false. even if db entry has been made through db api.
/** Function to check if p_key exist*/
function checkIfPKExists(idVal){
pkdb.get(idVal).then(function(value){
if(value){
return true;
} else {
return false;
}
},
function(err){
console.log(err);
return false;
})
}
/** UPDATE METHOD **/
var ch = checkIfPKExists("p_k"+req.body.id);
if(!ch){
res.send("pk does not exist oo " + req.body.id);
} else {
var pk_promise = pkdb.put("p_k"+req.body.id, req.body.pk);
pk_promise.then(
function(){
res.send(JSON.stringify(req.body.pk) + "Updated Successfully");
},
function(err){
res.send("Error occurred : " + err);
}
)
}
My understanding is ch value is set from checkPK function and since thats a promise it just goes ahead and processes if loop which by default stands true and done irrespective whether element is there or not same result. Not found.
What can I do to correct it?
One issue is that no value is returned from checkIfPKExists() function call, see Why is value undefined at .then() chained to Promise?. Use .then() and .catch() to get the Promise value returned from the function
function checkIfPKExists(idVal) {
// `return` the `Promise` here
return pkdb.get(idVal).then(function(value) {
if (value) {
return true;
} else {
return false;
}
}, function(err) {
console.log(err);
return false;
})
}
/** UPDATE METHOD **/
var ch = checkIfPKExists("p_k" + req.body.id);
ch.then(function(bool) {
// if `true` do stuff
if (bool) {
var pk_promise = pkdb.put("p_k" + req.body.id, req.body.pk)
return pk_promise.then(function() {
return res.send(JSON.stringify(req.body.pk) + "Updated Successfully");
}, function(err) {
return res.send("Error occurred : " + err);
})
} else {
// do other stuff
return res.send("pk does not exist oo " + req.body.id);
})
.catch(function(err) {
// handle error
})
checkIfPKExists() is an asynchronous function, if you want to use ch you would have to use a .then() to get it in a function and then use the value.
function checkIfPKExists(idVal)
{
return pkdb.get(idVal).then(function(value)
{
if(value)
{
return true;}
else
{
return false;
}
}, function(err)
{ console.log(err);
return false;
})
}
/** UPDATE METHOD **/
checkIfPKExists("p_k"+req.body.id).then(function(ch){
if(!ch)
{
res.send("pk does not exist oo " + req.body.id);
}
else
{
return pkdb.put("p_k"+req.body.id, req.body.pk).then(
function()
{
res.send(JSON.stringify(req.body.pk) + "Updated Successfully");
},
function(err)
{
res.send("Error occurred : " + err);
})
}})

Javascript + ExpressJS - return [something] or return (nothing)?

What is the difference between to return something and to return nothing?
For an example:
user.save(function(err){
if ( err && err.code !== 11000 ) {
console.log(err);
console.log(err.code);
res.send('Another error showed up');
return;
}
//duplicate key
if ( err && err.code === 11000 ) {
req.flash('error', 'User already exists');
res.redirect('/signup');
return;
}
res.locals.user = user;
req.session.user = user;
//res.locals.session = req.session;
res.redirect('/');
});
It seems that it has no difference them at all if I return res; or just return (nothing):
//duplicate key
if ( err && err.code === 11000 ) {
req.flash('error', 'User already exists');
res.redirect('/signup');
return res;
}
It is quite hard for me to understand without returning anything.
So why and what are the reasons we only use return itself?
And for the case like mine above, why don't we return res;?
Firstly, user.save(function callback(){}) that function inside of save() is a callback function, it will invoke after you user data saved to database.
Secondly, user.save() did not expecting any return value, this callback function will just been invoked after save.
so return in this callback function is to break/stop the function go toward running, its mean finished.
Since user.save() didn't expect any return value, so you can return nothing or anything, this return will just tell the function is end, no matter what you return, it will not being used anyway.
Hope this clear your confusion.:)
You dont need to return anything here. Making res.redirect('/') would just redirect you to the appropriate callback
This function is a callback and has no requirement to return anything.
Anything you return wont have any impact on the functionality

Synchronize call back in Angular JS

I am trying synchronize two call backs one from service and one directly called . (This is old code so please ignore code quality)
if($scope.newUser.password == $scope.newUser.password2)
{
// search for the user to see if it already exists
UserValidateService.findUserByEmail($scope.newUser.username, $scope.newUser.email, function(user){
console.log(user);
if(user[0]) {
alert('email Id already exists ******');
return false;
}
}).then(function(){
$http.get("/api/user/"+$scope.newUser.username)
.success(function(newUser) {
// if user does not exist, create it new
if(newUser.length == 0) {
$http.post("/api/user", $scope.newUser)
.success(function(newUser){
if(newUser == null)
alert("Unable to register user");
else
$location.path( $scope.newUser.username+"/home" );
});
}
else
{
alert("User already exists");
}
});
});
}
else
{
alert("Passwords must match. Try again");
}
Service :
app.factory('UserValidateService', function($http){
var findUserByEmail = function (user, email, callback) {
$http.get("/api/user/"+user+"/email/"+email)
.success(callback);
};
return {
findUserByEmail: findUserByEmail
};
});
Error:
TypeError: Cannot read property 'then' of undefined
at h.$scope.register (user.js:118)
at angular.js:10567
at angular.js:18627
at h.$eval (angular.js:12412)
at h.$apply (angular.js:12510)
at HTMLButtonElement.<anonymous> (angular.js:18626)
at HTMLButtonElement.jQuery.event.dispatch (jquery.js:5095)
at HTMLButtonElement.elemData.handle (jquery.js:4766)
Can any please let me where I am going wrong or how to make this code synchronize i.e calling
Your UserValidateService doesn't return a promise, it uses a callback from the $http success method. This is an anti-pattern that should be avoided.
Convert your factory to return the promise from the $http service:
app.factory('UserValidateService', function($http){
var findUserByEmail = function (user, email) {
return $http.get("/api/user/"+user+"/email/"+email)
};
return {
findUserByEmail: findUserByEmail
};
});
Then use the .then method of the promise to execute the callback functionality.
var promise = UserValidateService
.findUserByEmail($scope.newUser.username,
$scope.newUser.email);
var derivedPromise = promise.then ( function(response){
console.log(response.user);
if(response.user[0]) {
alert('email Id already exists ******');
});
//return response for chaining
return response;
});
Subsequent actions can chain off the derivedPromise.

Returning true or false inside functions, I am a bit confused

I have this function, for example:
app.get('/', function(req, res) {
var token = req.query.token;
if(!token) {
res.render('auth'); // Authentication
} else {
authorizedUsers.forEach(function(user) {
if(user.id == token) {
console.log('found, nickname: ' + user.nickname);
return true;
}
});
console.log('not found');
return false;
}
});
Basically it's looping through the authorizedUsers array, and looking for an entry where entry.id equals the token variable.
What I wanted to do is, if found, to return true and stop the execution of the rest of the app.get('/')... block.
If not found, obviously the forEach loop has already gone through all entries, and eventually the execution arrives to the printing of "not found" and return false;.
For my current code, even though an entry is found, execution continues and I still get the 'not found' log.
Am I missing anything?
To simplify things, what I wanna do is:
Looping through all authorizedUsers entries, comparing entry.id to the token variable.
If found, print "found" to the console and stop the execution.
If not found, print "not found" to the console and stop the
execution.
Thank you.
Edit
Following Michael's solution, this is my working code:
app.get('/', function(req, res) {
var token = req.query.token;
if(!token) {
res.render('auth'); // Authentication
} else {
if(!authorizedUsers.some(function(user) {
if(user.id == token)
return true;
})) {
console.log('No entries found.');
} else {
console.log('Entries found!');
}
}
});
You would use Array.prototype.some for this:
authorizedUsers.some(function(user) {
return user.id == token;
}
The some() method tests whether some element in the array passes the test implemented by the provided function.
The forEach function cannot be interrupted unless the code inside throws an exception.
So you could either do something like this
Or just let it run through all the records doing something like this:
var found = false;
authorizedUsers.forEach(function(user) {
if(user.id == token) found = true;
});
console.log('found? ', found);

Categories

Resources