Can someone tell me why this getter is returning me "Cannot read property 'testVar' of undefined"?
productPrice: (state) => (id) => {
const testVar = true
if (this.testVar) {
const priceObj = state.precioProducto.find(product => producto.idProducto === parseInt(id))
} else {
const priceObj = []
}
return (precioObj && state.productoPrecioReady) ? priceObj : null
},
You are using this.testVar, but testVar is declared as a constant in the getter block, so you must just declare your if condition as:
productPrice: (state) => (id) => {
const testVar = true
if (testVar) {
const priceObj = state.precioProducto.find(product => producto.idProducto === parseInt(id))
} else {
const priceObj = []
}
return (precioObj && state.productoPrecioReady) ? priceObj : null
}
Related
I have the following React code,
const useDynamicReplaceVariable = ({ label, formikValues, fieldsTypes }) => {
const { locale } = useTranslationState();
const formattedLabel = useMemo(() => {
const variablesRegex = /\?([\w-]+)\?/g;
let labelResult = label;
if (variablesRegex.test(label)) {
labelResult = ' ';
if (Object.keys(formikValues).length > 0) {
labelResult = label.replace(variablesRegex, (_, ...[variable]) => {
const type = fieldsTypes[variable];
// Set undefined or null to empty
let variableValue = (formikValues[variable] === undefined || formikValues[variable] == null) ? '' : formikValues[variable];
if (variableValue && [DesignerDdTypes.DatePicker, DesignerDdTypes.DatetimePicker].includes(type)) {
variableValue = dateToString(variableValue, locale, type === DesignerDdTypes.DatetimePicker);
}
return variableValue;
});
}
}
return labelResult;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [label, JSON.stringify(formikValues)]);
return { formattedLabel };
};
I can't understand the line labelResult = label.replace(variablesRegex, (_, ...[variable]), when no variable is defined, how come spread syntax is applied over it?
...[variable] is a shorthand for
function someFunction(...args) {
const [variable] = args
}
someFunction(1, 2, 3, 4, 5)
function someFunction(arg1, ...args) {
console.log('arg1', arg1)
console.log('args', args)
const [variable] = args
console.log('variable', variable)
}
someFunction(1, 2, 3, 4, 5)
function someFunction(arg1, ...[variable]) {
console.log('arg1', arg1)
console.log('variable', variable)
}
I would like to clean up this block of code. Is there a way of setting deep object properties without using Lodash, Ramda or some horrible method that splits the object property string and loops through it?
export const initialiseBlackbox = (value = '') => {
if (window === undefined) {
window = { IGLOO }
}
if (window.IGLOO === undefined) {
window.IGLOO = {}
}
if (window.IGLOO.getBlackbox === undefined) {
window.IGLOO.getBlackbox = () => ({ blackbox: value })
}
}
Sure, but it's not pretty:
export const initialiseBlackbox = (value = '') =>
Object.assign(window.IGLOO || (window.IGLOO = {}),
{ getBlackbox: () => ({ backbox: value }) });
For a generic reusable function
const deepSet = (t, p, ...v) => v.length > 1 ? (t[p] = t[p] || {}) && deepSet(t[p], ...v) : t[p] = v[0]
To use
deepSet(window, "IGLOO", "getBlackbox", () => ({ blackbox: 'some value' }))
I would really appreciate another pair of eyes to review why this issue persists.
Basically, a component does some check with validation functions imported from another file
...
const {emailField, phoneFieldUS, postalCodeField} = validators;
class ReturnForm extends React.Component {
...
formHasAnyErrors = () => {
console.log("phoneFieldUS type ", typeof phoneFieldUS)
console.log("postalCodeField type ", typeof postalCodeField)
const zipCodeValid = postalCodeField(form.contactInfo.postalCode);
const emailValid = emailField(form.contactInfo.email);
const mobileValid = phoneFieldUS(form.contactInfo.mobile);
if (!zipCodeValid || !emailValid || !mobileValid) {
return true;
}
return Object.values(errors.contactInfo).find(el => !!el);
};
...
}
And the validators imported looks like this:
exports.default = exports.validators = exports.validatorFactory = exports.statuses = exports.layouts = void 0;
const validatorFactory = (test, pass = () => {}, fail = () => {}) => {
return value => {
const validValue = test(value);
if (validValue === true) {
pass();
} else {
fail();
}
return validValue;
};
};
exports.validatorFactory = validatorFactory;
const validators = {
emailField: validatorFactory(value => {
return /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+#[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value); // eslint-disable-line max-len
}),
postalCodeField: validatorFactory(value => {
return ((value.length === 5 && /^\d+$/.test(value)) ^ (value.length === 6 && /\d/.test(value) && /[a-zA-Z]/.test(value)))
}),
emptyField: validatorFactory(value => value.length > 0 && !/^\s*$/.test(value)),
phoneFieldUS: validatorFactory(value => /^\(?(\d{3})\)?[-\. ]?(\d{3})[-\. ]?(\d{4})$/.test(value))
};
exports.validators = validators;
What I absolutely don't understand is
console.log("phoneFieldUS type ", typeof phoneFieldUS) // prints function
console.log("postalCodeField type ", typeof postalCodeField) // prints undefined
Hence every time the ReturnForm component is complaining about Uncaught TypeError: postalCodeField is not a function
Like how?????? They're both defined almost the same way?????? Please tell me if I'm missing something, any help appreciated!
We have a validation library like so..
const cache = [];
function rules(object) {
return {
addToCache(value) {
cache.push(value)
},
minLengthStr(property, propertyAlias = property) {
const value = object[property];
const message =
typeof value === 'string' && value.length > 2 ? null : `${propertyAlias} is less than 2`;
cache.push(message);
return rules(object);
},
emptyCollection(property, propertyAlias = property) {
const value = object[property];
const message = Array.isArray(value) && value.length <= 0 ?
`${propertyAlias} collection is empty` : null
cache.push(message);
return rules(object);
},
isString(property, propertyAlias = property) {
debugger;
const value = object[property];
const message = typeof value === 'string' ? null : `${propertyAlias} is not a string`;
cache.push(message);
return rules(object);
},
value() {
return cache.filter(Boolean);
}
}
}
function validateRunner(value) {
return rules(value)
}
You can call it like this...
const person = {
website: 'google.com',
name: 'Bi',
age: '23',
hobbies: [
'running',
'hiking'
]
};
const messages = validateRunner(person)
.minLengthStr('name', 'eeeeee')
.isString('name')
.emptyCollection('hobbies')
.value()
console.log(messages)
Example on CodePen
This has worked well so far.
But now we need to add some checks that are async..
For example, the OKUrl method..
let cache = [];
function fetchIt(url) {
return new Promise((res, rej) => {
setTimeout(() => {
const message = /http/.test(url) ? `${url} is ok` : null;
res(message);
}, 3000)
})
}
function rules(object) {
return {
addToCache(value) {
cache.push(value)
},
async okURL(property, propertyAlias = property) {
const message = await fetchIt(property);
return rules(object);
},
minLengthStr(property, propertyAlias = property) {
const value = object[property];
const message =
typeof value === 'string' && value.length > 2 ? null : `${propertyAlias} is less than 2`;
cache.push(message);
return rules(object);
},
emptyCollection(property, propertyAlias = property) {
const value = object[property];
const message = Array.isArray(value) && value.length <= 0 ?
`${propertyAlias} collection is empty` : null
cache.push(message);
return rules(object);
},
isString(property, propertyAlias = property) {
debugger;
const value = object[property];
const message = typeof value === 'string' ? null : `${propertyAlias} is not a string`;
cache.push(message);
return rules(object);
},
value() {
return cache.filter(Boolean);
}
}
}
function validateRunner(value) {
return rules(value)
}
const person = {
website: 'google.com',
name: 'Bi',
age: '23',
hobbies: [
'running',
'hiking'
]
};
const messages = validateRunner(person)
.minLengthStr('name', 'eeeeee')
.isString('name')
.emptyCollection('hobbies')
.okURL('website')
.value()
console.log(messages)
WIP Example on Codepen (This example does not work — just a WIP)
Is it possible to have a chainable structure like this with one or two async methods? Or does it call for totally changing the way its called?
let cache = [];
let minLengthStr = function(object, property, propertyAlias = property) {
return new Promise(function(resolve, reject) {
const value = object[property];
const message = typeof value === 'string' && value.length > 2 ? null : `${propertyAlias} is less than 2`;
cache.push(message);
resolve();
});
};
let emptyCollection = function(object,property, propertyAlias = property) {
return new Promise(function(resolve, reject) {
const value = object[property];
const message = (Array.isArray(value) && value.length <= 0) ? `${propertyAlias} collection is empty` : null;
cache.push(message);
resolve();
});
};
let isString = function(object,property, propertyAlias = property) {
return new Promise(function(resolve, reject) {
const value = object[property];
const message = typeof value === 'string' ? null : `${propertyAlias} is not a string`;
cache.push(message);
resolve();
});
}
let okURL = function(object,property, propertyAlias = property) {
return new Promise(function(resolve, reject) {
const value = object[property];
const message = /http/.test(value) ? `${value} is ok` : null;
cache.push(message);
resolve();
});
}
function validateRunner(value) {
Promise.all([minLengthStr(value,'name','fakeName'), emptyCollection(value,'hobbies', 'fakeHobbies'), isString(value,'name', 'dummyString'), okURL(value, 'website', 'fakeWebsite')]).then(function() {
console.log('All completed', cache.filter(Boolean));
});
}
const person = {
website: 'google.com',
name: null,
age: '23',
hobbies: []
};
validateRunner(person);
I have a problem searching for a nested array in my Angular app. I have to access the package.name. Please help thanksenfoiewfhfofhfowfoewhfowfoewhfwefwfhowefweofhew8ofwofhewofw8eofhwf
JSON
[{
"id": 1,
"name": "Yeah",
"package_id": 1,
"price": 100,
"package": {
"id": 1,
"name": "Yeah"
}
}]
TS
search(event) {
const val = event.target.value.toLowerCase();
if (!val) {
this.users = this.tempUsers;
}
const temp = this.tempUsers.filter((row) => {
return Object.keys(row).some((property) => {
return row[property] === null ? null : row[property].toString().toLowerCase().indexOf(val) !== -1;
});
});
this.users = temp;
}
TS
getAllUsers() {
this.usersService.getAll()
.subscribe(
(data: any) => {
console.log(data);
this.users = data.Users;
this.tempUsers= [...this.users];
},
error => {
console.log(error);
});
}
Does this work for you,
const temp = this.tempUsers.filter((row) => {
return Object.keys(row).some((property) => {
if (property === 'package') {
// check package.name value here
// like return row[property].name === 'something' ? true : false;
} else {
// the rest of the outer properties can be checked here
// not modifying your code here, but make sure it works for you
return row[property] === null ? null : row[property].toString().toLowerCase().indexOf(val) !== -1;
}
});
});
I have only answered your question on how to access the nested object inside the array method. Hope it helps or gives you an idea to fine tune your solution.
According to your data, You can use the following filter;
const filteredData = data.filter((item) => item.price.toString() === val || item.package_id.toString() === val || item.package.name.toString().toLowerCase().indexOf(val) !== -1 );
// UPDATED WITH CODE
search(event) {
const val = event.target.value.toLowerCase();
const filteredData = this.users.filter((item) => item.price.toString() === val ||
item.package_id.toString() === val ||
item.package.name.toString().toLowerCase().indexOf(val) !== -1 );
this.users = filteredData ;
}