How I can pass a parameter value in where clause MongoDB - javascript

i have a problem with a mongoDb query, i need to search for a parameter value of any MongoDB field.
I use a function in $where clause like:
db.response.find(
{
$where: function() {
var deepIterate = function (obj, value) {
for (var field in obj) {
if (obj[field] == value){
return true;
}
var found = false;
if ( typeof obj[field] === ‘object’) {
found = deepIterate(obj[field], value)
if (found) { return true; }
}
}
return false;
};
return deepIterate(this, “Text36")
}
});
The returned response was fine but I don't know how I can pass the value (Text36 in this sample) I want to found like a parameter
can someone help me please ? Thanks

Related

Check all values in && comparison?

JavaScript is known to only check the first variable in a && comparison in case the first variable returns false. Is there a way to 'ask' JavaScript to check both variables i.e. when they are methods?
For example: Suppose you have 2 methods that validate 2 separate user inputs:
const validateEmail = value => {
if(value.contains('#')){
setShowEmailError(false);
return true;
}
setShowEmailError(true);
return false;
};
const validatePswd = value => {
if(value !== ''){
setShowPswdError(false);
return true;
}
setShowPswdError(true);
return false;
};
Then check both conditions:
if(validateEmail(email) && validatePswd(pswd)){
//validate entire form and render errors
}
However, the above will not execute the validatePswd method if the first method validateEmail returns false.
Is there a way to check if both values are true and run both methods? Having JavaScript run both methods would be a breeze in some cases.
You can execute them in an array and then accumulate the result with && by reduce function.
const validateEmail = value => {
if(value.includes('#')){
//setShowEmailError(false);
return true;
}
//setShowEmailError(true);
console.log('wrong email')
return false;
};
const validatePswd = value => {
if(value !== ''){
//setShowPswdError(false);
return true;
}
// setShowPswdError(true);
console.log('wrong password');
return false;
};
// you can execute any number of validations within the array.
const result = [validateEmail('something'), validatePswd('')].reduce((acc, f) => acc && f, true);
console.log(result)
UPDATE
Or as #lux suggested using every method.
const validateEmail = value => {
if(value.includes('#')){
//setShowEmailError(false);
return true;
}
//setShowEmailError(true);
console.log('wrong email')
return false;
};
const validatePswd = value => {
if(value !== ''){
//setShowPswdError(false);
return true;
}
// setShowPswdError(true);
console.log('wrong password');
return false;
};
// you can execute any number of validations within the array.
const result = [validateEmail('something'), validatePswd('')].every(r => r);
console.log(result)
I don't know if you are looking for something like this:
const valEmail = validateEmail(email);
const valPsw = validatePswd(pswd);
if(valEmail && valPsw ){
//validate entire form and render errors
}

How do I ensure an array has no null values?

I would like test my Array (input value) before submit my form.
My array with value :
const fields = [
this.state.workshopSelected,
this.state.countrySelected,
this.state.productionTypeSelected,
this.state.numEmployeesSelected,
this.state.startAt
];
I've try this :
_.forEach(fields, (field) => {
if (field === null) {
return false;
}
});
alert('Can submit !');
...
I think my problem is because i don't use Promise. I've try to test with Promise.all(fields).then(());, but i'm always in then.
Anyone have idea ?
Thank you :)
The problem is that even though you're terminating the lodash _.forEach loop early, you don't do anything else with the information that you had a null entry.
Instead of lodash's _.forEach, I'd use the built-in Array#includes (fairly new) or Array#indexOf to find out if any of the entries is null:
if (fields.includes(null)) { // or if (fields.indexOf(null) != -1)
// At least one was null
} else {
// All were non-null
alert('Can submit !');
}
For more complex tests, you can use Array#some which lets you provide a callback for the test.
Live example with indexOf:
const state = {
workshopSelected: [],
countrySelected: [],
productionTypeSelected: [],
numEmployeesSelected: [],
startAt: []
};
const fields = [
state.workshopSelected,
state.countrySelected,
state.productionTypeSelected,
state.numEmployeesSelected,
state.startAt
];
if (fields.indexOf(null) != -1) {
console.log("Before: At least one was null");
} else {
console.log("Before: None were null");
}
fields[2] = null;
if (fields.indexOf(null) != -1) {
console.log("After: At least one was null");
} else {
console.log("After: None were null");
}
You do not need to use promises unless there is an asynchronous operation (for example if you are getting that array from your server).
If you already have that array you can do something like:
// Using lodash/underscore
var isValid = _.every(fields, (field) => (field!==null)}
// OR using the Array.every method
var isValid = fields.every((field)=>(field!==null))
// Or using vanilla JS only
function checkArray(array){
for(var i = 0; i < array.length ; i ++){
if(array[i]===null){
return false;
}
}
return true;
}
var isValid = checkArray(fields);
// After you get that value, you can execute your alert based on it
if(!isValid){
alert('Something went wrong..');
}
Try this simple snippet
var isAllowedToSubmit = true;
_.forEach(fields, (field) => {
if (!field) {
isAllowedToSubmit = false;
}
});
if(isAllowedToSubmit)
alert('Can submit !');
You can do that without library:
if (fields.some(field => field === null)) {
alert('Cannot submit');
} else {
alert('Can submit');
}
You don't need to use lodash, you can do this in simple vanilla javascript. Simply iterate over each field and if an error occurs set your errors bool to true
let errors = false;
fields.forEach(field) => {
if(field === null || field === '') {
errors = true;
}
});
if (!errors) {
alert('Yay no errors, now you can submit');
}
For an es6 you can use.
const hasNoError = fields.every((field, index, selfArray) => field !== null);
if (!hasNoError) {
alert('yay It works');
};
Have a look at Array.every documentation Array every MDN documentation

