Axios setting response data in vue component variable but variable not displaying data on browser - vue.js

Axios setting response data in Vue component variable but variable not displaying data on the browser. We can see data on console but when I display, Browser shows me nothing. Data are in JSON Format.
Snapshot:
Output:
<template>
<div class="card">
<div class="card-header">Subject</div>
<div class="card-body" >
<!-- <ul class="list-group">
<li class="list-group-item" :key = "message.id" v-for = "message in messages"> {{ message.subject}}</li>
</ul> -->
{{messages}}
</div>
</div>
</template>
<script>
export default{
name: 'subject-component',
data () {
return {
messages:{}
}
},
mounted () {
},
created(){
axios.get('http://127.0.0.1:8000/subject/get')
.then(response => {this.messages = response.data})
.catch((error) => console.log(error));
}
}
</script>

By setting up the project again, this issue has been resolved. And again I used the same approach for axios request like.
axios.get('http://127.0.0.1:8000/get/subjects')
.then((response)=>(this.subjects = response.data))
.catch(function(error){console.log(error)});
Thank you all for your effort.

Related

Axios get request and display results to html with vue

Currently learning Vue and Axios, and i'm trying to get data from an API and display it within an HTML card, but it seems that it tries to display the data before getting it from the API and then nothing renders.
<script type="text/javascript">
const {createApp} = Vue;
const data = null;
const error = null;
const app = createApp({
data(){
return{
movieID: localStorage.getItem("movieID"),
movieDetail: null
}
},
methods:{
getMovieDetail(){
var config = {
method: 'get',
url: 'https://api.themoviedb.org/3/movie/'+localStorage.getItem("movieID"),
headers: {
'Authorization': 'Bearer'
}
};
axios(config);
app.movieDetail = respuesta.data;
document.getElementById("tituloPeli").innerHTML = app.movieDetail.title
.then(function (response) {
app.movieDetail = response.data;
})
.catch(function (error) {
console.log(error);
});
}
},
mounted(){
this.getMovieDetail();
}
}).mount("#contenedor");
</script>
<div id="contenedor">
<div class="container-xxl my-4">
<h1>Data from movie with ID {{movieID}}</h1>
</div>
<div class="container">
<div class="row align-items-start">
<div class="col-12">
<div class="card my-2">
<img class="card-img-top" :src="'https://image.tmdb.org/t/p/w600_and_h900_bestv2' + movieDetail.poster_path">
<div class="card-body">
<h6 class="card-title">
{{movieDetail.title}}
</h6>
</div>
</div>
</div>
</div>
</div>
</div>
Highly appreciated if you could help me, thank u so much
The key is to not render the data until it's ready. This is called conditional rendering and can be done using the v-if directive
<h6 v-if="movieDetail?.title" class="card-title">
{{movieDetail.title}}
</h6>
Along with standard javascript optional chaining you can guarantee an object and it's properties are all defined before rendering it in your template.

Nuxt-content not working with asyncData in a component

I'm trying to fetch content from my content/blog folder but I can't make it work in the components/menu.vue page since it's a component ?
This is working in the page/index.vue but not in components/menu.vue. Why?
I'm new to all this and maybe I'm doing something wrong here, maybe I'm not able to fetch content from a component... I don't know.
<template>
<div class="container">
<div class="articles">
<div class="article" v-for="article of articles" :key="article">
<nuxt-link :to="{ name: 'slug', params: { slug: article.slug } }">
<div class="article-inner">
<img :src="require(`~/assets/${article.img}`)" alt="" />
<div class="detail">
<h3>{{ article.title }}</h3>
<p>{{ article.description }}</p>
</div>
</div>
</nuxt-link>
</div>
</div>
</div>
</template>
<script>
export default {
async asyncData ({ $content, params }) {
const articles = await $content('blog', params.slug)
.only(['title', 'description', 'img', 'slug'])
.sortBy('createdAt', 'asc')
.fetch()
console.log('bongo')
return {
articles
}
},
data () {
return {
num: this.$route.name
}
},
computed: {
currentRouteName () {
return this.$route.name
}
}
}
</script>
As written here: https://nuxtjs.org/docs/features/data-fetching#async-data
asyncData is only available for pages and you don't have access to this inside the hook.
So yes you can use asyncData only in a page.
An alternative would be to use a non-blocking fetch() hook as shown here: https://nuxtjs.org/docs/features/data-fetching#accessing-the-fetch-state

