I am trying to write a simple check() function following this example. The function successfully prints out "True!" but the return value of the function is undefined when I do console.log(submitModels.verifyOrganizationString(formInputs.organizationString));. How can I get the function to return true and false?
Right now the function only returns "Invalid organization string" even when the string is valid.
I am thinking this result has to do with the pg-promise library, but am not sure.
In the file submit.js, I have:
function verifyOrganizationString(organizationString) {
db.one("select * from organizations where organization_string=$1", [organizationString])
.then(data => {
console.log("True!");
return true;
})
.catch(error => {
console.log("False!");
return false;
});
}
module.exports = {
verifyOrganizationString,
};
In another file, I have
const submitModels = require('../models/submit.js');
function proccessSubmission(req, res) {
var formInputs = req.body;
console.log(submitModels.verifyOrganizationString(formInputs.organizationString));
if (submitModels.verifyOrganizationString(formInputs.organizationString)) {
submitModels.insertIntoDatabase(formInputs);
res.redirect('/');
} else {
res.send("Invalid organization string");
}
}
Your problem is due to both invalid use of promises and bad use of pg-promise.
If you want the function to return true/false depending on whether a record is found, change the function to this:
function verifyOrganizationString(organizationString) {
return db.oneOrNone("select * from organizations where organization_string = $1",
organizationString, a => !!a);
}
Then you can use it as one would a regular promise:
verifyOrganizationString('bla-bla')
.then(data => {
// data = true/false
})
.catch(error => {
// error
});
See also: SELECT ⇒ INSERT examples.
The reason you're getting undefined is because 'verifyOrganizationString' doesn't actually return anything. You need to return the promise created by your db.one chain.
Although the method will still not return true or false in that case but the Boolean wrapped in another promise so that you can chain the result of your verify function the same way you did with the result of db.one.
Related
I get some data from mongodb using mongoose find() and perform some validation on that data, but the problem is that this function is async and it does not wait for the data to be completed and execute the next code.
and when the next code is executed it enables to perform because it has null data. then i wrote my validation logic in the async function so that when data is available only then it move to next code but on every return it sends undefined data.
function isValidObject(obj) {
schemaData.find({}, (error, data) => { // calls data from db
var contactSchema = data; // this is data i need
if(//validation fails){
return "wrong data";// every time it returns undrfined on every
// condition
}
});
}
var validationResp = isValidObject(obj);
console.log(validationResp); // output is undefined
i also used "await" to wait for the data, but in that case it return [object promise] on every return statement
use async/await
In your case:
async function isValidObject(obj) {
let data = await schemaData.find({}); // wait until it resolve promise
//do your validaion
return data;
}
isValidObject(obj).then((validationResp)=>{console.log(validationResp)});
use the then() method it return a promise
var promise1 = new Promise(function(resolve, reject) {
resolve('Success!');
});
promise1.then(function(value) {
console.log(value);
// expected output: "Success!"
});
more details at MDN Using the then method
Are you familiar with "promises".You can use ".then(callback)". It will wait until async function is executed. And you can perform your validation in the callback function
User.findById(id)
.then(function(user) {
if (!user) {
return "here you return an error";
}
return "you return OK with payload from database";
})
.catch(next);
What is happening in your case is that when you assign var validationResp = isValidObject(obj); the function isValidObject(obj) has not returned anything and has only scheduled a callback(This is a very important concept when working with callbacks). As pointed out above you need to use Promises. The below is an example of your case as to how you can use Promises.
function isValidObject(obj){
return new Promise((resolve,reject) => {
schemaData.find({}, (error, data) => { // calls data from db
if(validation fails){
reject(error)// every time it returns undrfined on every
// condition
}else{
var contactSchema = data; // this is data i need
resolve(data)// You can resolve the promise with the data directly instead
// of assigning it to a variable or you can use (resolve(contactSchema))
}
})
})
}
After this when you want to use the data you can use do something like the below code snippet.
isValidObject(obj)
.then(result => {
// Use the result object here. This is the result from the Database
})
.catch(error => {
//Handle the Error
})
I am evaluating a function in a ng if to know if the user has permission to perform an action. The problem is that the function to evaluate makes a call to the backend, and apparently does not work correctly next to the ng-if, since it prints an empty object and not the result that the function returns.
I'm showing the result into the html with this to know what the function is responding to:
{{organizationController.isAllowedToInvite ()}}
this print to me an empty object {}
this is the function that I am evaluating:
self.isAllowedToInvite = () => {
organizationRoleService.getUserPermissions(self.organizationId)
.then((response) => {
const userPermissions = response.data;
if (userPermissions && userPermissions.organizationPermissions >= 4){
return true;
}
return false;
}, (error) => {
console.log(error);
});
};
this return a true or false, this works well by itself.
Why can not I show the result of the function when I print in the html? because instead of showing true / false it shows me an empty object {}?
i want it show me true or false, so I can evaluate it in the ng if correctly.
this is my ng-if, obviusly this does not work becouse has a {} value.
ng-if="organizationController.isAllowedToInvite()"
there's an async operation in your method, you cannot statically check the condition in the if. You should call the method on the controller instantiation and then use a flag that you set to true in case all the conditions are met and check that flag in the template
self.isAllowedToInvite = () => {
self.isAllowed = false;
organizationRoleService.getUserPermissions(self.organizationId)
.then((response) => {
const userPermissions = response.data;
if (userPermissions && userPermissions.organizationPermissions >= 4){
self.isAllowed = true;
}
}, (error) => {
console.log(error);
});
};
self.isAllowedToInvite();
and in your template
ng-if="organizationController.isAllowed"
I have this piece of code in my angular 6 application:
publish() {
change.subscribe((result: boolean) => {
if(!result) return; // exit publish function
});
// continue
}
I want this publish function to continue executing only if result is true.
How to manage this ?
it is impossible, you should put your publish function code inside your subscription, or there is another way you can do, you can use .toPromise() and async/await, if you will get your data one time and not in a stream
async publish() {
const result = await change.toPromise();
if(result) {
// your publish function code here
});
}
Converting observable to promise is always a bad idea, so better is just to create local variable and assign a value from yourObservable to this local variable.
async publish() {
let doBreak = false;
yourObservable.subscribe((result) => {
if (!result) {
doBreak = true;
}
}
if (doBreak) {
return;
}
}
I have some middleware in front of my publications:
Meteor.publish(publicationIdentifier, function (...args) {
try {
middleware()
} catch(error) {
return Users.find('emptyCursor')
}
return Model.pubsub(...args)
})
I need to return an empty Cursor when the middleware throws an error.
I currently do that by using find with an invalid id on some arbitrary collection: return Users.find('emptyCursor')
Is there some better way to do this?
I have tried
return
return false
return null
return new Mongo.Cursor()
Like in the doc
// Sometimes publish a query, sometimes publish nothing.
Meteor.publish('secretData', function () {
if (this.userId === 'superuser') {
return SecretData.find();
} else {
// Declare that no data is being published. If you leave this line out,
// Meteor will never consider the subscription ready because it thinks
// you're using the `added/changed/removed` interface where you have to
// explicitly call `this.ready`.
return [];
}
});
I've created this a couple days ago in which i needed help regarding how to add custom properties to a said document.
First of all, I'm running Word 1701(7766.2047).
Let's say I have a method In which I return a said custom property. First I'd check if the custom property has been created already. I would do this with a simple getItemOrNullObject(key) and..
If returns null Then simply create it AND return it
Else return it
It is of my understanding that I need to do a return context.sync().then for the object get actually loaded with data? Am I doing too much return context.sync() calls for nothing?
Word.run(function(context) {
var customDocProps = context.document.properties.customProperties;
context.load(customDocProps);
return context.sync()
.then(function() {
var temp = customDocProps.getItemOrNullObject("X");
return context.sync()
.then(function() {
if (!temp) {
context.document.properties.customProperties.add("X", 1234);
temp = customDocProps.getItemOrNullObject("X");
return context.sync()
.then(function() {
return temp;
});
} else {
return temp;
}
});
});
});
The following code throws me an 'ReferenceError: 'Word' is undefined' at start but if I debug it it runs before it breaks
var customDocProps = context.document.properties.customProperties;
context.load(customDocProps);
return context.sync().{....}
Also have one more question. Say I want to update my custom property, would :
Word.run(function (context) {
context.document.properties.customProperties.add("X", 56789);
return context.sync();
});
override the old value with the new one?
If you read this far thank you! Any help is appreciated.
Cheers!
Thanks for asking this question.
Your code is correct except for one minor detail: All the *getItemOrNullObject methods do NOT return a JavaScript null, so your "if (!temp)" statement will not work as you expect. If you want to validate existence you need to call if(temp.isNullObject) instead.
Also a couple of suggestions:
customProperties.add() semantics is that if the property does exist, it will be replaced. So, If you want to create or change the property you don't need to check if it exists or not. If you want to read its current value you do. This answers your 2nd question.
I have a simplified and more efficient proposal for your code, if you are interested on loading a single property.
Word.run(function (context) {
var myProperty = context.document.properties.customProperties.getItemOrNullObject("X");
context.load(myProperty);
return context.sync()
.then(function () {
if (myProperty.isNullObject) {
//this means the Custom Property does not exist....
context.document.properties.customProperties.add("X", 1234);
console.log("Property Created");
return context.sync();
}
else
console.log("The property already exists, value:" + myProperty.value);
})
})
.catch(function (e) {
console.log(e.message);
})
We will update the documentation as this seems to be confusing.
Thanks!
I use these function to get or set custom properties
// sets a custom property on the current Word file
function setDocProperty (propName, propValue, callback) {
Word.run(context => {
context.document.properties.customProperties.add(propName, propValue)
return context.sync()
.then(() => {
callback(null)
})
.catch(e => {
callback(new Error(e))
})
})
}
// gets a custom property from the current Word file
function getDocProperty (propName, callback) {
Word.run(context => {
var customDocProps = context.document.properties.customProperties
// first, load custom properties object
context.load(customDocProps)
return context.sync()
.then(function () {
// now load actual property
var filenameProp = customDocProps.getItemOrNullObject(propName)
context.load(filenameProp)
return context.sync()
.then(() => {
callback(null, filenameProp.value)
})
.catch(err => {
callback(new Error(err))
})
})
.catch(err => {
callback(new Error(err))
})
})
}
You use them like this:
setDocProperty('docId', 28, () => {
console.log('property set')
})
getDocProperty('docId', (err, value) => {
if (err) {
console.log('Error getting property', err)
} else {
console.log('the property is ' + value)
}
})