vue 3 watch specific object's item from array - vue.js

I am working on nuxt 3 (vue 3) and I need to watch the particular item of the specific object from the array.
My array
const formData = reactive({
addressDetails: [
{
address: "",
street: "",
suburb: "",
state: "",
postCode: "",
country: "",
unitNumber: "",
streetNumber: "",
streetName: "",
timeAtaddressYears: "",
timeAtaddressMonths: "0",
},
]
});
Here, I want to watch if any timeAtaddressYears items value has changed but not on the whole formData.addressDetails value. Ex if I add new address details then no need to any watch but in specific address details if I change any address's timeAtaddressYears then watch should be called.

const formData = reactive({
addressDetails: [
{
address: "",
street: "",
suburb: "",
state: "",
postCode: "",
country: "",
unitNumber: "",
streetNumber: "",
streetName: "",
timeAtaddressYears: "",
timeAtaddressMonths: "0",
},
]
})
const selected = computed(() => {
return formData.addressDetails.map(form => form.timeAtaddressYears)
})
watch(selected, (newValue, oldValue) => {
console.log(newValue, oldValue)
})

You can try this:
watch(() => formData.addressDetails[0].address, (newValue, oldValue) => {
});

I have found a similar one, we need to add a deep watcher if we want to watch the particular item of the specific object from the array.
VueJS Deepwatchers
watch(
() => formData,
(newValue, oldValue) => {
console.log(newValue, oldValue);
},
{ deep: true });

Related

set the new coordinates on the user after editing the address

I'm trying to edit the lat and lng on edit user. I manage to get the location displayed when I add a new user (I use getLocation() for both "add new user" and "edit user"), but the values of the lat and lng don't update when I run the edit function.
I tried to console.log the values and I do get the values of the user I'm editing in the console as well as the new coordinates but the user itself isn't updating.
any ideas?
(I use "vue-browser-geolocation")
export default {
....
name: "UsersBox",
data() {
return {
users: [],
// notEditing: true,
editingId: "",
showAddBox: false,
user: {
img: "janeth carton.jpg",
name: "",
role: "",
liveLocation: "Riviera State 32/106",
address1: "",
address2: "",
phone: "",
coordinates: {
lat: 0,
lng: 0,
},
},
};
},
async mounted() {
this.users = await this.fetchUsers();
},
methods: {
async saveEdit(userData) {
await this.getLocation(userData);
await fetch(`api/users/${userData.id}`, {
method: "PUT",
headers: {
"Content-type": "application/json",
},
body: JSON.stringify(userData),
})
.then((response) => response.json())
.then((userData) => console.log(userData));
this.editingId = "";
},
async getLocation(newUser) {
const API_KEY = "AIzaSyDkWzva7dAFQTO6rQVxZZawYTrcuo04PfI";
const API_URL = `https://maps.googleapis.com/maps/api/geocode/json?address=${newUser.address1}+${newUser.address2}&key=${API_KEY}`;
const apiResponse = await fetch(API_URL);
const locationData = await apiResponse.json();
console.log(locationData, "location");
console.log(locationData.results[0].geometry.location.lng, "lng");
console.log(locationData.results[0].geometry.location.lat, "lat");
console.log(this.user.coordinates.lat, "edit user lat");
this.user.coordinates.lat = locationData.results[0].geometry.location.lng;
this.user.coordinates.lng = locationData.results[0].geometry.location.lat;
},
....
},
};
</script>

vuesax put in vue api data table

