the model is Entity. No errors are thrown. The form gets submitted and a new Entity is saved. However, the description and title are both recorded as 'nil'. to here is src/components/NewEntity.vue:
<template>
<div class="entities">
<h1>Add Entity</h1>
<div class="form">
<div>
<input type="text" name="title" placeholder="TITLE" v-model="title">
</div>
<div>
<textarea rows="15" cols="15" placeholder="DESCRIPTION" v-model="description"></textarea>
</div>
<div>
<button class="app_entity_btn" #click="addEntity">Add</button>
</div>
</div>
</div>
</template>
<script>
import EntitiesService from '#/services/EntitiesService'
export default {
name: 'NewEntity',
data () {
return {
title: '',
description: ''
}
},
methods: {
async addEntity () {
await EntitiesService.addEntity({
title: this.title,
description: this.description
})
this.$router.push({ name: 'Entities' })
}
}
}
</script>
here is where the script imports from (for some reason SO would not initially allow me to include Services/Api.js):
services/EntitiesServices:
import Api from '#/services/Api'
export default {
fetchEntities () {
return Api().get('/entities')
},
addEntity (params) {
return Api().post('entities', {
title: params.title,
description: this.description
})
}
services/Api.js:
import axios from 'axios'
export default() => {
return axios.create({
baseURL: 'http://localhost:3000',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*'
}
})
}
OG Solution by cperez
Depending on your server, you need to 'stringify' your parameters object within your post function in two possible ways. If your server accepts JSON, then:
return Api().post('entities',
JSON.stringify({
title: params.title,
description: this.description
})
)
If you server doesn't accept JSON, you have to convert the object into encoded URL parameters with the querystring module:
var qs = require('querystring');
return Api().post('entities',
qs.stringify({
title: params.title,
description: this.description
})
)
Related
In code below, I'm checking Id overlap.
I want to hand over the value set to the v-model as a payload
I'm using mapState, so I handed over this.info.userid, but it doesn't work.
It keeps saying that I'm referring to the undefined value.
What value should I refer to?
this is my registration.vue
<div class="user-details">
<div class="input-box">
<span class="details">아이디</span>
<div class="validate-box">
<Field
:rules="validateId"
type="text"
placeholder="아이디를 입력하세요"
v-model="info.userId"
name="userId"
required />
<ErrorMessage
class="error-box"
name="userId" />
</div>
<div>
<button #click="idCheck">
중복확인
</button>
</div>
</div>
</div>
import { mapState } from 'vuex'
import { Field, Form, ErrorMessage } from 'vee-validate';
methods: {
async idCheck() {
this.$store.dispatch('signup/idChecking', {
userId: this.info.userId
})
}
},
computed: {
...mapState('signup',{
info: 'Userinfo'
})
}
and code below is my store registration.js
state: {
Userinfo: {
userId: '',
password: '',
passwordConfirm: '',
userName: '',
birthDate: '',
phoneNumber: '',
email: '',
year: '',
month: '',
day: ''
}
},
actions: {
async idChecking(payload) {
const { userId } = payload
axios.get(`http://??.???.???.???:????/api/check/${userId}`)
.then(res => {
console.log(res)
})
.catch(error => {
console.log(error)
})
}
}
I resolve the problem.
I didn't put 'state' in async idChecking method.
async idChecking(state, payload) <- like this.
When the client clicks on the button, I want him to block another client, so I want my id to be dynamic: http://example/user/:id.
My template:
<template>
<div class>
<div v-for="post in posts" :key="post.id">
<div>
<div>{{ post.name }}</div>
<div>{{ post.id }}</div>
<button #click='BlockUser'>Block</button>
</div>
</div>
</div>
</template>
And my script:
<script>
const axios = require('axios');
export default {
name: 'User',
data() {
return {
posts: [],
errors: [],
id: {
id: ""
},
}
},
methods: {
getData() {
axios.get(`http://example/user`)
.then(result => {
this.posts = result.data
console.log(result)
})
},
BlockUser() {
axios.get('http://example/user/blacklist/:id' + encodeURIComponent(this.id.id))
.then(response => {
console.log(response)
})
},
},
}
</script>
Initially, I set a value for the id in data id a number and it worked. But now that I put an empty string.
it returns an undefined
If your posts have user_id field inside, you can pass it to BlockUser method, and use it in the request url.
<button #click='BlockUser(post.user_id)'>Block</button>
BlockUser(user_id) {
axios.get(`http://example/user/blacklist/${user_id}`)
.then(response => {
console.log(response)
})
},
I used the vue 2. I had a data from ajax, this is my code example:
<template>
<div>
<input type="input" class="form-control" v-model="siteInfo.siteId">
<input type="input" class="form-control" v-model="siteInfo.info.name">
<input type="input" class="form-control" v-model="siteInfo.accountData.name">
</div>
</template>
<script>
export default {
name: 'Site',
data() {
return {
siteInfo: {},
/* siteInfoName: '', */
}
},
/*computed: {
siteInfoName: function() {
return siteInfo.info.name || '';
},
...
},*/
methods: {
getData() {
// do ajax get data
this.$http.post('URL', {POSTDATA}).then(response => {
/*
response example
{ body:
data: {
sitdeId: 1,
info: { name: 'test'},
accountData: { name: 'accountTest'},
}
}
*/
this.siteInfo = response.body.data;
})
}
},
mounted() {
this.getData();
}
}
</script>
I got a warring message
[Vue warn]: Error in render: "TypeError: Cannot read property 'name'
of undefined"
I can use computed to fix it, but if I had a lot model, I should
write a lot computed.
I should create a lot data for those model?
I should not use an object to bind a lot model?
Does it have another solution for this situation? Thanks your help.
Before the data loads siteInfo.info will be undefined, so you can't access name in the v-model:
v-model="siteInfo.info.name"
Likewise for siteInfo.accountData.name.
My suggestion would be to set the initial value of siteInfo to null and then put a v-if="siteInfo" on the main div. Alternatively you could put a v-if on the individual input elements that checks for siteInfo.info and siteInfo.accountData.
You may also want to consider showing alternative content, such as a load mask, while the data is loading.
Don't be worried about too many v-models - you can do an iteration on the Object - like with Object.entries().
Vue.component('list-input-element', {
props: ['siteLabel', 'siteInfo'],
template: '<div><label>{{siteLabel}}<input type="input" class="form-control" v-model="siteInfo"></label></div>'
})
new Vue({
name: 'Site',
el: '#app',
data() {
return {
siteInfo: {},
}
},
methods: {
getData() {
// using mockup data for this example
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => {
console.log(json)
this.siteInfo = json
})
// do ajax get data
/*this.$http.post('URL', {
POSTDATA
}).then(response => {
this.siteInfo = response.body.data;
})*/
}
},
mounted() {
this.getData();
}
})
div {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<list-input-element v-for="siteInfo in Object.entries(siteInfo)" :site-label="siteInfo[0]" :site-info="siteInfo[1]" />
</div>
Rounding up
So, when you do the single file template, use a computed value, and return an Object from that.
Base your v-for on that computed, and you'll have no problems.
Something like this:
<template>
<div>
<input type="input" class="form-control" v-for="infoEl in siteInfoComputed" v-model="infoEl">
</div>
</template>
<script>
export default {
name: 'Site',
data() {
return {
siteInfo: {},
}
},
computed: {
siteInfoComputed: function() {
// you could check for all the keys-values you want here, and handle
// 'undefined' problem here
// so, actually you "create" the Object here that you're going to use
let ret = {}
// checking if this.siteInfo exists
if (Object.keys(this.siteInfo).length) ret = this.siteInfo
return ret
},
},
methods: {
getData() {
// do ajax get data
this.$http.post('URL', {POSTDATA}).then(response => {
/*
response example
{ body:
data: {
sitdeId: 1,
info: { name: 'test'},
accountData: { name: 'accountTest'},
}
}
*/
this.siteInfo = response.body.data;
})
}
},
mounted() {
this.getData();
}
}
</script>
I am having an issue with calling a parent function:
Error in v-on handler: "TypeError: self.$parent.testAddCompontnet222 is not a function"
So i have setup a test function (method) in the following file called testAddCompontnet222()
parent file: PageAdd.vue
<template>
<b-container>
<b-container>
testVar2: (( {{ testVar2 }} ))
<b-button #click="testAddCompontnet222();">Add Test 2</b-button>
<SingleBlockTemplate v-if="componentTypeSelected == 1"></SingleBlockTemplate>
<TripleBlockTemplate v-if="componentTypeSelected == 2"></TripleBlockTemplate>
</b-container>
</b-container>
</template>
<script>
import axios from 'axios';
import SingleBlockTemplate from './component_templates/SingleBlockTemplate.vue';
import TripleBlockTemplate from './component_templates/TripleBlockTemplate.vue';
import ComponentAddForm from './ComponentAddForm.vue';
export default {
data(){
return {
title: 'Case Studies',
excerpt: 'some text here for reference',
slug: 'unique',
meta_title: 'title for search engines (should be the same as the page title)',
meta_description: 'meta descriptions for search engines',
meta_keywords: 'keywords',
order: '1',
status: '1',
showAddComponentForm: false,
error: false,
errors: {},
testVar2: '2',
newContentData: {},
componentTypeSelected: '2',
componentTypes: {},
componentList: {}
};
},
mounted: function () {
this.getComponentTypes();
//this.componentTypeToCreate =
},
methods: {
testAddCompontnet222(){
this.testVar2 = '222!';
console.log("test 222222!")
},
addPage(){
axios({
method: 'post',
url: this.$appAPI+'/twg-cms/page',
data: {
title: this.title,
excerpt: this.excerpt,
slug: this.slug,
meta_title: this.meta_title,
meta_description: this.meta_description,
meta_keywords: this.meta_keywords,
order: this.order,
status: this.status
}
}).then(response => {
console.log(response.data)
}).catch(e => {
console.log(e)
this.errors.push(e)
});
},
getComponentTypes(){
axios.get(this.$appAPI+`/twg-cms/component_types`)
.then((response) => {
this.componentTypes = response.data.data;
})
.catch(() => {
console.log('handle server error from here');
});
},
componentTypeOnChange(value){
//console.log(this.componentTypeSelected)
}
},
components: {
ComponentAddForm,
SingleBlockTemplate,
TripleBlockTemplate
}
}
</script>
I then attempt to call the function from a child element (imported file): TripleBlockTemplate.vue
I have tried using just this.$parent.testAddCompontnet222(); and as you can see below currently self.$parent.testAddCompontnet222();
But both return the same error. I have this working in exactly the same way on other components
<template>
<form autocomplete="off" #submit.prevent="addComponent" method="post">
<b-button #click="testAddCompontnet();">Add Test</b-button>
<p>This is a triple block component</p>
<ckeditor :editor="editor" v-model="content[0]" :config="editorConfig"></ckeditor>
<ckeditor :editor="editor" v-model="content[1]" :config="editorConfig"></ckeditor>
<ckeditor :editor="editor" v-model="content[2]" :config="editorConfig"></ckeditor>
<b-button #click="addComponent" variant="outline-primary">Save component</b-button>
</form>
</template>
<script>
import axios from 'axios';
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
export default {
data(){
return {<template>
<form autocomplete="off" #submit.prevent="addComponent" method="post">
<b-button #click="testAddCompontnet();">Add Test</b-button>
<p>This is a triple block component</p>
<ckeditor :editor="editor" v-model="content[0]" :config="editorConfig"></ckeditor>
<ckeditor :editor="editor" v-model="content[1]" :config="editorConfig"></ckeditor>
<ckeditor :editor="editor" v-model="content[2]" :config="editorConfig"></ckeditor>
<b-button #click="addComponent" variant="outline-primary">Save component</b-button>
</form>
</template>
<script>
import axios from 'axios';
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
export default {
data(){
return {
editor: ClassicEditor,
name: 'Name here',
class: 'Class here',
html_id: 'ID here',
content:[
'<div><h1>Title 1</h1><br /><p>some simple text here</p></div>',
'<div><h1>Title 2</h1><br /><p>some simple text here</p></div>',
'<div><h1>Title 3</h1><br /><p>some simple text here</p></div>'
],
editorConfig: {
// The configuration of the editor.
}
};
},
methods: {
testAddCompontnet(){
var self = this;
self.$parent.testAddCompontnet222();
console.log("test 222!")
},
addComponent(){
axios({
method: 'post',
url: this.$appAPI+'/twg-cms/component',
data: {
name: this.name,
content: JSON.stringify({content: this.content}),
class: this.class,
html_id: this.html_id
}
}).then(response => {
console.log(response.data)
}).catch(e => {
console.log(e)
this.errors.push(e)
});
}
}
}
</script>
editor: ClassicEditor,
name: 'Name here',
class: 'Class here',
html_id: 'ID here',
content:[
'<div><h1>Title 1</h1><br /><p>some simple text here</p></div>',
'<div><h1>Title 2</h1><br /><p>some simple text here</p></div>',
'<div><h1>Title 3</h1><br /><p>some simple text here</p></div>'
],
editorConfig: {
// The configuration of the editor.
}
};
},
methods: {
testAddCompontnet(){
var self = this;
self.$parent.testAddCompontnet222();
console.log("test 222!")
},
addComponent(){
axios({
method: 'post',
url: this.$appAPI+'/twg-cms/component',
data: {
name: this.name,
content: JSON.stringify({content: this.content}),
class: this.class,
html_id: this.html_id
}
}).then(response => {
console.log(response.data)
}).catch(e => {
console.log(e)
this.errors.push(e)
});
}
}
}
</script>
Finally here is a working method which i am currently not using...
The following code, would allow me to use the same/similar code to update/change the parent variable testVar1 to update it's parent: ComponentAddForm.vue below
testAddCompontnet(){
var self = this;
self.$parent.testVar1 = '11111! test;
console.log("test 222!")
},
ComponentAddForm.vue:
<template>
<b-container>
testVar1: (( {{ testVar1 }} ))
<b-button #click="testAddCompontnet222();">Add Test 2</b-button>
<SingleBlockTemplate v-if="this.componentTemplateId == 1"></SingleBlockTemplate>
<TripleBlockTemplate v-if="this.componentTemplateId == 2"></TripleBlockTemplate>
</b-container>
</template>
<script>
import axios from 'axios';
import SingleBlockTemplate from './component_templates/SingleBlockTemplate.vue';
import TripleBlockTemplate from './component_templates/TripleBlockTemplate.vue';
export default {
props: ['componentTemplateId'],
data(){
return {
name: 'Case Studies',
testVar1: '1'
};
},
mounted: function () {
this.showComponentTemplate();
},
methods: {
testAddCompontnet222(){
this.$parent.testVar2 = '222!';
console.log("we made it here <--------");
},
showComponentTemplate(){
if(this.componentTemplateId === '1'){
console.log('test 1')
}
if(this.componentTemplateId === '2'){
console.log('test 2')
}
}
},
components: {
SingleBlockTemplate,
TripleBlockTemplate
}
}
</script>
Im creating a Notification component using Vuex to store data API and called it in components but I have some issues
Component.vue
<template>
<div class="notification_check">
<div class="header">
<span>Notifications </span>
<span>(1)</span>
</div>
</div>
<ul v-for="notification in $store.state.notification.notifications.list" :key="notification.id">
{{notification.id}}
</ul>
</template>
<script>
export default {
data: function () {
return {
config: {
'headers': {
'Authorization': 'JWT ' + this.$store.state.token
}
},
notifications: this.$store.state.notification.notifications.list
}
},
created: function () {
this.getNotification()
},
methods: {
getNotification: function () {
this.$store.dispatch('getNotification', this.config)
}
}
}
</script>
This is Action Commit:
getNotification ({commit}, config) {
api.get(`/notifications/`, config)
.then(response => {
commit('GET_NOTIFICATION', response.data)
})
},
This is my data API which stored in Vuex Store. Please take a look:
Error occurs:
Cannot read property 'list' of null