Vue.js consume json - javascript

My problem is with this json.
http://dev-rexolution.pantheonsite.io/api/noticias
I need to consume with vuejs 2 only the first element of the array to be able to display it, working with the console I worked but with no vuejs.
This console log work: console.log(response.data[0].title[0].value);
<template>
<div class="Box Box--destacado1">
<div class="Media Media--rev">
<div class="Media-image">
</div>
<div class="Media-body">
<span class="Box-info">{{ noticias[0].field_fecha[0].value}}</span>
<h3 class="Box-title">
{{ /*noticias[0].title[0].value */}}
</h3>
<p class="Box-text">{{/*noticias[0].field_resumen[0].value*/}}</p>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data: () => ({
noticias: [],
errors: []
}),
// Fetches posts when the component is created.
created() {
axios.get(`http://dev-rexolution.pantheonsite.io/api/noticias`)
.then(response => {
// JSON responses are automatically parsed.
this.noticias = response.data
})
.catch(e => {
this.errors.push(e)
})
}
}
</script>

You're probably running into an issue where your template is attempting to show data that doesn't exist until the AJAX request has completed.
I would set a flag to indicate when the data is available and toggle the display using v-if. For example
Template
<div class="Media-body" v-if="loaded">
Script
data () {
loaded: false,
noticias: [],
errors: []
}
and in your created hook
.then(response => {
this.loaded = true
this.noticias = response.data
})
Alternatively, set up your initial noticias array with some dummy data
noticias: [{
title: [{ value: null }]
field_fecha: [{ value: null }]
field_resumen: [{ value: null }]
}]

Related

How to write, update local JSON file in vue js

