Parsing input properties in a vue component - javascript

I feel like I am running out of ideas on how to solve this issue.
So I have a component that should read a file and display some data from that file. I want to pass only the filename to component so that it can handle reading and parsing the file. To do this I added a property to the component.
The issue I seem to have is that I can't really access that property from the data function, and if I add a watcher on the property I can parse the file as expected, but I can't seem to get that data into the DOM.
This is what I have right now:
<template>
<main :key="fileName">
fileName: {{fileName}}
<div class="post">{{data}}</div>
<div class="info">
<div v-for="item in info" v-bind:key="item.name">{{item.name}}</div>
</div>
</main>
</template>
<script>
const { parse } = require("#/service/parser");
const fs = require("fs");
let postInfo = { data: "abc", info: [] };
export default {
props: ["fileName"],
watch: {
fileName: {
immediate: true,
handler: (newVal, oldVal) => {
if (newVal) {
postInfo = parse(
fs
.readFileSync(__dirname + "/../../assets/" + newVal, "utf8")
.split("\n")
);
}
}
}
},
data: () => {
return postInfo;
}
};
</script>
I am obviously completely new to Vue, and I'm probably missing something stupid here.
So what am I doing wrong and how do I get the parsed data into my DOM?

Don't use an arrow function for your data function. Arrow functions bind this to whatever context the function is declared in. You need to let Vue properly bind this to the instance it is creating. So use
data() {
return postInfo;
}
or if for some reason you need to be old school:
data: function () {
return postInfo;
}

Related

I cannot read vuex-persist in v-if

I am trying to use vuex-persist on nuxt.js but when try to read the data in a v-if doesn't work.
I created a new file inside plugins called vuex-persis.js with the following code:
import VuexPersistence from 'vuex-persist'
export default ({ store }) => {
new VuexPersistence({
storage: window.localStorage,
}).plugin(store);
}
and into nuxt.config.js I added the following code:
plugins: [{ src: '~/plugins/vuex-persist', mode: 'client' }],
The code that I use in order to store and get data is the following:
this.$store.commit('login', { idToken });
store.state.isLogin
and I have added the following file inside the project ./store/index.js
export const state = () => ({
isLogin: false,
idToken: '',
});
export const mutations = {
login(state, newState) {
state.isLogin = true;
state.idToken = newState.idToken;
},
logout(state) {
state.isLogin = false;
state.idToken = '';
},
};
I have the following navbar when I try to get the data from store:
navbar-button(to='/board', v-if='$store.state.isLogin')
p {{ $t("navbar_board") }}
navbar-button(v-if='$store.state.isLogin', #click.native='logout')
p {{ $t("navbar_logout") }}
but always enter in the same place, log in.
I tried to use a computed like this but doesn't work on the v-if
computed: {
isLogin: function () {
console.log(this.$store.state.isLogin);
return this.$store.state.isLogin;
},
},
the console.log prints the value stored in the browser but the console.log in node prints always the default state.
Anyway, the console.log always prints the correct value stored in the localstorage.
Any idea about how can I use that data in the v-if?
Thanks
Finally solved directly using $store.state.isLogin in the v-if

Vue prefetch data from separate backend

I have some queries from an API-Server that returns a json object that will be static over a user session, but not static forever.
It's a one-pager with Vue router.
How can I achieve that I:
can access this.myGlobals (or similar eg window.myGlobals) in all components, where my prefetched json-data from API-Server is stored.
My approach that is already working is to embed help.js via a mixin.
Oddly enough, I get hundreds of calls to this query. At first I thought that it only happened in the frontend and is chached, but the requests are actually sent hundreds of times to the server. I think it is a mistake of my thinking, or a systematic mistake.
i think the problem is, that the helper.js is not static living on the vue instance
main.js:
import helpers from './helpers'
Vue.mixin(helpers)
helpers.js:
export default {
data: function () {
return {
globals: {},
}
}, methods: {
//some global helper funktions
},
}, mounted() {
let url1 = window.datahost + "/myDataToStore"
this.$http.get(url1).then(response => {
console.log("call")
this.globals.myData = response.data
});
}
}
log in console:
call
SomeOtherStuff
(31) call
SomeOtherStuff
(2) call
....
log on server:
call
call
call (pew pew)
My next idea would be to learn vuex, but since its a easy problem, im not sure if i really need that bomb ?
You can use plugin to achieve this.
// my-plugin.js
export default {
install (Vue, options) {
// start fetching data right after install
let url1 = window.datahost + "/myDataToStore"
let myData
Vue.$http.get(url1).then(response => {
console.log("call")
myData = response.data
})
// inject via global mixin
Vue.mixin({
computed: {
myData () {
return myData
}
}
})
// or inject via instance property
Vue.prototype.$myData = myData
// or if you want to wait until myData is available
Vue.prototype.$myData = Vue.$http.get(url1)
.then(response => {
console.log("call")
myData = response.data
})
}
}
and use it:
Vue.use(VueResource)
Vue.use(myPlugin)

How can I get data from json file using vue js 2?

