If you put a value in every input, it works normally. However, errors appear even if only one input is empty.
nameValue.length, an error appears that you cannot work on the length.
Object.values(nameValue).length, the error 'Cannot convert undefined or null to object' appears.
const [values, setValues] = useState({
nameValue: '',
numberValue: '',
contentValue: '',
});
const { nameValue, numberValue, contentValue } = values;
const handleNumber = e => {
const { value, name } = e.target;
setValues({
...values,
[name]: value,
});
};
useEffect(() => {
if (numberValue.length === 11) {
setValues({
numberValue: numberValue.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3'),
});
} else if (numberValue.length === 13) {
setValues({
numberValue: numberValue
.replace(/-/g, '')
.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3'),
});
}
}, [numberValue]);
const handleSend = e => {
e.preventDefault();
//console.log(typeof stringify(nameValue) === 'undefined');
const nameValueTrue =
Object.values(nameValue).length > 4 ||
Object.values(nameValue).length < 1 ||
typeof nameValue !== 'string' ||
typeof nameValue === 'undefined';
const numberValueTrue =
Object.values(numberValue).length < 13 ||
Object.values(numberValue).length > 14;
const contentValueTrue =
typeof contentValue !== 'string' ||
Object.values(contentValue).length < 2;
const error = !e.target.value;
if (nameValueTrue) {
alert('이름을 확인해주세요.');
console.log('name안');
} else if (numberValueTrue) {
console.log('number');
alert('휴대폰번호를 확인해주세요.');
} else if (contentValueTrue) {
console.log('content');
alert('내용을 확인해주세요.');
} else {
goto();
}
};
<ContentBox>
<div>Name</div>
<ContentInput
name="nameValue"
value={nameValue || undefined}
//value={nameValue || ''}
//value={nameValue}
onChange={handleNumber}
/>
</ContentBox>
<ContentBox>
<div>Phone Number</div>
<ContentInput
name="numberValue"
value={numberValue || undefined}
//value={numberValue || ''}
//value={numberValue}
onChange={handleNumber}
/>
</ContentBox>
<ContentBox>
<div>Content</div>
<ContentInput
placeholder="내용 입력."
name="contentValue"
value={contentValue || undefined}
//value={contentValue || ''}
//value={contentValue}
onChange={handleNumber}
/>
</ContentBox>
<Submit onClick={handleSend}>Send</Submit>
In your useEffect, you're overwriting the whole values object to just be numberValue. You need to spread the object there too, like you have in handleNumber
Related
I am parsing a few emails from a CSV in the method below and i am getting Cannot read properties of undefined (reading 'emailAddress'). I even tried filtering the undefined results out but no luck . How can I filter the ones that are undefined.
const getContactsFromText = (text) => {
if(text == "" || text.trim() == '' || text === undefined){
settingTheAlert();
return;
}
const contacts = text.split(/[,;\n]/)
.filter(x => x.length > 0)
.map(x => x.trim())
.map(x => {
const [, , displayName = '', emailAddress = ''] = x.match(/"?((.*?)"?\s*<)?([^">]*)/);
if (!emailAddress && !displayName) return;
if(emailAddress === undefined) return;
return { id: emailAddress, emailAddress, displayName, isChecked: true };
})
.filter(x => isValidEmail(x.emailAddress))
.sort(sortByEmail);
if(contacts.length < 1){
settingTheAlert();
return;
}
onImport(contacts);
}
const isValidEmail = (email) => {
const EMAIL_RE = /^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const isValid = EMAIL_RE.test(String(email).toLowerCase());
if (!isValid) console.log('invalidEmail', { email })
return isValid;
}
In your code here:
.map(x => {
const [, , displayName = '', emailAddress = ''] = x.match(/"?((.*?)"?\s*<)?([^">]*)/);
if (!emailAddress || !displayName) return;
if (emailAddress === undefined) return; // this is useless (it's covered above)
return { id: emailAddress, emailAddress, displayName, isChecked: true };
};
})
you implicitly return nothing/undefined on these lines:
if (!emailAddress || !displayName) return;
if (emailAddress === undefined) return; // again, this line is not needed
which is equivalent to returning undefined. Then in the subsequent filter you assume the x.emailAddress exists, but it might not, as just above you were returning undefined under some corner cases.
To remedy that you either:
Gotta change your filter function (probably the best solution)
Make the isValidEmail function expect the whole email object rather than the expected string (probably a bit less desirable)
If you got for the first approach, it should look something like:
// ... other code
.map(x => {
const [, , displayName = '', emailAddress = ''] = x.match(/"?((.*?)"?\s*<)?([^">]*)/)
if (!emailAddress || !displayName) {
return null
}
return { id: emailAddress, emailAddress, displayName, isChecked: true }
})
.filter(emailObj => emailObj && isValidEmail(emailObj.emailAddress)) // checking first that the emailObj is not undefined and then checking if the emailObj.emailAddress is valid.
Should work.
I'm trying to set validPassword and validFormData values to false whenever a form is submited and the values are empty. I'm calling this function on submit but it's only changing the last property in my useState
const [validPassword, setValidPassword] = useState({
password: true,
confirmPassword: true
})
const [validFormData, setValidFormData] = useState({
email: true,
name: true,
lastName: true,
phone: true,
})
const signupAction = (e) => {
e.preventDefault()
if (formData.email === "" || formData.name === "" || formData.lastName === "" || formData.phone === "" || formData.password === "" || formData.confirmPassword === "") {
for (let p in formData) {
if (formData[p] === "") {
if (p === "password" || p === "confirmPassword") {
setValidPassword({ ...validPassword, [p]: false })
} else {
setValidFormData({ ...validFormData, [p]: false })
}
}
}
} else {
console.log('success')
}
/* signup(formData, history) */
}
What I get from this is:
validPassword = {
password: true,
confirmPassword: false
}
validFormData = {
email: true,
name: true,
lastName: true,
phone: false,
}
The setState function is async. The common pattern of setting a state which is the one you are using is not fool proof one. One should use callback based setting state to by pass these common issues. Code like below would work
const signupAction = (e) => {
e.preventDefault()
if (formData.email === "" || formData.name === "" || formData.lastName === "" || formData.phone === "" || formData.password === "" || formData.confirmPassword === "") {
for (let p in formData) {
if (formData[p] === "") {
if (p === "password" || p === "confirmPassword") {
setValidPassword((prevState) => ({...prevState, [p]: false }))
} else {
setValidFormData((prevState) => ({ ...prevState, [p]: false }))
}
}
}
} else {
console.log('success')
}
/* signup(formData, history) */
}
Further, to prevent multiple updates, it is best if you store the changes in the loop in a local variable and set all at once like below
const signupAction = (e) => {
e.preventDefault()
if (formData.email === "" || formData.name === "" || formData.lastName === "" || formData.phone === "" || formData.password === "" || formData.confirmPassword === "") {
const tempValidPassword = { ...validPassword};
const tempValidFormData = { ...validFormData};
for (let p in formData) {
if (formData[p] === "") {
if (p === "password" || p === "confirmPassword") {
tempValidPassword[p] = false;
} else {
tempValidFormData[p] = false;
}
}
}
setValidPassword(tempValidPassword);
setValidFormData(tempValidFormData);
} else {
console.log('success')
}
/* signup(formData, history) */
}
Note: These are only pesudo-code. Fit according to your needs. Try to use functional updates to state as mentioned here whenever possible
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
}
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!
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 ;
}