jQuery each with ajax call will continue before it's finished

I have some jQuery which uses an each loop to go through values entered in a repeated form field on a Symfony 3 CRM. There is a $.post which sends the entered value to a function that checks for duplicates in the database, and if it's a duplicate it adds something to an array, otherwise it adds a blank value to indicate it's not a dupe. Once these have been done, it then checks the final array and adds any errors to the error block to display to the user.
However, it seems that the array is ALWAYS blank and I belivee it's because it's running the code that displays the errors BEFORE it's actually finished getting the response.
Here is my code:
$('#puppy_form').on('submit', function() {
var bitch_errors = [];
var dog_errors = [];
// NOTE: Bitch and dog names need to be checked differently so we know which error is assigned to which input
$('.check_bitch_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_bitch_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_bitch_name)) {
bitch_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_bitch_name }
).done(function (response) {
if(response == 'duplicate') {
bitch_errors[i+1] = "duplicate";
} else {
bitch_errors[i+1] = "";
}
});
}
});
$('.check_dog_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_dog_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_dog_name)) {
dog_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_dog_name }
).done(function (response) {
if(response == 'duplicate') {
dog_errors[i+1] = "duplicate";
} else {
dog_errors[i+1] = "";
}
});
}
});
if(count(bitch_errors) == 0 && count(dog_errors) == 0) {
return true;
}
// loop through the errors and assign them to the correct input
$.each( bitch_errors, function( key, value ) {
if (value == "invalid") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
});
$.each( dog_errors, function( key, value ) {
if(value != "") {
if (value == "invalid") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
}
});
return false;
});
Basically, it first checks that the inputted name is valid, then posts off and checks for dupes. The issue is, even though it does the validity check (and prints errors accordingly) it seems to ignore the dupe check and carry on before it's even called back the first response.
How can I make sure it's finished it's checking before going on and adding the errors to the form? I've tried other solutions including attempting to implement the $.when functionality in jQuery but I don't really understand how to make it work. Any help appreciated.
First, write a function that returns an asynchronous promise to give you a value for one dog:
function checkDog(name) {
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(name)) {
return $.Deferred().resolve("invalid");
} else {
return $.post('/check-puppy-name', { name: name } )
.then(function (response) {
if (response === 'duplicate') {
return 'duplicate';
} else {
return '';
}
});
}
}
Then you can write one that handles multiple dogs, also returning a promise (which won't itself be resolved until every dog has been checked):
function checkDogs(array) {
return $.when.apply($, array.map(checkDog));
}
Note that there's no DOM-related code yet. You can now write a function that gets the values from a bunch of DOM inputs and returns them in an array:
function getInputValues($selector) {
return $selector.get().map(function(el) {
return el.value;
});
}
So now (on submit) you can check your two sets of inputs and then finally when both of these are available, you can examine the results and update the DOM:
$('#puppy_form').on('submit', function() {
var bitch_names = getInputValues($('.check_bitch_name'));
var dog_names = getInputValues($('.check_dog_name'));
var bitch_promises = checkDogs(bitch_names);
var dog_promises = checkDogs(dog_names);
$.when(bitch_promises, dog_promises).then(function(bitch_errors, dog_errors) {
// update the DOM based on the passed arrays
...
});
});
You are right, ajax calls are like their name says asynchronous. Therefor you can only rely on the .done function. A simple solution would be to initialize a counter variable at the beginning for bitches and dogs and in the according done function you decrement it until it reaches zero. Then, also in the done function, you put an if that calls validation of the error arrays. Here is UNTESTED code to show what I mean:
$('#puppy_form').on('submit', function() {
/*
here you get the initial count for bitches and dogs
*/
var bitch_count = $('.check_bitch_name').length;
var dog_count = $('.check_dog_name').length;
var bitch_errors = [];
var dog_errors = [];
// NOTE: Bitch and dog names need to be checked differently so we know which error is assigned to which input
$('.check_bitch_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_bitch_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_bitch_name)) {
bitch_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_bitch_name }
).done(function (response) {
if(response == 'duplicate') {
bitch_errors[i+1] = "duplicate";
} else {
bitch_errors[i+1] = "";
}
/*
now on every checked name you decrement the counter
and if both counters reach zero you can be sure you
checked all and only now you call your validation
*/
bitch_count--;
if(bitch_count === 0 && dog_count === 0) {
return validateErrors();
}
});
}
});
$('.check_dog_name').each( function(i, obj) {
// need to check each name for validity and duplication.
var entered_dog_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_dog_name)) {
dog_errors[i+1] = "invalid";
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_dog_name }
).done(function (response) {
if(response == 'duplicate') {
dog_errors[i+1] = "duplicate";
} else {
dog_errors[i+1] = "";
}
/*
same here
*/
dog_count--;
if(bitch_count === 0 && dog_count === 0) {
return validateErrors();
}
});
}
});
}
/*
...and finally all code that should be processed after the ajax calls
*/
function validateErrors() {
if(count(bitch_errors) == 0 && count(dog_errors) == 0) {
return true;
}
// loop through the errors and assign them to the correct input
$.each( bitch_errors, function( key, value ) {
if (value == "invalid") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="bitch_name['+key+']"]').parent().addClass('has-error');
$('input[name="bitch_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
});
$.each( dog_errors, function( key, value ) {
if(value != "") {
if (value == "invalid") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Names must be at least two words, and only contain letters');
return false;
} else if(value == "duplicate") {
$('input[name="dog_name['+key+']"]').parent().addClass('has-error');
$('input[name="dog_name['+key+']"]').next('.error-message').html('Sorry, this name has already been taken');
return false;
}
}
});
return false;
});
You could use the async lib to manage these requests and collect the results which will then be passed into the final callback where you can process them.
I haven't tried to run this code but hopefully it will get you close enough if not already there.
async.parallel({
bitch_errors: function(callback) {
var bitch_errors = [];
async.forEachOf($('.check_bitch_name'), function(obj, i, cb) {
// need to check each name for validity and duplication.
var entered_bitch_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_bitch_name)) {
bitch_errors[i+1] = "invalid";
cb();
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_bitch_name }
).done(function (response) {
if(response == 'duplicate') {
bitch_errors[i+1] = "duplicate";
} else {
bitch_errors[i+1] = "";
}
cb();
});
}
}, function () {
callback(null, bitch_errors);
});
},
dog_errors: function(callback) {
var dog_errors = [];
async.forEachOf($('.check_dog_name'), function(obj, i, cb) {
// need to check each name for validity and duplication.
var entered_dog_name = obj.value;
var pattern = /^[a-zA-Z,.]+\s[a-zA-Z,.]+(\s[a-zA-Z,.]+){0,}$/;
if(!pattern.test(entered_dog_name)) {
dog_errors[i+1] = "invalid";
cb();
} else {
// now to check for duplicates
$.post('/check-puppy-name', { name: entered_dog_name }
).done(function (response) {
if(response == 'duplicate') {
dog_errors[i+1] = "duplicate";
} else {
dog_errors[i+1] = "";
}
cb();
});
}
}, function () {
callback(null, dog_errors);
});
}
}, function(err, results) {
// you can now access your results like so
if(count(results.bitch_errors) == 0 && count(results.dog_errors) == 0) {
// ... rest of your code
});