I am trying to get data from json file, it has just json data.
[{"id":81,"body":"There are some reason to fix the issues","created_at":"2017-11-16 11:56:47","updated_at":"2017-11-16 11:56:47"}]
I added vue-resource and properly use it as per vue syntax.
import vueResource from 'vue-resource'
Vue.use(vueResource)
In my userlist component i am trying following script
export default {
data:function(){
return {
list:[],
car:{
id:'',
body:''
}
};
},
created: function(){
this.fetchCarList();
},
methods:{
fetchCarList: function(){
this.$http.get('http://localhost:8080/api.js').then(function(response){
this.list = response.data
});
}
}
}
And this is component HTML loop
<ul id="example-1">
<li v-for="item in list">
{{ item.body }}
</li>
</ul>
I have checked http://localhost:8080/api.js which is properly returning the data. Also when I am adding the json data in fetchCarList method then loop works fine but with get() call it does not working.
How can I solve the issue?
You have a scoping issue: this within the callback does not refer to your Vue instance. That is because you are not using ES6 arrow function, i.e.:
this.$http.get('http://localhost:8080/api.js').then(response => {
this.list = response.data
});
...which means the outer this is not passed in. You will have to proxy that yourself, i.e. var self = this on the outside, and then use self.list = response.data:
var self = this;
this.$http.get('http://localhost:8080/api.js').then(response => {
self.list = response.data
});

Struggle with fetch() in Vue.Js + GitHub API (octokat.js)

(Beginner here)
I'm trying to create an app in Vue.js that would let me interact with GitHub API. I tried to use vue-github-api at first, but because of troubles working with pagination I switched to octokat.js.
I tried to use the same template that was suggested in vue-github-api docs and just switch to the octokat.
For brevity I'll include this small sample:
<template>
<div class="row">
<div class="col-sm-3">
<div class="panel panel-default">
{{ user.name }}
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
userData: {},
issuesList: {}
}
},
mounted: function () {
var Octokat = require('octokat')
var octo = new Octokat({
token: 'xxxxx'
})
octo.user.fetch(function (e, val) {
this.userData = Object.assign({}, val)
// or this.userData = val (not sure, which is correct)
})
},
computed: {
user: function () {
if (this.userData) {
return this.userData
}
return 'Uh-oh...'
}
}
}
</script>
<style></style>
What I'm getting is:
Uncaught TypeError: Cannot set property 'userData' of undefined
If I would do this:
this.userData = octo.user.fetch()
Then if i console.log it I get this:
[]
I just can't seem to be able to get the desired output out of the "fetch" command.
Has anybody dealt with something similar, or did you spot a glaring error?
Let's look at the code fetching from the GitHub API:
octo.user.fetch(function (e, val) {
this.userData = Object.assign({}, val)
// or this.userData = val (not sure, which is correct)
});
Inside your callback function you are attempting to assign to this.userData however it is not working.
What you have to look at here is what is this referring to?
You are assigning this.userData inside the callback to octo.user.fetch. As a result this is not bound to your Vue instance – it would be bound to the function calling it or in your case undefined because the transpiler most likely added a 'use-strict' pragma.
What can I do about this?
In ES6 we have arrow functions. Arrow functions do not have this bound to it, therefore this is still referring to your Vue instance.
octo.user.fetch((e, val) => {
this.userData = Object.assign({}, val)
});
Further reading
You Don't Know JS: this & Object Prototypes, Chapter 1: this Or That?
You Don't Know JS: this & Object Prototypes, Chapter 2: this All Makes Sense Now!
this documentation on MDN

Vue JS v-for not iterating over array

Hi guys I am using Vue JS to try and loop through my data. Here is my whole JS file:
var contentful = require('contentful');
var client = contentful.createClient({
space: 'HIDDEN',
accessToken: 'HIDDEN'
});
Vue.component('careers', {
template: '<div><div v-for="career in careerData">{{ fields.jobDescription }}</div></div>',
data: function() {
return {
careerData: []
}
},
created: function() {
this.fetchData();
},
methods: {
fetchData: function() {
client.getEntries()
.then(function (entries) {
// log the title for all the entries that have it
entries.items.forEach(function (entry) {
if(entry.fields.jobTitle) {
this.careerData = entries.items;
}
})
});
}
}
});
var app = new Vue({
el: '#app'
});
I am using methods to access some data from Contentful, once it has grabbed the necessary data it is sent to my data object.
If I console.log(careerData); within my console the following data is returned:
So I'd expect if I used v-for within my template and tried iterating over careerData it would render correctly however on my front-end I am left with an empty div like so:
<div id="app"><div></div></div>
I am currently pulling my component into my HTML like so:
<div id="app">
<careers></careers>
</div>
No errors are displayed within my console, can you think of any reason this might be happening?
Thanks, Nick
Several problems I think. As #dfsq said, you should use a arrow function if you want to keep context (this).
fetchData: function() {
client.getEntries()
.then(entries => {
this.careerData = entries.items
});
}
Then you may replace {{fields.jobDescription}} by {{career.fields.jobDescription}}, as #unholysheep wrote.
It may work. If it does not, you could add a this.$forceUpdate(); right after this.fetchData();
Use arrow function in forEach callback so you don't loose context:
fetchData: function() {
client.getEntries()
.then(entries => {
this.careerData = entries.items
});
}

Categories