make the title post clickable vue

I'm using vue + laravel and i try do display the data from api like this:
<div v-for="article in articles" :key="article.id" class="hieght">
<div class="NewArticle">
<h6 class="NewArticleTitle">{{ article.title.ar }}</h6>
</div>
<div>
<p class="NewArticleBody">{{ article.excerpt.ar }}</p>
</div>
</div>
and the script is:
<script>
export default {
data() {
return {
articles: []
}
},
created() {
this.axios
.get('http://localhost:8000/api/articles/')
.then(response => {
this.articles = response.data;
});
}
}
But I want the post to open when I click on the title, I don't know how can i do that using vue
You need to create a view component for your post. and make the h6 title tag a router-link tag that takes you to the post (or article) details page.

vuejs problem change route get userChoice in localstorage but push on the profile route before getting new userChoice?

the problem is that on click I increments the new userChoice according to the user chosen but it pushes on the profile route before retrieving the new userChoice click.
what to do here is my template I will put everything in the same function change use the push at the end but it does not work either then I do 2 functions but it does not work either what is the solution ??
<template>
<section
class="stopPadMarg container-fluid d-md-flex justify-content-between"
>
<div class="py-5 stopPadMarg bg-primary col-md-1">
<img
src="../assets/image/icon.png"
width="60px"
class="rounded-circle"
alt="logo"
/>
</div>
<div class="largeur80">
<form class="justify-content-center form-inline py-3 my-2 my-lg-0">
<input
v-model="searchKey"
id="search"
class="form-control mr-sm-2"
type="search"
placeholder="Search"
aria-label="Search"
/>
</form>
<div>
<h3
class="backPrimaire opacity mx-1 text-primary bordurePost bordureRond"
>
<b-icon-chevron-double-down
class="mr-5 my-1 pt-1 text-secondary"
animation="cylon-vertical"
font-scale="1"
></b-icon-chevron-double-down>
Vos collegues
<b-icon-chevron-double-down
class="ml-5 my-1 pt-1 text-secondary"
animation="cylon-vertical"
font-scale="1"
></b-icon-chevron-double-down>
</h3>
</div>
<div class="hauteur">
<div class="mt-5 d-flex flex-wrap">
<div
v-for="(user, id) in filteredList"
v-bind:key="id"
class="col-md-3 d-flex flex-column align-items-center align-content-center"
>
<div #click="changeUser(user)" class="cursor">
<img
#click="changeRoute"
v-if="user.image_url !== null || ''"
:src="user.image_url"
width="100px"
height="100px"
class=" justify-content-left bordureProfil
rounded-circle"
/>
<img
v-else
src="../assets/image/icon.png"
width="100px"
class=" justify-content-left bordureProfil rounded-circle"
/>
</div>
<div>
<h5 class="mt-2">
{{ user.nom.toUpperCase() }}
</h5>
<h6 class="mb-3">{{ user.prenom.toLowerCase() }}</h6>
</div>
</div>
</div>
</div>
</div>
<div class="py-5 stopPadMarg bg-primary col-md-1">
<img
src="../assets/image/icon.png"
width="60px"
class="rounded-circle"
alt="logo"
/>
</div>
</section>
</template>
<script>
import axios from "axios";
export default {
components: {},
data() {
return {
searchKey: "",
postes: [],
users: [],
user_id: localStorage.getItem("userId"),
userChoice: localStorage.getItem("userChoice"),
};
},
async created() {
this.postes = [];
this.users = [];
await axios
.get("http://localhost:3000/postes")
.then(
(response) => ((this.postes = response.data), console.log(response))
)
.catch((error) => console.log(error));
await axios
.get("http://localhost:3000/users")
.then(
(response) => ((this.users = response.data), console.log(this.users))
)
.catch((error) => console.log(error));
await axios
.get("http://localhost:3000/users")
.then(
(response) => (
(this.userDef = response.data.find((user) => {
return user.id;
})),
console.log(this.userDef)
)
)
.catch((error) => console.log(error));
await axios
.get(`http://localhost:3000/user/${this.user_id}`)
.then(
(response) => (
(this.userConnect = response.data), console.log(this.userConnect.id)
)
)
.catch((error) => console.log(error));
await axios
.get("http://localhost:3000/commentaires")
.then(
(response) => (
(this.comments = response.data), console.log(this.comments)
)
)
.catch((error) => console.log(error));
},
computed: {
filteredList() {
return this.users.filter((user) => {
return user.nom.toLowerCase().includes(this.searchKey.toLowerCase());
});
},
},
methods: {
async changeUser(user) {
await localStorage.removeItem("userChoice");
await localStorage.setItem("userChoice", user.id);
this.$router.push(`/profil/${this.userChoice}`);
},
async changeRoute() {
await this.$router.push(`/profil/${this.userChoice}`);
},
},
};
</script>
<style></style>
and the picture here
if I press a second time on the same profile it gives it to me if I return to the colleagues page but not if I change profile there is an empty page
here picture of the routes path
in fact the route does not change profile and remains on 58 here c the profile of that which is connected and if we change number on the route it launches a page page so this is the problem with the path of the route that the we see in the browser cache
Having looked at your code it's obvious why you'd get an empty page when changing routes. Let me explain:
Your routes say this:
Register a route /profil/${userChoice} (which is a value read from localStorage).
This route definition is only read once, at page intialisation. So, when your page loads only /profil/58 will be defined, /profil/59 wont.
What you are probably looking for is route parameters:
https://router.vuejs.org/guide/essentials/dynamic-matching.html
You'd want the number part of this url to be dynamic and respond to changes.
So, instead of reading the value from localStorage, you would write:
{
path: '/profil/:user_id',
name: 'ProfilUser',
...
}
Now when your Profil components is initialized instead of accessing localStorage you read the provided value as follows:
created() {
var userChoice = this.$route.params.user_id;
}
(note it is also possible to get this param as a prop, consult the vue-router docs on how to do this)
Another thing you need to keep in mind is that you need to respond when this parameter changes. Your component will not be refreshed/remounted.
To respond to parameter changes you can do the following:
watch: {
'$route.params.user_id'() {
this.reloadAllStuff();
}
}
I would recommend to not use localStorage for this use case, let the URL parameter be the main source of truth.
Further reading:
https://qvault.io/2020/07/07/how-to-rerender-a-vue-route-when-path-parameters-change/

