How to pass boolean result in "If condition" - javascript

I have a function in my ionic app to check if user email is already exists in firebase database.
checkValidEmail(email):any{
let result=this.userService.getUserByEmail(email);
console.log(result);
result.subscribe((k:User[])=>{
if(k.length>0){
return true;
}else{
return false;
}
});
}
I am trying to pass its boolen result in following if condition to check whether entered email address is already exists in database. It it exists display an error.
if(this.checkValidEmail(this.user.email)){
console.log("Error : Already has this email address ");
this.error ="Already has this email address in out system";
}
But I cant get true or false into if(this.checkValidEmail(this.user.email)) . Please help I'm new in this.

The result object is an asynchronous stream and the subscribe callback triggers at a later time so checkValidEmail doesn't return a result.
You can use a callback and get that callback to trigger or you could use promises or RxJS observables.
To keep things simple I have changed your code with a simple callback function.
checkValidEmail(email,resultCallback){
let result=this.userService.getUserByEmail(email);
console.log(result);
result.subscribe((k:User[])=>{
if(k.length>0){
resultCallback(true);
}else{
resultCallback(false);
}
});
}
Revise the code as follows
this.checkValidEmail(this.user.email,(isError)=>{
if (isError){
console.log("Error : Already has this email address ");
this.error ="Already has this email address in out system";
}
});

Related

How can this method return an Observable that can be subscribed by the caller method?