https://codepen.io/oxy1023/pen/gOKzbBL
methods: {
datas() {
var vm = this;
axios
.get(`http://115.145.177.104:1807/machinerepairhistory`, [
{
company: "",
factory: "",
repairno: "",
model_group: "",
repairdate: "",
repairtime: "",
repaircomp: "",
repairissue: "",
sparepart: "",
repairstory: "",
repairamt: "",
repairuserid: "",
repairusernm: "",
remark: "",
createdate: "",
createid: "",
updatedate: "",
updateid: "",
},
])
.then((response) => {
console.log("response.data : " + JSON.stringify(response.data));
vm.datas = response.data;
})
.catch((error) => {
console.error(error);
});
axios;
I have created a table using vuesax.
I want to insert data, but it doesn't come out properly. Why?
Is the data not entering properly in 'datas'?

like/dislike button with api call not working using vue an mongoDB

I am learning vuejs and i am working on my first project which is a social network, and i want to implement a like button that call the api to add a like or remove it if the user has already liked it. It does work in my backend but i can't make it work in the front.
I need to send the userId and add or remove the like when i click on the button
This is the data
data() {
return {
post: {
file: "",
content: "",
likes: 0,
},
showModal: false,
showModifyPost: false,
user: {
firstname: "",
lastname: "",
_id: "",
},
};
},
the last method i tried
likePost(id) {
axios
.post('http://127.0.0.1:3000/api/post/like/' + id, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
})
.then(() => {
console.log("response", response);
this.user._id = response.data._id;
if(post.usersLiked == user._id) {
this.post.likes += 0
} else if (post.usersLiked != user._id) {
this.post.likes += 1
};
})
.catch((error) => console.log(error));
}
and this is the model
const postSchema = mongoose.Schema({
userId: { type: String, required: true, ref: "User" },
content: { type: String, required: true, trim: true },
imageUrl: { type: String, trim: true },
likes: { type: Number, default: 0 },
usersLiked: [{ type: String, ref: "User" }],
firstname: {type: String, required: true, trim: true },
lastname: {type: String, required: true, trim: true },
created_at: { type: Date},
updated_at: { type: Date }
});
Any idea what is wrong ? Thank you !
.then(() => { // you missed value response from Promise here
this.user._id = response.data._id;
if(post.usersLiked == user._id)
})
Do you mean this.post.usersLiked === user._id I suppose, so post within your data options should be
post: {
file: "",
content: "",
likes: 0,
usersLiked: false,
// something else reflect to your post schema
},
i want to implement a like button that call the api to add a like or remove it if the user has already liked it
By saying that you just need a simple boolean value to do this
likePost(id) {
axios
.post('http://127.0.0.1:3000/api/post/like/' + id, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
})
.then((response) => {
// Just need to toggle state
this.$set(this.post, 'usersLiked', this.post.usersLiked !== response?.data?._id)
})
.catch((error) => console.log(error));
}
Found the answer, i changed the axios method to this
likePost(id) {
let userId = localStorage.getItem('userId');
axios
.post('http://127.0.0.1:3000/api/post/like/' + id, { userId }, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
})
.then((response) => {
console.log(response.data);
this.getAllPost();
})
.catch((error) => console.log(error));
}
i also made a few changes to the data
data() {
return {
posts: [],
post: {
file: "",
content: "",
},
showModal: false,
showModifyPost: false,
user: {
firstname: "",
lastname: "",
_id: "",
},
};
},
and i also made some changes on the controller
exports.ratePost = (req, res, next) => {
console.log(req.body.userId)
//using findOne function to find the post
Post.findOne({ _id: req.params.id }).then(post => {
if (!post.usersLiked.includes(req.body.userId)) {
// making a object with $inc and $push methods to add a like and to add the user's id
let toChange = {
$inc: { likes: +1 },
$push: { usersLiked: req.body.userId },
};
// we update the result for the like
Post.updateOne({ _id: req.params.id }, toChange)
// then we send the result and the message
.then(post =>
res
.status(200)
.json(
{ message: "Liked !", data: post }
)
)
.catch(error => res.status(400).json({ error }));
} else if (post.usersLiked.includes(req.body.userId)) {
// using the updateOne function to update the result
Post.updateOne(
{ _id: req.params.id },
// we use a pull method to take off a like
{ $pull: { usersLiked: req.body.userId }, $inc: { likes: -1 } }
)
.then(post => {
// then we send the result and the message
res
.status(200)
.json(
{ message: "Post unliked", data: post }
);
})
.catch(error => res.status(400).json({ error }));
}
});
};

How to convert a html button into native script?

This is the html code, this button is used to filter food by name:
So the name of the food should be displayed as a button so that users can filter the option.
<button id="filterme" v-for="f in filterFood"
#click="$chooseFilter(f)">Filter food by {{f}}</button>
This is the script code:
const app = new Vue({
el: "#app",
data: {
thisFood: [], //food array
newFood: {
name: "",
price: "",
cuisine: ""
},
filterFood: ["null", "pizza", "chips", "rice", "chocolate", "salad"]
methods() {
if (localStorage.getItem("thisFood")) {
try {
this.thisFood= JSON.parse(localStorage.getItem("thisFood"));
} catch (e) {
localStorage.removeItem("newFood");
}
this.thisFood.push(this.newFood); //add new food
this.newFood= {
name: "",
price: "",
cuisine: "",
}
}
},
chooseFilter(filter) {
this.filter = filter;
},
I tried using a button it's not working.
<button text:"filterme" for =" f in filterFood" #tap="chooseFilter(f)">
Filter food by {{f}} </button>
Please take another look at the Vue documentation: https://v2.vuejs.org/v2/guide/components.html
Maybe you're not sharing all your code, but the structure is way off.
Your methods function (which should be an object) is inside your data object.
Besides that you're missing parentheses .
Start with a valid structure and syntax:
const app = new Vue({
el: "#app",
data: {
thisFood: [], //food array
newFood: {
name: "",
price: "",
cuisine: "",
},
filterFood: ["null", "pizza", "chips", "rice", "chocolate", "salad"]
},
methods: {
chooseFilter(filter) {
//
}
},
});

vue js axios response to array list

i am working a typeahead. and my typeahead accept a array list like ['Canada', 'USA', 'Mexico'].
and now i have a axios api to get a list of country. but i don't know how can i convert to a array list. Now work if hardcode a country list.
<vue-bootstrap-typeahead
:data="addresses"
v-model="addressSearch"
/>
data() {
return {
addresses: ['Canada', 'USA', 'Mexico'],
addressSearch: '',
}
},
axios.get('api_link', {})
.then(function (response) {
//How can i create a array list from api return useing name like addresses?
})
And my api return:
[
{
"id": 1,
"name": "Canada"
},
{
"id": 2,
"name": "USA"
},
]
Make use of the created() lifecycle hook to get the data:
created() {
axios.get('api_link', {})
.then((response) => { this.addresses = response.data.map(x => x.name) })
}
In your data() make sure to initialize to an empty array:
data() {
return {
addresses: [],
...
}
Just so you see what the map function does:
console.log([ { "id": 1, "name": "Canada" }, { "id": 2, "name": "USA" }, ].map(x=>x.name))
You can use array.map to take only the names like this:
axios.get('api_link', {})
.then((response) => {
this.addresses = response.data.map(country => country.name)
})