Getting form data from vuex - javascript

I'm trying to make a edit form thats pre-populated by my vuex model.
My idea was to bind the input to data, and populate data from the computed vuex getters.
Then when the user is done filling out the form, submit data to vuex and the server.
The problem is on load, data is empty so the template errors out.
Error in data(): "TypeError: Cannot read property 'title' of
undefined"
(simplified)
<template>
<input type="text" v-model= "title" >
</template>
<script>
...mapGetters('project', {
projectById: 'byId',
}),
data: function(){
return {
title: this.project.title
}
}
computed: {
project() {
var project = this.projectById(Number.parseInt(this.id))
return (project === undefined) ? {} : project;
}
</script>

Related

Submit a form from a Modal in Vue js

I need to send a form from a modal. Not using a full Vue app, but inserting Vue.js in my HTML page.
I tried a lot of unsuccesful things with my current modal, so I reduced it to the basic modal example I used for the first time https://v2.vuejs.org/v2/examples/modal.html
For the form, I used also the most basic form validation example at https://v2.vuejs.org/v2/cookbook/form-validation.html (I have it working in other places).
And I have created this unsuccessful fiddle:
https://jsfiddle.net/JIBRVI/03qnok9m/53/
Vue.component('modal', {
template: '#modal-template'
})
// start app
// eslint-disable-next-line no-new
new Vue({
el: '#app',
data: {
showModal: false,
errors: [],
name: ''
},
methods: {
checkForm: function (e) {
if (this.name) {
return true
}
this.errors = []
if (!this.name) {
this.errors.push('Name required.')
}
e.preventDefault()
}
}
})
In the basic modal example I added the form with a field, a submit button and a placeholder to show errors. Also the input field «name» and the array «errors» to the data section in the app. I also added the «checkForm» method.
The main error says:
Property or method "checkForm" is not defined on the
instance but referenced during render. Make sure that this property is
reactive, either in the data option, or for class-based components, by
initializing the property
Maybe the main page can communicate with the modal, so data and methods from the main page can’t be used.
I also tried to make a component with the form, but it didn’t work either. I can’t communicate with the modal.
Any help will be aprreciated.
You need to move the name and checkform methods to the modal component. You have currently defined those two in the app component and are trying to access it from the modal which is in the modal component.
Vue.component('modal', {
template: '#modal-template',
data(){
return {
name: '',
errors: [],
}
},
methods: {
checkForm: function (e) {
if (this.name) {
return true
}
this.errors = []
if (!this.name) {
this.errors.push('Name required.')
}
e.preventDefault()
}
}
})

error in calling data to view in laravel and vue js

i am trying to show some table data in view using vue js and laravel :
here is what i have tried :
this is comment controller :
public function index()
{
$comment = Comment::Latest()->paginate(10);
return new CommentResource($comment);
}
here is my vue js comment script
export default {
data: function() {
return {
comments: {}
}
},
created() {
this.loadComments();
}
,
methods: {
loadComments(){
axios.get("../api/comment").then(
({ data })=>(this.comments - data.data)
// response => this.comments = response.data
);
},
}
}
and finally the html part of vue html
<div v-for="comment in comments" >
{{ comment.title }}
</div>
the result is this error i get in browser :
[Vue warn]: Error in render: "TypeError: Cannot read property 'title' of undefined"
and here
[Vue warn]: Property or method "comment" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
and
TypeError: Cannot read property 'title' of undefined
btw i am sure that i have this because this is my api that i recice on
http://localhost:8000/api/comment
{"current_page":1,"data":[{"id":1,"title":"asd","body":"asd","user_id":1,"user_email":"asd","status":1,"created_at":null,"updated_at":null}],"first_page_url":"http:\/\/localhost:8000\/api\/comment?page=1","from":1,"last_page":1,"last_page_url":"http:\/\/localhost:8000\/api\/comment?page=1","next_page_url":null,"path":"http:\/\/localhost:8000\/api\/comment","per_page":10,"prev_page_url":null,"to":1,"total":1}
and when i console log this :
axios.get("../api/comment").then(({ data }) => (console.log(data)))
i get this result :
You're already extracting data from the response. So either you use the response object like this :
axios.get("../api/comment").then((response) => (this.comments = response.data.data)));
Or you extract the data property and use it.
axios.get("../api/comment").then(({ data }) => (this.comments = data.data)));
This is because axios returns a response object that has a data property that contains the server response. As your server response also has a data property that you want to use, you want to use response.data.data

Vue.js undefined error on object value when loaded and rendered

