I am trying to get data through NUXT Api.
also want to return it to the computed property.
I'm sure I missed some stupid mistake or something simple.
I appreciate help.
async asyncData ({ app, params }) {
let listdata = []
try {
const Id = params.someid
const { data } = await app.$axios.get(`/api/some/path/me/${Id}`)
listdata = data
return {
listdata
}
} catch (e) {
return (e)
}
},
data () {
return {
}
}
computed here.
computed: {
returnlist () {
const list = this.listdata
return list
}
},
and result undefined
listdata console.log here
{data: Array(4), status: 200, statusText: 'OK', headers: {…}, config: {…}, …}
config: {url: '/api/some/path/me/Obj_id', method: 'get', headers: {…}, baseURL: '/', transformRequest: Array(1), …}
data: Array(4)
0: {partiant: Array(2), _id: 'Obj_id', sender: 'Obj_id', …}
1: {partiant: Array(2), _id: 'Obj_id', sender: 'Obj_id', …}
2: {partiant: Array(2), _id: 'Obj_id', sender: 'Obj_id', …}
3: {partiant: Array(2), _id: 'Obj_id', sender: 'Obj_id', …}
length: 4
...
status: 200
statusText: "OK"
[[Prototype]]: Object
Related
In an admin profile, I have a list where I display the session history. I created a button to delete all sessions where isActive = false. To see the result I have to refresh my page. I want the data updated dynamically.
I'm trying to use a forEach loop to check if session isActive = false, delete the session and update sessions.
Here it's what I have done but it only removes 2-3 raw of sessions. It should remove ALL inactive sessions.
import { defineStore } from "pinia";
import axios from "axios";
export const useAuthenticationStore = defineStore({
id: "authenticationStore",
state: () => ({
session: null,
sessions: [],
loaders: {
login: false,
logout: false,
retrieveSession: false,
retrieveSessions: false,
deleteInactiveSessions: false,
},
}),
getters: {
admin: (state) => state.session?.admin,
},
actions: {
async deleteInactiveSessions(id) {
const apiRoute = `/api/inactive-sessions`;
try {
this.loaders["deleteInactiveSessions"] = true;
const deletedInactiveSessions = await axios.delete(apiRoute);
console.log(deletedInactiveSessions);
this.sessions.forEach(() => {
const deletedInactiveSessionsIndex = this.sessions.findIndex(
(session) => session.id === deletedInactiveSessions.id
);
return this.sessions.splice(deletedInactiveSessionsIndex);
});
} finally {
this.loaders["deleteInactiveSessions"] = false;
}
},
This is what deletedInactiveSessions returns me:
{data: {…}, status: 200, statusText: 'OK', headers: AxiosHeaders, config: {…}, …}
config
:
{transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}
data
:
{count: 3}
headers
:
AxiosHeaders {access-control-allow-credentials: 'true', access-control-allow-origin: '*', connection: 'close', content-length: '11', content-security-policy: "default-src 'self';base-uri 'self';block-all-mixed… https: 'unsafe-inline';upgrade-insecure-requests", …}
request
:
XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status
:
200
statusText
:
"OK"
[[Prototype]]
:
Object
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 }));
}
});
};
I am creating an application in which a user can create how to update a project, the application is being done with Vue 3 and Go, but I find a problem and that is that when I want to obtain the project data and then update the information it is generated An error, and it is that when obtaining the data from the api it does well because it shows me the information I want, the problem is when I refresh the page because the data is lost immediately.
this is an example of what the api returns me:
{
"id_project": 3,
"name": "gbhnju",
"description": "derftgyh",
"start_date": "2021-08-06T00:00:00Z",
"end_date": "2021-08-17T00:00:00Z",
"created_at": "2021-08-06T15:57:19.27Z",
"updated_at": "0001-01-01T00:00:00Z"
}
These values are returned, but when I update the page they are lost.
This is the component that makes the request to obtain the project data:
export default {
components: { EditProject },
setup() {
const route = useRoute();
const project = reactive({});
onMounted(() => {
fetch(`http://localhost:8000/api/v1/projects/${route.params.id}`)
.then((res) => res.json())
.catch((error) => console.error(error))
.then((data) => {
Object.assign(project, data);
});
});
return {
project,
};
},
};
</script>
And this is the component which receives the information to be able to update the data:
<script>
import { ref, toRef, toRefs } from '#vue/reactivity';
import { useRoute, useRouter } from 'vue-router';
export default {
props: {
project: {
type: Object,
required: true,
},
},
setup(props) {
const project = toRefs(props.project);
console.log(project);
const content = toRef(props, 'project');
const name = toRef(content.value, 'name');
const description = toRef(content.value, 'description');
const endProject = toRef(content.value, 'endProject');
const user = toRef(content.value, 'user');
const users = ref();
const route = useRoute();
const router = useRouter();
fetch(`http://localhost:8000/api/v1/users/selected_user`)
.then((data) => data.json())
.catch((error) => console.error(error))
.then((response) => {
users.value = response;
});
const editProject = () => {
if (
name.value === '' ||
description.value === '' ||
endProject.value === '' ||
user.value === ''
) {
console.log('error');
return;
}
fetch(`http://localhost:8000/api/v1/projects/${route.params.id}`, {
method: 'PUT',
body: JSON.stringify({
name: name.value,
description: description.value,
end_date: new Date(endProject.value.replace('-', '/')),
user: {
id_user: user.value,
},
}),
headers: {
'Content-Type': 'application/json',
},
});
router.push({
name: 'Project',
});
};
return {
name,
description,
endProject,
user,
users,
editProject,
};
},
};
</script>
This is the sample code to display the data by console:
const end_date = toRefs(props.project, 'end_date');
console.log(end_date);
What it shows me by console is the following:
created_at: ObjectRefImpl {_object: Proxy, _key: "created_at", __v_isRef: true}
description: ObjectRefImpl {_object: Proxy, _key: "description", __v_isRef: true}
end_date: ObjectRefImpl
__v_isRef: true
_key: "end_date"
_object: Proxy {id_project: 3, name: "gbhnju", description: "derftgyh", start_date: "2021-08-06T00:00:00Z", end_date: "2021-08-17T00:00:00Z", …}
value: "2021-08-17T00:00:00Z"
[[Prototype]]: Object
id_project: ObjectRefImpl {_object: Proxy, _key: "id_project", __v_isRef: true}
name: ObjectRefImpl {_object: Proxy, _key: "name", __v_isRef: true}
progress: ObjectRefImpl {_object: Proxy, _key: "progress", __v_isRef: true}
project_state: ObjectRefImpl {_object: Proxy, _key: "project_state", __v_isRef: true}
start_date: ObjectRefImpl {_object: Proxy, _key: "start_date", __v_isRef: true}
updated_at: ObjectRefImpl {_object: Proxy, _key: "updated_at", __v_isRef: true}
user: ObjectRefImpl {_object: Proxy, _key: "user", __v_isRef: true}
user_creation: ObjectRefImpl {_object: Proxy, _key: "user_creation", __v_isRef: true}
But when I want to show the value of the toRef by console it generates an undefined one, or if I update the page the obtejo is as if it were lost:
console.log(end_date.value);
This is what it shows me when I update the page:
[[Prototype]]: Object
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
get __proto__: ƒ __proto__()
I've two Models, Post and Tag with Many To Many relationships.
Post Schema:
const postSchema = new Schema(
{
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: [true, 'A post must belong to a user.'],
},
title: {
type: String,
unique: [true, 'A Post already exists with this title.'],
required: [true, 'A Post must have a title.'],
},
slug: { type: String, unique: true },
body: { type: String, required: [true, 'A Post must have a body.'] },
coverImage: String,
images: Array,
isDraft: { type: Boolean, default: false },
isPublished: { type: Boolean, default: false },
tags: [{ type: Schema.Types.ObjectId, ref: 'Tag' }],
},
{
timestamps: { currentTime: () => Math.floor(Date.now() / 1000) },
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
)
Tag Schema:
const tagSchema = new Schema(
{
title: { type: String, required: true },
slug: { type: String },
posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }],
},
{
timestamps: { currentTime: () => Math.floor(Date.now() / 1000) },
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
)
Now I want to remove all the references of the Posts from the Tag documents when a Post is deleted.
I'm trying to the following remove middleware in the Post model but it is not working. The post get deleted but the reference still there on the Tag documents.
postSchema.pre('remove', function (next) {
var post = this
post
.model('Tag')
.update(
{ posts: { $in: post.tags } },
{ $pull: { posts: post._id } },
{ multi: true },
next
)
})
After trying many times I finally fired out what wrong I was doing. Following the fix I made to make it work:
In Post Controller I was previously doing this:
const post = await Post.findByIdAndDelete(req.params.id)
Which I changed to:
const post = await Post.findById(req.params.id)
await post.remove()
And in Post Model:
postSchema.pre('remove', async function (next) {
await this.model('Tag').updateMany(
{ posts: this._id },
{ $pull: { posts: this._id } },
{ multi: true },
next
)
})
I develop a project which gets datas from database. I use Vuex for state management.
Vuex Store File
const store = createStore({
state: {
notUser: {
name: "",
email: '',
password: ''
},
user: {
name: '',
email: '',
messages: [],
about: '',
place: '',
age: '',
role: '',
blocked: false
},
problem: {
title: '',
content: ''
},
problems: [],
errorMessage: {
error: false,
message: '',
success: false
},
},
mutations: {
errorHandler(state, error) {
state.errorMessage.error = true
state.errorMessage.message = error.response.data.message
},
defineUser(state, req) {
state.user = req.data.user
console.log(state.user)
},
getProblems(state, problems) {
state.problems = problems
console.log(state.problems)
}
},
actions: {
register({ commit }, notUser) {
axios({
method: 'post',
url: 'http://localhost:3000/api/auth/register',
data: notUser,
withCredentials: true,
headers: {
"Accept": "application/json"
}
})
.then(res => {
this.state.errorMessage.success = true
console.log(res.data.data.user)
})
.catch(err => {
this.state.errorMessage.success = false
console.log(err.response)
commit('errorHandler', err)
})
},
userLogin({commit}, notUser) {
axios({
method: 'post',
url: 'http://localhost:3000/api/auth/login',
data: notUser,
withCredentials: true,
headers: {
"Accept": "application/json"
}
})
.then(res => {
this.state.user = res.data.data.user
this.state.errorMessage.success = true
console.log(this.state.user)
})
.catch(err => {
this.state.errorMessage.success = false
console.log(err.response)
commit('errorHandler', err)
})
},
checkUser({commit}, access_token) {
axios({
method: 'post',
url: 'http://localhost:3000/api/auth/VpW02cG0W2vGeGXs8DdLIq3dQ62qMd0',
data: access_token,
withCredentials: true,
headers: {
"Accept": "application/json"
}
})
.then(res => {
console.log(res)
commit('defineUser', res)
return true
})
.catch(err => {
console.log(err.response)
commit('errorHandler', err)
return false
})
},
sendProblem({commit}, problem) {
axios({
method: 'post',
url: 'http://localhost:3000/api/problem/add',
data: problem,
withCredentials: true,
headers: {
"Accept": "application/json"
}
})
.then(res => {
console.log(res)
return true
})
.catch(err => {
console.log(err.response)
commit('errorHandler', err)
return false
})
},
getAllProblems({commit}) {
axios({
method: 'get',
url: 'http://localhost:3000/api/problem/getall',
withCredentials: true,
headers: {
"Accept": "application/json"
}
})
.then(res => {
commit('getProblems', res.data.data)
return true
})
.catch(err => {
console.log(err.response)
commit('errorHandler', err)
return false
})
}
// registerUser({commit}, user) {
// commit('register', user)
// }
},
Vue Component: Where Vuex store is being used
computed: {
...mapState(["user", 'problems'])
},
mounted() {
return this.getAll()
},
methods: {
...mapActions(['getAllProblems']),
goToAdd() {
this.$router.push('/add')
},
async getAll() {
this.getAllProblems()
}
}
The problem is when I try to request with getAllProblems action, it should mutate problems variable with getProblems(). Actually it does. But after problems variable changes, it turns something a proxy object. Here are images:
Here is an image of proxy object:
The original data coming from database:
Thanks for comment of #Hasan Hasanova
Okay got it. I called api before website is mounted and used function to get variables from store. The other problem was happened because of using wrong syntax of v-for. Here is the code:
computed: {
allProblems() { // this is the problems array that i was trying to get
return this.$store.state.allProblems
},
loader() {
return this.allProblems == null ? true : false
}
},
beforeMount() {
this.$store.dispatch('getAllProblems', {root: true})
},
And here is the template code :
<div v-if="allProblems.length > 0" class="middle-side">
<div v-for="(problem) in allProblems" :key="problem.id" class="card">
<router-link :to="{ name: 'ProblemDetail', params: { id: problem._id, slug: problem.slug }}">
<div class="card-header">
<div class="card-header-title">
<div class="user-image">
<img src="../../assets/problem.png" />
</div>
<span class="user-name">{{ problem.user.name }}</span>
</div>
...
Thanks for all.
I have the same problem as yours, but I solved it first by converting it before the getter's return, converting it to JSON to string, and converting a string to JSON again before returning it.
const str = JSON.stringify(data)
return JSON.parse(str)
You want to use mapActions to call the action. Then get your data via state, instead of returning the function, since the action is calling a mutation via commit.
computed: {
// you have access to `problems` in the template. Use `v-if` before you `v-for` over the array of problems.
...mapState(["user", 'problems'])
},
mounted() {
this.getAllProblems();
},
methods: {
// ...mapActions(['getAllProblems']),
goToAdd() {
this.$router.push('/add')
}
}
For some reason that happens during the passing of res.data.data to mutations. So if you're expecting a single row result set you should do like:
POPULATE_THIS_STATE_VAR(state, data) {
state.thisStateVar = data[0]
}
... and if you're expecting an array of objects to the result set like what you have, you could do like:
POPULATE_THIS_STATE_VAR(state, data) {
if (data) {
for (let i = 0; i < data.length; i++) {
state.thisStateVar .push(data[i])
}
}
}