In a Vue component I have a data() function that returns an object of data – standard stuff really:
data() {
return {
PlaceholderHTML: "",
ProductID: "",
CustomInvalidMessage: "",
Form: {
Price: "",
Currency: ""
},
}
},
When some data (usually a File) is posted to the server using axios, a ProductID is generated on the server and sent back to Vue. I then set the ProductID like
this.ProductID = response.data.ProductID;
All that works fine. In Vue Developer Tools the ProductID value is indeed set to 15005. If I do a console.log(ProductID) then I get back empty string on initial state and when ProductID is set after the axios.post() the console shows 15005.
So why does the following test never succeed?
const formData = new FormData();
if (this.ProductID != null && this.ProductID.length) {
formData.append("ProductID", this.ProductID); // This never happens
console.log(`Appended ${this.ProductID}`) // This too never prints anything
}
So if I remove the if(... && this.ProductID.length) part above, then there is no problem:
if (this.ProductID != null) {
formData.append("ProductID", this.ProductID); // Appended as empty string on initial state and then 15005 after this.ProductID is set
}
What is wrong with the && this.ProductID.length part?
this.ProductID is a number and in js the Number constructor does not have length method only String does so, to fix your problem check it like this:
this.ProductID.toString().length
Related
I would like to take the output of one query (a TRPC query on Prisma) and use this as the dependent input in a future query.
I followed the dependent documentation for React Query but running into type errors that the return of the first may possibly be undefined (e.g. product is possibly 'undefined'):
const { data: product } = api.product.getUnique.useQuery({ id: pid });
const options = api.option.getAll.useQuery(
{
product: product.productSize,
region: product.productRegion,
},
{ enabled: !!product }
);
Does the inclusion of enabled not already handle this? If not, what is the correct way to adapt for Typescript.
Just casting the product value as a boolean return any truthy value (f.e if product will be equal to {} it will still result in true, that means that product won't necessarily have the productSize or productRegion properties, I would change it first to:
{ enabled: !!product && product.productSize && product.productRegion }
If that doesn't fix the typescript error, you as a developer can know for sure that the values are actually there so what you can use the as keyword in typescript to tell it that you know for sure that the type is what you want it to be:
(In this example I assumed that the values are string but you can change it to number or whatever the true value of them are)
const options = api.option.getAll.useQuery(
{
product: product.productSize as string,
region: product.productRegion as string,
},
{ enabled: !!product && product.productSize && product.productRegion }
);
I'm trying to get the string value within a class-object variable called question5. I'm trying to access this variable like so in the front-end.
axios.get("http://localhost:3001/users/questionaire/?getquestion5=question5")
.then((res) => console.log(res.data))
Also, this is how it looks inside of the object in the js file.
const [answerslist, setAnswerslist] = useState(
{
question1: "",
question2: "",
question3: "",
question4: "",
question5: "",
question6: "",
question7: "",
question8: ""
}
)
However, when queried and log onto the console from the backend it literally just logs the string 'question5.' In other words, the string is literally just question5 not the text being added to it.
router.route('/questionaire').get((req, res) =>{
console.log(req.query.getquestion5)
User.find({email: req.query.getquestion5}, function (err, docs){
if(docs){
console.log("Email exist")
console.log(`${req.query.getquestion5}`);
console.log(docs)
}
else{
console.log(req.query.getquestion5)
console.log("Email doesnt exist")
}
}).clone().catch(function(err){console.log(err)})
})
Any reason why this might be the case?
If your intention is to send the answerlist.question5 state value in the query string getquestion5 parameter, try using Axios' params config option
params are the URL parameters to be sent with the request
Must be a plain object or a URLSearchParams object
NOTE: params that are null or undefined are not rendered in the URL.
axios.get("http://localhost:3001/users/questionaire", {
params: {
getquestion5: answerslist.question5
}
});
You'd then receive whatever value was in state at the time the request was made into the req.query.getquestion5 property.
Using params is preferable to interpolating strings directly into the URL since it will automatically URL-encode values that otherwise would not be valid. The equivalent safety measure would look like this...
axios.get(
`http://localhost:3001/users/questionaire?getquestion5=${encodeURIComponent(answerslist.question5)}`
);
which gets unmaintainable with more parameters.
I know that the same question has been asked before but none of them are working for me, so here is my requirement ->
I have users list and I logged in as a Admin, First I called getUsers api to get the list of the users and displayed the list in the UI, there is a button Accept for each user to approve them, So on click of Accept button, I am calling this method ->
const [allUserList, setAllUserList] = useState(usersArray)
const [filterUserListAfterUpdate, setFilterUserListAfterUpdate] = useState([])
const onClickAcceptUser (id) => {
let updatedUserList = []
allUserList.forEach(user => {
if(user._id === id){
user.approved_by_customer_admin = true
}
updatedUserList.push(user)
})
setFilterUserListAfterUpdate(updatedUserList)
}
return(<UserList filteredUsersList = {filterUserListAfterUpdate} onAccept={(id) => onClickAcceptUser(id) />)
NOTE -: I am using NodeJs as in backend and MongoDB and this is my full user object =>
//All the below values are dummy not real.
approved_by_customer_admin: false
auth0_id: "email|622e0414804c"
company_id: "622df44843fc4"
created_date: "2022-03-13T14:47:52.589Z"
email: "demo#gmail.com"
industry_name: "gmail"
is_active: false
phone_number: ""
prefer_contact: "email"
role: "customer_auditor"
updated_date: "2022-03-13T14:47:52.589Z"
__v: 0
_id: "6243ffa"
I need to change only one property of object(or maybe more than one, in future).
At the line user.approved_by_customer_admin = true I got the error in my console.
Any suggestions would be appreciable.
find an index of array of object and update the value of that like this
let updatedUserList = [...allUserList]
const objIndex = updatedUserList.findIndex(user => user._id == approveUser.id);
updatedUserList[objIndex].approved_by_customer_admin = true;
filterUserListAfterUpdate(updatedUserList)
Tapping in the dark: based in your comment in one of the answer mentioning "Cannot assign to read only property" I am suspecting some other component like Mongoose to produce the error.
Some search lead me to How to fix the error (TypeError: Cannot assign to read only property 'map' of object '#<QueryCursor>') and https://github.com/Automattic/mongoose/issues/11377, suggesting to downgrade Node (strictly below 17.5.0)
I have been in the process of teaching myself Vue.js and really like it so far. I have a project that I finally get the chance to use it on. I am creating a form and wanting to do some validations. I am used to the C# way of doing things, such as String.IsNullOrWhiteSpace() that just hits everything in one swoop. I haven't found a way to do that in Vue yet, if even possible. I do know of simpler ways to do it in regular javascript
This is my app and data
const app = new Vue({
el: '#app',
data() {
return {
errors: [],
parentInfo: {
name: null,
address: null,
city: null,
state: null,
zip: null,
primaryPhone: null,
secondaryPhone: null
}
}
}
...
Here are my validations for the form. This still does not catch if they add a whitespace to every field.
checkParentInfo: function () {
this.errors = [];
for (var i in this.parentInfo) {
if (this.parentInfo[i] === null && i !== 'secondaryPhone' || !this.parentInfo[i] && i !== 'secondaryPhone') {
this.errors.push('All parent info must be filled out, with the exception of a Secondary Phone Number');
return;
}
}
}
Is there a built in way to do my if statement? In one swoop like I can in C#?
Instead of if (this.parentInfo[i] === null) you can easily write if (!this.parentInfo[i]) which will be true when this.parentInfo[i] is anything but undefined, null, NaN, 0, "" (empty string) or false.
A string containing only a whitespace will return true, so you'll have to run if (this.parentInfo[i]===" ") for that.
You can of course create your own method IsNullOrWhiteSpace and use that instead.
Please also note that this is rather a Javascript question than a Vue.js question.
I declare state via redux connect
const mapStateToProps = state => ({
singleBase: state.interaction.base
});
export default requiresLogin()(connect(mapStateToProps)(BasePage));
The state shows fine via console log console.log(this.props.singleBase);
id: "5b757e6743904228586a5a7f"
creatorId: "5b6e39ce08406602d0a9e125"
title: "tester"
currentUsers: 2
messages: 0
On the backend I have the following model:
const BaseSchema = mongoose.Schema({
creatorId: { type: mongoose.Schema.Types.ObjectId, required: true },
title: { type: String, required: true },
currentUsers: { type: Number, default: 0 },
messages: { type: Number, default: 0 }
});
But when I try to console log the value of currentUsers: console.log(this.props.singleBase.currentUsers); I get the following error: Cannot read property 'currentUsers' of undefined.
I tried both setting the Schema to a pure number, e.g. 5, as well as as a text "5". Neither one works. What detail am I missing to be able to get the value of currentUsers ?
EDIT & SOLUTION:
const users =
this.props.singleBase && this.props.singleBase.currentUsers !== undefined
? this.props.singleBase.currentUsers
: 0;
return (
<div>
<h2>{users}</h2>
</div>
);
Here we ensure that this.props.singleBase exists and is true, while I make sure that this.props.singleBase.currentUsers has a value that is not undefined. If both evaluates true I display this.props.singleBase.currentUsers. The point of this is that until the asynchronous action has completed the singleBase will be empty. Once filled with data, I can display the currentUsers value.
You are most probably getting this data asynchronously, this is why you are getting this error. Before logging this.props.singleBase you should see an undefined in the console. This does not fire an error but if you try to get some property of an undefined object you hit this error. Trying to log undefined objects is ok, but trying to log a property where this object is undefined is not since at this time that object is undefined.
You can put a condition before your log:
this.props.singleBase && console.log(this.props.singleBase.currentUsers);
This is what will you do to render your items in the future instead of logging them. So, always remember, if you are doing an asynchronous job, there will be no data in the first render.
const users =
this.props.singleBase && this.props.singleBase.currentUsers !== undefined
? this.props.singleBase.currentUsers
: 0;
return (
<div>
<h2>{users}</h2>
</div>
);
Here we ensure that this.props.singleBase exists and is true, while I make sure that this.props.singleBase.currentUsers has a value that is not undefined. If both evaluates true I display this.props.singleBase.currentUsers. The point of this is that until the asynchronous action has completed the singleBase will be empty. Once filled with data, I can display the currentUsers value.
It might be happening because you're trying to console.log it before the current state is loaded. Try setting some flag like loading=true while you're getting your asynchronous data, and then change it to false after loading it.