I have tried to use file system (fs module) but, not getting that how to use that FS module.
could anyone explain with proper example.
I was doing an example in vue js.
Create component
Added json file
Pass records as props on component
listen that props on another component
and render student list and perform remove record
Now next i want to Pass updated list using emit & update the JSON as well
This code is working properly just i want to update local json file after delete record.
StudentRegistration.vue
<template>
<div class="container">
<div class="row">
<template v-if="students.length">
<!-- {{student.length}} -->
<studentCard class="student__parent" v-for="student in students" :key="student.id" :student="student" #studentRemoveId="studentRemoveId"/>
</template>
<template v-else>
<div class="not__available">
Data not available
</div>
</template>
</div>
</div>
</template>
<script>
import studentCard from './studentCard.vue'
import studentData from '../data/StudentData.json'
export default {
name: 'StudentRegi',
components:{
studentCard
},
data() {
return {
students: studentData,
}
},
methods: {
studentRemoveId(studid){
this.students = this.students.filter( item => {
console.log('hey there ::=> ', item);
return item.id !== studid.id
});
}
},
}
</script>
studentCard.vue
<template>
<div>
<span class="student__remove" #click="removeStudent(student)">X</span>
<div class="student__inner">
<div class="student__image">
<img :src="student.avatar" alt="">
</div>
<div class="student__name student-detail">
<div>Name</div>
<div>{{student.fname}} {{student.lname}}</div>
</div>
<div class="student__age student-detail">
<div>Age</div>
<div>{{student.age}}</div>
</div>
<div class="studet_email student-detail">
<div>Email</div>
<div>{{student.email}}</div>
</div>
<div class="student__phone student-detail">
<div>Phone</div>
<div>{{student.phone}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name:'StudentCard',
props:['student'],
methods: {
removeStudent(studid){
this.$emit('studentRemoveId', studid);
}
},
}
</script>
data.json
[
{
"id": 1,
"fname": "Atul",
"lname": "Bhavsar",
"age": "10 Years",
"email": "atul#gmail.com",
"phone": "9685958698",
"avatar": "https://i.postimg.cc/d3ykpLs8/stud1.jpg"
},
{
"id": 7,
"fname": "Foram",
"lname": "Dobariya",
"age": "20 Years",
"email": "sanju#gmail.com",
"phone": "9856985698",
"avatar": "https://i.postimg.cc/QtWp5XBn/stud7.jpg"
},
]
Hey After some searches I found a solution so sharing here it may help who stuck related to this issue,
As i show above code i just wanted to add code where i can write my json file. so i have made some changes in code, that is as below.
Add command in CMD :
json-server --watch './src/data/studentData.json' --port 3001
then it will provide local link from where you can open you json data
Resources
http://localhost:3001/studente
see below image :
StudentRegistration.vue
this code should be in script tag in StudentRegistration.vue component
In this file added below code added code in method and created create method
export default {
name: 'StudentRegi',
components:{
studentCard
},
data() {
return {
studentsGetData: []
// studentsGetData: studentData,
}
},
methods: {
studentRemoveId(studid){
fetch(`http://localhost:3001/studente/${studid.id}`,
{
method: 'DELETE',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(resp => {
console.log('res ::=> ', resp.data);
resp.data;
}).catch(error => {
console.log(error);
});
this.studentsGetData = this.studentsGetData.filter( item => {
return item.id !== studid.id
});
}
},
async created(){
await fetch('http://localhost:3001/studente')
.then(res => res.json())
.then(data => {
console.log('data ::=> ', data);
this.studentsGetData = data
} )
.catch(err => console.log(err.message))
}
}
Now Run your project

How to load Bootstrap-vue "b-table" row data dynamically using "_showDetails"?

I have bootstrap-vue "b-table" used in my Vue page. Each row has an "view-details" button, that shows additional information about the selected row. I was looking for examples that can send request to backend when user clicks for view-details, that expands the row and shows details retrieved from backend. The "_showDetails" option from bootstrap-vue table seems limited as the examples all use the data that was already loaded along with the main tableland using this way would overload the page as my data for each row is too big.
Are there any examples or even other libs that support such functionality?
You can do this with bootstrap-vue without any problems.
Create a method that gets called when you click your "view details" button, this method will call your backend and insert the data onto your item. Once the data has been retrieved you set _showDetails to true on the item, which will open the details.
You could also open it immediately and show a loading message while the data is retrieved, that's up to you.
new Vue({
el: '#app',
created() {
// Get initial data
fetch('https://reqres.in/api/users')
.then(response => response.json())
.then(json =>
/* Map and use only some of the data for the example */
this.items = json.data
.map(user => {
return {
id: user.id,
first_name: user.first_name,
last_name: user.last_name
}
}))
},
data() {
return {
items: [],
fields: ['id', 'first_name', 'last_name', {
key: 'actions',
label: ''
}]
}
},
methods: {
toggleDetails(item) {
if (item._showDetails) { // if details are open, close them
item._showDetails = false
} else if (item.details) { // if details already exists, show the details
this.$set(item, '_showDetails', true)
} else {
fetch(`https://reqres.in/api/users/${item.id}`)
.then(response => response.json())
.then(json => {
const user = json.data;
item.details = {
email: user.email,
avatar: user.avatar
}
this.$set(item, '_showDetails', true)
})
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.5.0/dist/bootstrap-vue.min.js"></script>
<link href="https://unpkg.com/bootstrap-vue#2.5.0/dist/bootstrap-vue.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap#4.3.1/dist/css/bootstrap.min.css" rel="stylesheet" />
<div id="app">
<b-container>
<b-table :items="items" :fields="fields">
<template v-slot:cell(actions)="{ item }">
<b-btn #click="toggleDetails(item)">
Show details
</b-btn>
</template>
<template v-slot:row-details="{ item : { details: { email, avatar }}}">
<b-card>
<b-img :src="avatar" fluid></b-img>
{{ email }}
</b-card>
</template>
</b-table>
</b-container>
</div>

Vuejs not updating list but updating obect

I am learning Vuejs and I am stuck. Why can I see the messages get added to the object (in Chrome Vue debugger) yet it is not added to the div that contains the list?
My Vue Component:
<template>
<div id="round-status-message" class="round-status-message">
<div class="row">
<div class="col-xs-12" v-for="sysmessage in sysmessages" v-html="sysmessage.message"></div>
</div>
</div>
</template>
<script>
export default {
props: ['sysmessages'],
methods: {
scrollToTop () {
this.$el.scrollTop = 0
}
}
};
</script>
My Vue instance:
$(document).ready(function()
{
Vue.component('chat-system', require('../components/chat-system.vue'));
var chatSystem = new Vue({
el: '#system-chat',
data: function () {
return {
sysmessages: []
};
},
created() {
this.fetchMessages();
Echo.private(sys_channel)
.listen('SystemMessageSent', (e) => {
this.sysmessages.unshift({
sysmessage: e.message.message,
});
this.processMessage(e);
});
},
methods: {
fetchMessages() {
axios.get(sys_get_route)
.then(response => {
this.sysmessages = response.data;
});
},
processMessage(message) {
this.$nextTick(() => {
this.$refs.sysmessages.scrollToTop();
});
// updateGame();
}
}
});
});
My template call in HTML:
<div id="system-chat">
<chat-system ref="sysmessages" v-on:systemmessagesent="processMessage" :sysmessages="sysmessages" :player="{{ Auth::user() }}"></chat-system>
</div>
There are no compile or run time errors and I can see records added to the props in the vue chrome tool. I can also see empty HTML elements added to the div.
What have I missed?
UPDATE: My record structures:
response.data is an array of objects, each like this:
{"data":[
{"id":100,
"progress_id":5,
"message":"start message",
"action":"welcome"
},
{"id"....
e.message.message contains the text message entry, so just a string.
I am trying to access the message variable in each object during the fetchMessages method.
You're adding objects with sysmessage as the property.
this.sysmessages.unshift({
sysmessage: e.message.message,
});
But you are trying to view
v-for="sysmessage in sysmessages" v-html="sysmessage.message"
Based on your update, the code should be:
this.sysmessages.unshift({
message: e.message.message,
});
And you can leave the template as
v-html="sysmessage.message"

Vue JS unable to display to DOM the returned data of method

Template html
<div class="item" v-for="n, index in teamRoster">
<span> {{ getFantasyScore(n.personId) }} </span>
</div>
Method
getFantasyScore(playerId) {
if(playerId) {
axios.get(config.NBLAPI + config.API.PLAYERFANTASYSCORE + playerId)
.then( (response) => {
if( response.status == 200 ) {
console.log(response.data.total)
return response.data.total;
}
});
}
}
I'm trying to display the returned data to DOM but it doesnt display anything. But when I try to console log the data is displays. How can I be able to display it. What am I missing?
Problem is, your getFantasyScore method doesn't return anything and even then, the data is asynchronous and not reactive.
I would create a component that loads the data on creation. Something like
Vue.component('fantasy-score', {
template: '<span>{{score}}</span>',
props: ['playerId'],
data () {
return { score: null }
},
created () {
axios.get(config.NBLAPI + config.API.PLAYERFANTASYSCORE + this.playerId)
.then(response => {
this.score = response.data.total
})
}
})
and then in your template
<div class="item" v-for="n, index in teamRoster">
<fantasy-score :player-id="n.personId"></fantasy-score>
</div>
You shouldn't use methods for AJAX results because they are async. You could retrieve the full teamRoster object and then add this to your div:
<div class="item" v-for="fantasyScore in teamRoster" v-if="teamRoster">
<span> {{ fantasyScore }} </span>
</div>

How to Re-bind / Refresh Dom after ajax call in vuejs2 (like $scope.$apply in angularjs)?

I am using vue.js 2 with webpack template. i am new to vue.js.
i want to bind DOM after data is received in ajax call.
here in my code contains v-for in which the response html is need to bind with v-html="tHtml[index]" every time after data is received from api call.
What can be used to re-bind or refresh view/DOM as we use $scope.$apply() in angularjs.
home.vue
<template>
<div class="row" id="home">
<h3 v-if="msg"><span class="label label-warning">{{msg}}</span></h3>
</div>
<div v-for="obj in tdata">
<div v-html="tHtml[$index]"></div>
</div>
</div>
</template>
<script>
import appService from '../service'
import bus from '../service/bus'
export default {
created() {
appService.checkAuth();
console.log("service appService val: "+appService.user.authenticated);
//called after vue has been created
bus.$on('eventBusWithTopic', (data) => { //fetch event bus on ready to get data
//alert("event fetched! "+data.user_id);
console.log("event fetched! "+data.user_id);
this.searchedTopic = data.topic;
this.user_id = data.user_id;
bus.$off('eventBusWithTopic'); //un-bind event after use
//check details
})
},
data() {
return {
searchedTopic: '',
user_id: '',
tdata: {},
tHtml: []
}
},
methods: {
getdata(){
console.log("dfd "+this.user_id);
appService.getdata(this, this.user_id, this.searchedTopic).success((res) => {
//console.log(" res: "+JSON.stringify(res));
this.tdata = res.data;
if(this.tdata.length > 0){
//**GET HTML** // <<--==--==--==
for(var i=0;i<this.tdata.length;i++){
this.getTemplate(this.tdata[i].id_str);
}
}
if(res.success == 0)
this.msg = res.message;
}).error((e) => console.log("error while getting data: "+JSON.stringify(e)))
},
getTemplate(id){
this.$http.get("https://uqkcgyy8wb.execute-api..*****../user/"+id+"/getHtml", (resp) => {
//return resp.data.html;
this.tHtml[this.tHtml.length] = resp.data.html;
console.log(this.tHtml);
}).error((e) => console.log("error while getting html: "+JSON.stringify(e)))
}
}
}
</script>

Categories