I am not so into Angular and RxJS and I am going crazy trying to subscribe an Observable.
This is my code:
createUser(user, file) {
console.log(user);
if (user.password != user.password_confirmation) {
let passwordError: any = new Object();
passwordError["message"] = "Inserted password and inserted password confirmation are different";
this.eventAuthError.next(passwordError);
}
else {
this.afAuth.auth.createUserWithEmailAndPassword(user.email, user.password)
.then(userCredential => {
console.log("INTO THEN !!!")
this.newUser = user;
console.log(userCredential);
userCredential.user.updateProfile({
displayName: user.firstName + ' ' + user.lastName
});
console.log("PROFILE UPDATED !!!");
this.uploadFileIntoFirebaseStore(file);
})
}
}
uploadFileIntoFirebaseStore(fileToBeUploaded) {
var n = Date.now();
const filePath = `user_avatar/${n}`;
const fileRef = this.storage.ref(filePath);
return this.storage.upload(`user_avatar/${n}`, fileToBeUploaded)
.snapshotChanges().subscribe(refStatus => {
console.log("FILE REF: ",
fileRef.getDownloadURL().subscribe(urlStr => console.log("URL STR:", urlStr)));
return fileRef.getDownloadURL();
})
}
As you can see the createUSer() method is my entry point to create a new user on Firebase (basically I have to create a user via e-mail and password, save an image file (that came from my custom user registration form page) into Firebase Storage and then create a new object into FireStore (but this is not implemented at the moment in this code).
As you can see at the end of my createUser() method I am executing my uploadFileIntoFirebaseStore() method by:
this.uploadFileIntoFirebaseStore(file);
This works fine and correctly insert the file into Firebase Storage.
And here happens a thing that I can't understand.
How you can see into this method I am simply subscribing the snapshotChanges() result applied on the storage upload that will "triggered" when my file upload is completed. Into this subscribe I am returning fileRef.getDownloadURL() that is an Obaservable that I can use to retrieve the URL of the uploaded file when the upload is completed.
Ok now I have to retrieve this value (the URL of the uploaded file) into the previous createUser() method (that called this uploadFileIntoFirebaseStore() method) so I tried to change this:
this.uploadFileIntoFirebaseStore(file);
with this:
this.uploadFileIntoFirebaseStore(file).subscribe( bla => console.log("DO SOMETHING"));
And here I have a problem: I can't subscribe this method. I think because I am returning the Observable into an inner arrow function but my method is returning nothing.
How can I fix this situation in such a way that the uploadFileIntoFirebaseStore() return an Observable that can be subscrived into createUser() method?
Or am I missing the point and my reasoning is wrong?
.subscribe is a method of Observable.
this.storage.upload(`user_avatar/${n}`, fileToBeUploaded).snapshotChanges()
The above returns Observable so you were able to subscribe.
But:
this.storage.upload(`user_avatar/${n}`, fileToBeUploaded).snapshotChanges().subscribe()
The above returns Subscription, not an Observable so you cannot subscribe.
A Subscription is an object that represents a disposable resource, usually the execution of an Observable.
https://rxjs-dev.firebaseapp.com/guide/subscription
Solution
You can use .pipe and switchMap operator to manipulate the result from the Observable object of snapshotchanges.
return this.storage.upload(`user_avatar/${n}`, fileToBeUploaded)
.snapshotChanges()
.pipe(
switchMap(refStatus => fileRef.getDownloadURL())
);
https://www.learnrxjs.io/learn-rxjs/operators/transformation/switchmap

Firebase - change remember property dynamically when authenticating

I have a checkbox input in my html which the user can check if he/she wishes to stay logged into the app after the browser has been closed. I would like to change between remember: "default", and remember: "sessionOnly" depending on whether the user checks the box or not.
This is my function to check whether the box in the html is checked or not:
function checkLoginTerm() {
var result;
if(document.getElementById('#loginkeeping').checked) {
result = "sessionOnly";
} else {
result = "default";
}
return result;
}
Then I call the function in my login function to be executed after the user authenticates like this:
function loginUser(username, password) {
if (checkVariable(username)) {var username = document.getElementById("loginUsername").value;}
if (checkVariable(password)) {var password = document.getElementById("loginPassword").value;}
firebaseRef.authWithPassword({
email : username,
password : password
}, function(error, authData) {
if (error) {
alert("Login Failed! "+ error, error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
}, {
remember: checkLoginTerm()
});
}
If I do this, the login process will never complete. But if I put the appropriate string directly after remember: (for example remember: "sessionOnly"), it will do what its told.
As pointed out by Rob DiMarco in the comments below my question, there were two minor issues -
The id of the element is loginkeeping and not #loginkeeping
I had made a logic error in the conditional statement within my checkLoginTerm() function

Email check with jQuery doesn't work

I tried to make Ajax form and tried to make email verification there. I found this solution
http://jsfiddle.net/EFfCa/
but can't turn it on in my script:
<script>
$('#joinForm').ajaxForm(function() {
var testEmail = /^[A-Z0-9._%+-]+#([A-Z0-9-]+\.)+[A-Z]{2,4}$/i;
var name = $("input[name=name]")
var email = $("input[name=email]")
if(name.val()==''||email.val()=='') {
$(".notify").show();
$(".notify p").text('empty');
} else if(testEmail.test(email.value)) {
$(".notify").show();
$(".notify p").text('email is wrong');
} else {
$(".notify").show();
$(".notify p").text('good');
}
});
</script>
The form always passed verification even email is wrong. Verification for empty fields works good...
The following line else if(testEmail.test(email.value)) will return true if the email is correct.
In your logic that's where the email is wrong could that be the problem?
This is because your passing email.value. jquery objects don't have a parameter called value, so this will resolve as undefined.
.test() returns true if it is passed undefined, so your test will always pass.
use .val() instead.
$('input').blur(function() {
var testEmail =/^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
if (testEmail.test(this.value)) alert('passed');
else alert('failed');
});

What are MongoDB Modifiers and Operators?

I am working on a Meteor application and one of the features I'm building is a form that inserts a new document into an array (inserts a shipping address to a user's profile where a user can have multiple addresses). The error I keep getting is:
Exception while invoking method 'addAddress' Error: When the modifier option is true, validation object must have at least one operator
I have been unsuccessfully trying to figure out the answer on Stackoverflow, Github, etc. but could not find a solution. I now want to take the approach of understanding exactly what the error means - so my question is what exactly are modifier options and operators in MongoDB? From what I understand, modifiers provide constraints on what type of data is returned from a query, and operators are used to modify data. Are these definitions correct?
Does anyone know what the error I'm getting might mean? Here is my sample code:
My click event to capture data on a form and call a method to add an address:
Template.editAddress.events({
'click .addAddress': function(e, tmpl) {
e.preventDefault();
var currentUserId = Meteor.userId();
console.log(currentUserId);
var addressDetails = {
address: {
streetAddress: $('#streetAddress').val()
}
};
console.log(addressDetails);
Meteor.call('addAddress', addressDetails, currentUserId, function(error) {
if (error) {
alert(error.reason);
} else {
console.log('success!');
Router.go('Admin');
}
});
}
});
My method to insert the address:
Meteor.methods({
'addAddress': function(addressDetails, currUserId) {
var currentUserId = currUserId;
console.log('user to add address to is ' + currUserId);
Meteor.users.update(currentUserId, {$addToSet:
{
'address.streetAddress': addressDetails.streetAddress
}
});
}
});
Note that when I type that query in the console, it works:
db.users.update({_id: 'Qdf89k3fd93jfdk'}, {$addToSet: {'address.streetAddress': '12345 fake st'}});
Thank you in advance!
Your addressDetails object doesn't have a field streetAddress, so addressDetails.streetAddress returns undefined. Use addressDetails.address.streetAddress instead in the update. And also, like Joshua pointed out, use an object as selector with { _id: currUserId }. So the whole function should be:
Meteor.users.update( { _id: currentUserId }, {$addToSet:
{
'address.streetAddress': addressDetails.address.streetAddress
}
});
}
One more thing, you should not pass the userId from the client. Any method you define is callable from the client and like that, I would be able to call your method 'addAddress' from the browser console with any userId to update their address. Instead, use the this.userId object in method calls (see here) and check that it is not null, i.e. user is logged in.
if (! this.userId)
throw new Meteor.Error(401, "You must be logged in!");
var currentUserId = this.userId;
It looks like you're passing in the document id directly into the MongoDB query method, rather than constructing an object with an _id property with a value of said document id.
i.e try
var currentUserId = { _id: currUserId };

Inserting multiple values in Mysql using Nodejs and notifying user with a response

I am making a new webservice where i send a curl command with JSON and the JSON contains a array as
[{tempid:1,email:abc#123,address:asd},{tempid:2,email:abc#12345,address:asd45},{tempid:3,email:abc#1234,address:asd4}]
Now when i pass and insert the array in a mysql table tempid is just to show a mapping to the user to the contact id generated in the database as tempid:1 is now inserted and in database it has cid 120 , like this for tempid2 and 3 ,
But when i am trying to show the client the updated values it shows only one value , last last change not the whole updated Array. Its becuase of the async nature of the connection.querry function , so i need help in this , here is my webservice
contactadd webservice -->
for(var i=0;i<=request.body.contact.length-1;i++)
{
if(request.body.contact[i].tempid)
{ var ardata=new Array();
var o=request.body.contact[i];
pair=Object.keys(o).map(function(a){ return [a, o[a]] });
AM.addcontact(pair,request.session.user,request.body.contact.length,function(e,o){
if(!o)
{
response.send('something went wrong'+e);
}
else
{
//response.send(o);
}
});
}
}
Here is the update function in the database.js script -->
//ContactSync-addcontact module for database
exports.addcontact=function (arr,email,addnum,callback)
{
var counter=0;
var uid;
var data=new Array();
var showinsert=new Array();
var values=new Array();
var datatable=new Array();
var inserting=new Array();
var tempid=0;
connection.query('SELECT UID FROM user where email1="'+email.email+'"',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
if(rows[0]!=undefined)
{
uid=rows[0]['UID'];
}
else
{
uid="no id in database";
}
}
});// get the UID of the inserting user
// make array of user provided data
for(var j=0;j<=arr.length-1;j++)
{
if(arr[j][0]!='tempid')
{
data.push(arr[j][0]);
}
else
{
tempid=arr[j][1];
}
}
connection.query('SELECT column_name FROM information_schema.columns where table_schema="webservice" AND table_name="usercontacts"',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
for(var i=0;i<=rows.length-1;i++)
{
datatable.push(rows[i]['column_name']);
}
}
for(var k=0;k<=datatable.length-1;k++)
{
if(inArray(data[k],datatable))
{
inserting.push(data[k]);
}
}
if(inserting.length>0)
{
for(var z=0;z<=arr.length-1;z++)
{
if(inArray(arr[z][0],inserting))
{
values.push('"'+arr[z][1]+'"');
}
}
// Insert tempid values and data in the usercontacts table with inserting and values
connection.query('INSERT INTO usercontacts (cid,uid,'+inserting+') VALUES("","'+uid+'",'+values+')',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
connection.query('SELECT * FROM usercontacts WHERE uid="'+uid+'" ORDER BY cid DESC LIMIT 0,'+addnum+'',function(err,rows,fields){
if(err)
{
throw err;
}
else
{ showinsert.push('temp-id: '+tempid+',cid:'+rows[0].cid+',uid:'+uid);
//for(var i=0;i<=inserting.length-1;i++)
forEach(inserting,function(row,index)
{
showinsert.push(inserting[index]+":"+values[index]);
counter+=1;
});
callback(null,showinsert);
}
});
}
});
//insertion finished
}
else
{
callback("Please Provide atleast one field to enter with tempid");
}
});
}
I just need to insert all the callback in a array which has been inserted and show user that array ,please help , completely stuck and then only i am trying StackOverflow.
Thank you for reading till the end BTW
I'm not sure what the specific problem is, but there are some problems with the code you've shared that will bite you sooner or later. One of these may be causing your problem.
Race conditions
If the query SELECT UID FROM user where email1= for any reason takes longer than the SELECT column_name FROM information_schema.columns just below it then you won't have a value for the variable uuid and your logic will fail. Remember that these calls are non-blocking, so you can't rely on one finishing before the other one unless they're nested or use another flow-control mechanism (As #Tracker points out, async is popular).
Catching edge cases
In the line below you're assigning a string value to the uid variable and then continuing to use that variable even though it now contains an error message.
uid="no id in database";
Doing that means that your code later on will have trouble reacting. Instead use a different variable, leave the uid = undefined or immediately return the callback with an error, e.g.
return callback(new Error("user not found"));
Reporting errors
Don't throw errors in Node unless you want to kill the process, e.g. dependency problems during server startup. It doesn't work like Java, async errors are not caught by try/catch and will kill your process or leave you in a state that's hard to reason about. Instead make the error object your first parameter to the callback and return it immediately, like this:
if ( err ) return callback(err);
Then in your client code you can always check the first parameter to see if there was a problem.
Security problem
As #Tracker mentioned, don't ever do the this:
connection.query('SELECT UID FROM user where email1="'+email.email+'"', ...
If the value of the variable is passed through as "; drop table user; or similar then you're in trouble. Instead you can use node-mysql's build in escaping like this:
connection.query('SELECT UID FROM user where email1=?', [email.email], ...
Whitelist
You're querying information_schema.columns in order to detect which fields are valid then inserting them into usercontacts. This is a clever trick, but increases a 3 query process to 4 queries, and raises questions if there are any fields that a user shouldn't be inserting data into. Using a column whitelist may seem like more code to maintain, but would actually be simpler than all the code required to match columns dynamically.
Arrays
I don't see the source for the function inArray() but it looks like it does the same as Array.prototype.indexOf() so it may be better to use that. e.g.
if ( datatable.indexOf(data[k]) > -1 ) inserting.push(data[k]);
Every line of custom code you can delete is a line of code you don't have to maintain.

Categories