List down an array of messages from the converstions

I would like to list down the messages from a chat Id ... I am using Vue js and i could get the data but i am not able to display them using the component . anyone would like to guide ?
This is my message component where the messages will be displayed here
<template>
<div class="row w-20 " >
<div class="card col-4 ">
<ul>
<li v-for="(conversation,index) in conversation" :key="conversation.id">
<div >
{{message}}
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: ['conversation_index_route'],
data() {
return {
conversations: [],
url: 'http://127.0.0.1:8000/comms/conversation/'
}
},
beforeMount() {
this.$eventBus.$on('selectConversation', this.getConversations)
this.getConversations();
},
methods: {
getConversations(id) {
console.log(this.url+id);
axios.get(this.url+ id)
.then(response => {
this.conversations = response.data;
})
}
}
}
</script>
This are the data that can seen in VUE .. I need to display the messages which is in array
conversation_index_route:"http://127.0.0.1:8000/comms/conversation"
conversations:Object
all_staff_attended:false
centre_id:5
children:"3828,4197,7748,11591,12376,12394,12433,12441,12754,12755,12765,13284,14149,14602,14656,14941"
classes:"139"
cover_image:"https://via.placeholder.com/150x150"
created_at:"2020-06-09 19:14:20"
exited_users:null
id:258
last_id:1917
messages:Array[5]
0:"{"_id":1921,"text":"Okayyyy","createdAt":"2020-06-10 01:46:10","user":{"_id":13077,"name":"Mom (Alex,Jacob,Ahmad,Patrick,Ethan Lim)","avatar":null},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":13077,"1":14083,"2":3}}"
1:"{"_id":1920,"text":"Chvfhdgy","createdAt":"2020-06-10 01:46:00","user":{"_id":13077,"name":"Mom (Alex,Jacob,Ahmad,Patrick,Ethan Lim)","avatar":null},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":13077,"1":14083,"2":3}}"
2:"{"_id":1919,"text":"Heyyyy","createdAt":"2020-06-10 01:45:28","user":{"_id":14083,"name":"Siti","avatar":"https:\/\/api.cloudinary.com\/v1_1\/ds13udsoy\/image\/download?timestamp=1592882587&public_id=archaana%2Flibrary%2Fprofile%2Fstaff%2Fcd3ecc89-f67e-4e5e-89e9-badafd903bba_1591032813&type=private&expires_at=1592882647&signature=d0f12d520d18ff1a6b594bcb0ecb742f8ffd88a6&api_key=567141618229528"},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":14083,"1":13077,"2":3}}"
3:"{"_id":1918,"text":"Hello","createdAt":"2020-06-10 01:45:14","user":{"_id":14083,"name":"Siti","avatar":"https:\/\/api.cloudinary.com\/v1_1\/ds13udsoy\/image\/download?timestamp=1592882587&public_id=archaana%2Flibrary%2Fprofile%2Fstaff%2Fcd3ecc89-f67e-4e5e-89e9-badafd903bba_1591032813&type=private&expires_at=1592882647&signature=d0f12d520d18ff1a6b594bcb0ecb742f8ffd88a6&api_key=567141618229528"},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":14083,"1":13077,"2":3}}"
4:"{"_id":1917,"text":"Hahaha","createdAt":"2020-06-10 01:14:34","user":{"_id":13077,"name":"Mom (Alex,Jacob,Ahmad,Patrick,Ethan Lim)","avatar":null},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":13077,"1":181,"2":14083,"3":3}}"
parent_users:"2413,3461,11690,11770,11786,12262,12263,13077,14232,15275,16713"
parents:Array[11]
staff_users:"321,16707,12117,13488,14083"
staffs:Array[5]
status_id:1
title:"Class 0906"
updated_at:"2020-06-09 19:14:20"
url:"http://127.0.0.1:8000/comms/conversation/"
Can Anyone help me how to display the array of message in the component ..
Alright let's assume that this is how your response is structured:
{
all_staff_attended: false,
centre_id: 5,
messages: Array[5]
...etc.
}
Then when you call your getConversations method you could make your data property this.conversations equal to messages array from your response:
getConversations(id) {
console.log(this.url+id);
axios.get(this.url+ id)
.then(response => {
//from your response you would want to get messages array
this.conversations = response.data.messages;
})
}
Once you got your messages array, you can then loop through it with v-for like so:
<ul>
<li v-for="(conversation,index) in conversation" :key="conversation.id">
<div>
<p>Message: {{conversation.text}}</p>
<p>User: {{conversation.user.name}}</p>
<p>Created at: {{conversation.createdAt}}</p>
</div>
</li>
</ul>
Now, you can access each object of the messages array like in the example above.