I have LIVR in a project i'm working now and is quite unclear to me how this work. I can't understand how to create new rules for custom validation.
Here's the code:
LIVR.Validator.defaultAutoTrim(true);
let validator = new LIVR.Validator({});
LIVR.Validator.registerDefaultRules({
nested_object_value() {
return function (value) {
if (!value || (value && !value.value || value === [])) {
return 'REQUIRED';
}
return '';
};
},
max_number_advancement() {
return function (value) {
if (value > 100) {
return 'MAX_NUMBER';
}
return '';
};
},
required_if_activity_present() {
return function (value, allValue) {
if (allValue.activitycycletype && !value || allValue.requestpeople === []) {
console.log(first)
return 'REQUIRED_IF_CYCLETYPE';
}
return '';
};
},
});
And this is how its used:
validationForm = () => {
const { formValue, updateErrors } = this.props;
const validData = validator.validate(formValue);
console.log(formValue)
if (!validData) {
const errorsValidator = validator.getErrors();
if (errorsValidator && Object.keys(errorsValidator).length > 0) {
const newErrors = {};
Object.keys(errorsValidator).forEach((error) => {
newErrors[error] = errorsValidator[error];
});
updateErrors(newErrors);
}
blame(t('validation-error'));
return false;
}
updateErrors({});
return true;
}
Opening the form with this validation in the app, seems to call only the last method required_if_activity_present().
What i expect here is that i can create a new method inside registerDefaultRules(), that is a LIVR method, like this:
LIVR.Validator.registerDefaultRules({
re quired_not_empty() {
return function (value) {
if (!value) {
return 'REQUIRED';
}
return '';
};
},
... //other methods
}
but seems not working, the newer method is not being called at all by validator.validate()
Anyone know how to create a new rules where i can check if an element inside the object that has to be validate is an empty array?
Because seems that LIVR doesn't return a validation error in this case, but only on empty string and null values.
Thanks in advance
I want to write a function which will return id from array of object but when i call that function it returns me what I pass.
export function getRecipeByID(requestId) {
recipes.find(function (recipe) {
return recipe.id === requestId;
});
return requestId;
}
for example I call function
getRecipeByID(1)
and it returns 1.
I guess what you want to write is this:
export function getRecipeByID(requestId) {
return recipes.find(function (recipe) {
return recipe.id === requestId;
});
}
Notice that it doesn't return requestId but the result of recipes.find()
That's because you return requestId in your method while what you want is to return the result of recipes.find...
export function getRecipeByID(requestId) {
return recipes.find(function (recipe) {
return recipe.id === requestId;
});
}
you return requestId after using find which cause issue
const recipes = [
{
id: 2,
name: 'pasta'
},
{
id: 3,
name: 'sandwich'
},
{
id: 4,
name: 'pizza'
}
]
function getRecipeById(requestId) {
const findRecipe = recipes.find(function (recipe) {
return recipe.id === requestId;
});
return findRecipe;
}
console.log(getRecipeById(2)); // it will return{ id:2, name:"pasta" }
Try this:
export function getRecipeByID(requestId) {
const recipe = recipes.find(item => item.id === requestId);
if (recipe && recipe.id) {
return recipe.id;
} else {
return null;
}
}
Explanation: You're not assigning the result of the find operation (the element that has been found or null if there was no matching element) to any variable and are simply returning the request id.
Also: I'd suggest you'd look into arrow functions. They have been available for some years now and make your code much easier to read. :)
If you really want a function that return the same Id that you fetch, then do it:
export function getRecipeByID(requestId) {
return requestId;
}
otherwise, if want to fetch an Object of your list of object then you can simply try:
const array1 = [{}]
export function getRecipeByID(requestId) {
return array1.find(element => element.id == requestId);
}
The following should put out "Yuval"
console.log(pathFind(["book", "author", "name"], {
book: {
author: {
name: "Yuval"
}
}
}));
I've tried writing this function but it keeps returning undefined:
function pathFind(path, object) {
return path.reduce((accumulator, name) => {
if(accumulator && accumulator[name] != typeof 'object') {
accumulator[name]
} else {
undefined, object
}
})
}
What am I missing? (a typo?)
Is there a way to use recursion inside this function in combination with reduce? (i.e how to approach recursion for this?)
Try the following:
var obj = {
book: {
author: {
name: "Yuval"
}
}
};
var path = ["book", "author", "name"];
function findPath(obj, path){
if(path.length === 0) return obj;
return findPath(obj[path[0]], path.slice(1));
}
console.log(findPath(obj,path));
I am running a loop through my array to check if calendar and tpoint have values. In my else statement of my if-statement I am attempting to get the key's name with var notSelected = (obj.prop.subProp).val() !== '';.
I know I am off with my method.. I am just unsure how to get the key name.
So, with my example, since the values in tpoint are empty, I am wanting the var notSelected to equal tpoint.
Anyone know how I can do this?
var packageContents = {
'packages': [
{
'price': '23',
'name': 'Bronze Bundle Package',
'calendar': {
'type': '2year',
'color': 'Brushed Nickel',
},
'tpoint': {
'type': '',
'touches': '',
'years': '',
}
}
]
};
var bundleSet = null;
var bundleSet = null;
packageContents.packages.forEach(function (obj) {
for (var prop in obj) {
if (prop === 'calendar' || prop === 'tpoint') {
for (var subProp in obj[prop]) {
if (obj[prop][subProp] !== '') {
bundleSet = true;
} else {
bundleSet = false;
var notSelected = (obj.prop.subProp).val() !== '';
console.log(notSelected);
}
}
}
}
console.log(bundleSet);
});
What about something like this:
function hasEmptyProps(prop) {
return Object.values(prop).some(x => x === '');
}
const result = packageContents.packages.map(x => {
if (hasEmptyProps(x.calendar)) {
return 'calendar';
} else if (hasEmptyProps(x.tpoint)) {
return 'tpoint'
} else {
return '';
}
})
console.log(result)
Would return ["tpoint"] (or an array of "calendar", "", or "tpoint")
Tell me, how correctly to check the existence of a key in associative arrays?
For example:
var mydata = {
key1: '',
key2: {
subkey1: {
subkey1_1: {
value1: ''
value2" '',
},
},
subkey2: '';
},
}
if ((mydata.key2 != undefined) && (mydata.key2.subkey1 != undefined) && (mydata.key2.subkey1.subkey1_1 != undefined))
mydata.key2.subkey1.subkey1_1.value1 = 'test';
Too long and confusing
((mydata.key2 != undefined) && (mydata.key2.subkey1 != undefined) && (mydata.key2.subkey1.subkey1_1 != undefined))
I would like to use a simpler function, like
safeSet(mydata.key2.subkey1.subkey1_1.value1, 'test');
or
if (is_undefined(mydata.key2.subkey1.subkey1_1.value1) == true)
mydata.key2.subkey1.subkey1_1.value1 = 'test'; // now - error if 'mydata.key2.subkey1.subkey1_1' not exist
You can create custom function using reduce() to test if nested property exists. You can just pass key as string.
var mydata = {
key1: '',
key2: {
subkey1: {
subkey1_1: {
value1: '',
value2: '',
},
},
subkey2: ''
},
}
function safeSet(key, data) {
return key.split('.').reduce(function(r, e) {
return r ? r[e] : undefined;
}, data) != undefined
}
console.log(safeSet('key2.subkey1.subkey1_1.value1', mydata))
You should use the in operator:
"key" in obj // true, regardless of the actual value
Or, if you want to particularly test for properties of the object instance (and not inherited properties), use hasOwnProperty:
obj.hasOwnProperty("key") // true
hope this would help you.
Source: http://www.advancesharp.com/questions/628/checking-if-an-associative-array-key-exists-in-javascript
Alternatively, you can make use of the .has() method of Lodash.
Then, you would only need to check:
if (_.has(mydata, 'key2.subkey1.subkey1_1.value1')
mydata.key2.subkey1.subkey1_1.value1 = 'test';
For trying to get something in a nested structure I'd do something like this:
function getPath(element, path) {
var handledSoFar = [];
for (var i = 0; i < path.length; i++) {
var property = path[i];
handledSoFar.push(property);
if (typeof element[property] === 'undefined') {
throw new Error('Path ' + handledSoFar.join('->') + ' is undefined');
}
element = object[property];
}
return element;
}
var mydata = {
key1: '',
key2: {
subkey1: {
subkey1_1: {
value1: '',
value2: 'hi'
}
},
subkey2: ''
}
};
// Prints 'hi'
console.log(getPath(mydata, ['key2', 'subkey1', 'subkey1_1', 'value2']));
// Throws error 'Path key2->subkey2->subkey1_1 is undefined'
console.log(getPath(mydata, ['key2', 'subkey1', 'subkey1_1', 'value2']));
Of course keeping track of the search in handledSoFar is optional but might be useful for development / debugging.
You can also use the lodash deep field selector: lodash.get (documentation)
const get = require('lodash.get');
const set = require('lodash.set');
if (!get(mydata, 'key2.subkey1.subkey1_1.value1')) {
set(mydata, 'key2.subkey1.subkey1_1.value1', 'test');
}
You could split the path and make a check if the following element exist. If not assign an object to the new property.
Return then the value of the property.
At the end assign the value.
function setValue(object, path, value) {
var fullPath = path.split('.'),
way = fullPath.slice(),
last = way.pop();
way.reduce(function (r, a) {
return r[a] = r[a] || {};
}, object)[last] = value;
}
var object = { key1: '', key2: { subkey1: { subkey1_1: { value1: '', value2: '' } }, subkey2: '' } };
setValue(object, 'key2.subkey1.subkey1_1.value1', 'test');
console.log(object);
The problem with the example function that you proposed:
safeSet(mydata.key2.subkey1.subkey1_1.value1, 'test');
or
is_undefined(mydata.key2.subkey1.subkey1_1.value1)
Is that the mydata.key2.subkey1... part is run before the function is called. So if one of the subkeys does not exist, an exception will be thrown before your code is reached.
You could get something similar using a callback though...
safeSet(function(val) { mydata.key2.subkey1.subkey1_1.value1 = val; }, 'test')
the implementation of safeSet would then be:
var safeSet = function(setterFunc, val) {
try {
setterFunc(val);
} catch (e) {
if (e instanceof TypeError) {
return false;
} else {
throw e;
}
}
return true;
}
safeSet returns true if the value was set, and false otherwise.