Backbone Collection .findwhere() underscore method

This code is returning the alert message the number of times models are present in collection. I want to print it just once and come out of the loop as soon as the username and password matches.
what to do?
this.collection.find(function(model)
{
debugger
var user = model.get('username');
var pwd = model.get('password');
if(enteredUsername == user && enteredPassword == pwd)
{
return(alert("success"));
}
else
{
return(alert("failure"));
}
});
Sources of BB
where: function(attrs, first) {
if (_.isEmpty(attrs)) return first ? void 0 : [];
return this[first ? 'find' : 'filter'](function(model) {
for (var key in attrs) {
if (attrs[key] !== model.get(key)) return false;
}
return true;
});
},
¶
Return the first model with matching attributes. Useful for simple cases of find.
findWhere: function(attrs) {
return this.where(attrs, true);
},
so try
console.log(this.collection.findWhere({username: username, password: password}));

Error returning an Object

I have an Array of Objects called ENTITIES and the following function that receives and String id and the whole objects Array:
function getEntityById( id, ENTITIES) {
id = id.toString(); //made sure id is string
ENTITIES.forEach(function( ENT ) {
if( ENT.name == id ) {
return( ENT );
}
});
}
I've already checked the function with console.log and its working fine. (id is checked and the 'if' is getting TRUE). The problem occurs when i try to access the returned Object 'ENT' outside the function, like this:
var entity0 = getEntityById( 'test', ENTITIES);
console.log( entity0.id );
I get the following error: Uncaught TypeError: Cannot read property 'id' of undefined
It's like getEntityById function never really returned an Object.
Could you guys help me? Any clues?
You have this function:
function getEntityById( id, ENTITIES) {
id = id.toString(); //made sure id is string
ENTITIES.forEach(
and then you have this function
function( ENT ) {
if( ENT.name == id ) {
return( ENT );
}
which returns back to your original function:
});
}
which doesn't do anything with it, so getEntityById returns nothing... so you get undefined.
What you could do is:
function getEntityById( id, ENTITIES) {
id = id.toString(); //made sure id is string
var return_ENT;
ENTITIES.forEach(function( ENT ) {
if( ENT.name == id ) {
return_ENT = ENT;
}
});
return return_ENT;
}
A better option might be to use filter:
function getEntityById( id, ENTITIES) {
id = id.toString(); //made sure id is string
return ENTITIES.filter(function(ent) { return ent.name == id})[0];
};
If you want to return the found entity you have to save it, exit the forEach loop and return the variable:
function getEntityById(id, ENTITIES) {
var result = null;
id = id.toString(); //made sure id is string
ENTITIES.forEach(function( ENT ) {
if( ENT.name == id ) {
result = ENT;
}
});
return result;
}
But in that case you'll do some redundant work (if the required entity is found - there's no need to continue the loop). So I would recommend to do like:
function getEntityById(id, ENTITIES) {
var i = ENTITIES.length;
while(--i >= 0) {
if (ENTITIES[i].id === id) {
return ENTITIES[i];
}
}
}

Categories

Resources