OK. I'm not a total newbie and do have some Vue xp but this is bugging me. What really obvious thing am I missing.
I have an object loaded via an ajax call inside a mounted method:
job: {
"title": "value",
"location": {
"name":"HONG KONG"
}
}
When I call {{ job.title }} all good. When I call {{ job.location.name }} I have an undefined error but the value renders. When I call {{ job.location }} I get the json object so it is defined.
Aaargh! I'm sure it's really simple but can't possibly see why this isn't as straight forward as it should be.
// Additional
This is my entire Vue class
const router = new VueRouter({
mode: 'history',
routes: []
});
const app = new Vue( {
router,
el: '#app',
data: {
job: {}
},
mounted: function () {
var vm = this
jQuery.ajax({
url: 'https://xxx' + this.jobId,
method: 'GET',
success: function (data) {
vm.job = data;
},
error: function (error) {
console.log(error);
}
});
},
computed: {
jobId: function() {
return this.$route.query.gh_jid
}
}
})
When your component renders it tries to get value from job.location.name but location is undefined before ajax request is completed. So I guess error is kind of Cannot read property 'name' of undefined.
To fix this you can define computed property locationName and return, for example, empty string when there is no loaded job object yet:
computed:{
//...
locationName() {
return this.job.location ? this.job.location.name : '';
}
}
Or you can define computed for location and return empty object if there is no location, or you can just add empty location object to your initial data(if you are sure that your API response always has location) like job: { location: {}} all ways will fix your issue.
Also there is a way to fix it with v-if directive in your template:
<div v-if="job.location">
{{ job.location.name }}
<!-- other location related stuff -->
</div>
An ES6 solution for you:
computed: {
getJobName(){
return this.job?.location.name
}
}
Optional Chaining

Vuejs: How to properly pass props to component data

i'm playing with Vue 2.0, but there is something unclear..
how can i pass the props to the internal data of a component?
Looking at the documentation it seems that i have done right.
HTML
<lista-servizi :servizi="modello"></lista-servizi>
the "modello" is a data already defined.
THE VUE COMPONENT
Vue.component('lista-servizi', {
template:
'<span class="blu">{{listaServizi.lineaGialla.descrizione}}</span>',
props: ['servizi'],
data: function(){
return{
listaServizi : this.servizi
}
basically i try to give to data listaServizi the same value as props servizi,
but in the console i have the following message:
[Vue warn]: Error in render function: "TypeError: Cannot read property 'descrizione' of undefined"
found in
---> <ListaServizi>
<Root>
You should used computed instead.
Vue.component('lista-servizi', {
//...
computed: {
listaServizi() {
return this.servizi
}
}
}
Most likely you have a problem with modello.
By defining the modello, your code works fine. Below is an example based on your code that works:
<div id="app-1">
<lista-servizi :servizi="modello"></lista-servizi>
</div>
Vue.component('lista-servizi', {
template: '<span class="blu">{{listaServizi.lineaGialla.descrizione}}</span>',
props: ['servizi'],
data: function(){
return{
listaServizi : this.servizi
}
}
})
var app1 = new Vue({
el: '#app-1',
data: {
modello: {
lineaGialla : {
descrizione : " This is a description"
}
}
}
})
Here is a link to a working bin
https://jsbin.com/qoloqoz/1/edit?html,js,output

Content is undefined when trying to work with a record in Ember

I am trying to update a record in the Ember store. When I try to do this, it returns the following error:
Uncaught Error: Assertion Failed: Cannot delegate set('name', test) to the 'content' property of object proxy : its 'content' is undefined.
The controller looks like this:
import Ember from 'ember';
export default Ember.Controller.extend({
model: null,
event: {
name: "test",
id: "adfg8943224xcvsdf"
},
actions: {
editEvent (event) {
var Event = this.store.find('event', event.id);
Event.set('name', event.name);
Event.save()
}
}
});
The route looks like this:
import Ember from 'ember';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model () {
return {
event: this.store.find('event')
}
},
setupController (controller, model) {
controller.set('model', model);
}
});
The template triggers the action, sending along a object called event, which has properties like name and id. The values of the event object come from the controller and have been set before triggering the editEvent action:
<form {{action 'editEvent' event on="submit"}}>
I believe what is happening is that your model hook is returning a POJO that contains a promise that will resolve. If you want to pass that to your action then you need to do
<form {{action 'editEvent' model.event on="submit"}}>
That being said you should really just return a promise from your model hook so that Ember will wait for your data to load before rendering the template. With the way you have it setup now, if your data takes a long time to load, someone could submit the form before the model is loaded and you'll get an error.
I think you want your route to look like this (no need to override setupController):
import Ember from 'ember';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model () {
return this.store.find('event');
}
});
Then in your template:
<form {{action 'editEvent' model on="submit"}}>
If you need to load multiple models then you should use Ember.RSVP.hash.
See this answer: EmberJS: How to load multiple models on the same route?
Also, I'm not quite sure what your action is trying to do but you don't need to find the record again. The code you posted for your action doesn't actually do anything. It gets the event and then sets the event's name to its own name.
actions: {
editEvent (event) {
// you already have the event, you passed it in as a parameter
// you don't need to query the store again for it.
var Event = this.store.find('event', event.id);
// This doesn't do anything as it just sets the event.name to itself
Event.set('name', event.name);
Event.save()
}
}
I think you mean to do this:
actions: {
editEvent (event) {
event.set('name', 'updated name');
event.save();
}
}

Categories

Resources