Vue.js - Data Property isn't accessible - javascript

I have a Vue.js 3 app. In this app, I'm trying to search through an array of object. I've created a fiddle here. In this fiddle, the code causing the issue looks like this:
async runSearch() {
let searchResults = this.data;
if (this.searchQuery) {
let info = JSON.stringify(searchIndex);
alert(info);
console.log(searchIndex);
searchResults = await courseIndex.search(courses);
}
this.results = searchResults;
}
For some reason, it's like searchIndex doesn't exist. However, I do have it in the model as shown here:
data() {
return {
searchIndex: null,
searchQuery: null,
data: data,
results: null,
}
}
What am I doing wrong? Why can't I execute a search?

use this.searchIndex to access reactive variables defined in data in Vue.

Related

Chart data displays on the console.log but not on the page (Using Axios/Vue)

I'm trying to use axios to get data for my Chart but I couldn't know how to make it appear on the canvas, i can see the values on the console.log as below
Console.log,
I'm not too sure what is happening, here's my code :
mounted(){
const ctx = document.getElementById('myChart');
let myData = [];
const myChart = new Chart(ctx,
{
type: 'line',
data: {
labels: [....],
datasets: [{
data: this.myData,
backgroundColor: [ ['blue']],
}] },
options: {.....}
});
myChart;
here's the methode:
created: function(){
this.getData();} ,
methods: {
getData : function(){
axios.get('http://localhost:3000/Chart/chartjs')
.then(resp => {this.myData = resp.data
console.log(resp.data); }) }
your problem is related to the reactivity fundamentals of VueJS. As you are declaring a local variable in the mounted method and trying to access the property myData on this without declaring it in the component, VueJS will not update the UI.
The way you presented your code, I'll assume that you are using VueJS3 with the Options API.
To have a reactive component, you need to declare a reactive state. This is usually done before the mounted() method.
export default {
data() {
return {
myData: []
}
},
mounted() {
...
Afterward, in your mounted and getData methods, instead of declaring myData, you need to use this.myData. VueJS will take care of the reactivity.
Also, I noticed that you are trying to access the DOM directly. This is not a usual or recommended in VueJS. You should use a bind to make sure your properties are updated correctly.

Vue: Access values over api (nested)

Hi Stackoverflow Community,
In my template I try to show data which I receiver over an api call. When I log the api get response this is what I receive:
Now I try to show the data in location with the following code:
{{ userdetails.location.location_name }}
My script looks like this:
data() {
return {
userdetails: [],
};
},
methods: {
getUserData() {
DataService.getUserById()
.then((response) => {
this.userdetails = response.data;
console.log(response);
})
...
created() {
this.getUserData();
},
The strange thing is, I can see the location_name in my application. But I also receive an error:
I think I made somewhere a mistake, but I can't find it. Do you have any ideas what I am doing wrong?
Thank you in advance for all your tipps!
At the start, when the template tries to access userdetails.location.location_name, it is an empty list, so you will see the error. Only once the DataService updated userdetails will the nested properties exist.
The easiest way to prevent this is to start out with userdetails as something which is 'falsey' and then use v-if to determine whether to render:
<div v-if="userdetails">{{userdetails.location.location_name}}</div>
data() {
return {
userdetails: undefined,
};
},
Note however that if your DataService could ever return a dict which doesn't have the location property, you will need to do more testing in v-if to determine if it can be rendered.

Add Vue.js computed property to data gathered from a server

Coming from Knockout.js, where you can simply create an observable everywhere by defining it, is there something similar in Vue.js?
let vm = {
someOtherVar: ko.observable(7),
entries: ko.observableArray()
};
function addServerDataToEntries(data) {
data.myComputed = ko.pureComputed(() => vm.someOtherVar() + data.bla);
vm.entries.push(data);
}
addServerDataToEntries({ bla: 1 });
In my Vue.js project, I'm getting a list of objects from the server. For each of those objects, I want to add a computed property that I can use in a v-if binding. How can I achieve that?
I'm not familiar with the way Knockout does it but it sounds like a Vue computed. Create a data object to hold your fetched data:
data() {
return {
items: null
}
}
Imagine fetching it in the created hook (or Vuex, wherever):
async created() {
const response = await axios.get(...);
this.items = response.data;
}
Create your computed:
computed: {
itemsFormatted() {
if (!this.items) return null;
return this.items.map(item => {
// Do whatever you want with the items
});
}
}
Here is a demo using this pattern where I'm loading some data and printing out a filtered result from it. Let me know if I misunderstood what you're looking for. (You can see the original fetched data in the console.)

load json of data into vuex store and access in component

I am trying to load a JSON file of content into my vuejs app and accessing it in my components. I am able to load the json into the vuex store by creating an API:
import Vue from 'vue';
const Http = new Vue();
export function getData() {
return Http.$http.get('./app/assets/content/en_uk.json')
.then(response => Promise.resolve(response.data))
.catch(error => Promise.reject(error));
}
and an action
export const getSiteContent = ({commit}) => {
api.getData().then(data => {
commit('siteContent', data);
});
};
I run getSiteContent on created function of the main vue instance
export default new Vue({
el: '#root',
store,
router,
created() {
getSiteContent(store);
},
render: h => h('router-view')
});
using the vue debug tool in chrome i can see the store
export const state = {
isSearching: false,
searchQuery: '',
siteData: {},
filteredComponents: [],
hasResults: false,
activeComponent: null
};
gets updated with the siteData.
This is part of the json:
{
"global": {
"project_name": {
"text": "Project title"
},
"search": {
"form_placeholder": {
"text": "Search..."
},
"no_results": {
"text": "Sorry no results for '{0}' was found"
},
"search_text": {
"text": "You are searching for '{0}' and there are {1} found"
}
}
}
}
When I try and access
computed: {
...mapGetters(['siteData']),
mumbo () {
return this.siteData.global.project_name;
}
}
in my component like {{mumbo}} I get cannot read property of project_name of undefined.
I feel like this is a time issue as it doesn't fall over when I set it to return siteData.global
I'm not sure if I am doing something wrong or I am missing a connection to get this to work.
As you guessed the problem here is that Vue is trying to access the contents of siteData for that computed property while the data is still loading. Although siteData is a valid object initially, trying to access siteData.global.project_name fails because siteData has no field global when the data hasn't loaded yet. To prevent the error, you will have to include a check like this:
mumbo () {
return this.siteData.global ? this.siteData.global.project_name : 'Loading...';
}
To illustrate the solution, here's a simple JSFiddle based on your code.

store.push not reflecting on template with ember-cli-pagination

I'm new to Ember.js and I'm trying to add an object to the store after an ajax request.
The problem is that it does not reflect on template if I use ember-cli-pagination.
If I use this.store.findAll in model, it works, but when I use this.findPaged it does not.
I'm using ember-inspector and the object appears in the store, just don't in the browser.
My code:
import Ember from 'ember';
import RouteMixin from 'ember-cli-pagination/remote/route-mixin';
export default Ember.Route.extend(RouteMixin, {
actions: {
create: function(email) {
let adapter = Ember.getOwner(this).lookup('adapter:application');
let url = adapter.buildURL('billing/delivery-files');
let store = this.get('store');
let modelName = 'billing/delivery-file';
return adapter.ajax(url, 'POST', {
email: email
}).then(function(data) {
var normalized = store.normalize(modelName, data.object);
store.push(normalized);
});
}
},
model(params) {
return this.findPaged('billing/delivery-file',params); //does not work
// return this.store.findAll('billing/delivery-file'); //works
}
});
Tried the solutions from this issue, and did not work at all.
What am I missing?
Figured out!
After pushing to the store, I needed to push to the paginated array a reference to the store object. Don't know exactly why but it worked like a charm!
model.content.pushObject(pushedRecord._internalModel);
In my case I wanted it at the first position of the array, so I did:
model.content.insertAt(0, pushedRecord._internalModel);

Categories

Resources