I'm trying to make an edit button for an object(song). I want to pass my data to the edit form, so the input it will be completed with the actual data, but I always get undefined. I tried a lot of solutions but no one worked for me. What's the problem?
My Song Component, I am trying to pass its data to the edit form
<template>
<div class="hello">
<h1>{{ song.name }}</h1>
<p>Author: {{ song.author }}</p>
<p>Views: {{ song.views }}</p>
<!-- <button #click="$router.push('/update-song?id=' + song.id )">Update</button> -->
<button #click="$router.push({path: '/update-song', Component: UpdateSong, props: {song: song}})">Update</button>
</div>
</template>
<script>
export default {
name: 'Song',
props: {
song: Object
}
}
</script>
My edit view:
<template>
<div>
<p>Update a song: {{this.author}} - {{this.name}}</p>
<input type="text" id="name" placeholder="Name" v-model="name"/><br/>
<input type="text" id="author" placeholder="Author" v-model="author"/><br/>
<input type="text" id="country" placeholder="Country" v-model="country"/><br/>
<input type="text" id="duration" placeholder="Duration" v-model="duration"/><br/>
<input type="text" id="views" placeholder="Views" v-model="views"/><br/>
<input type="text" id="genre" placeholder="Genre" v-model="genre"/><br/>
<button #click="updateSong">Update Song</button>
</div>
</template>
<script>
export default{
name: 'UpdateSong',
props: {
song: Object
},
mounted() {
console.log(this.song) //undefined
},
data(){
return{
name: '',
author: '',
country: '',
duration: 0,
views: 0,
genre: ''
}
},
methods: {
updateSong(){...}
}
}
</script>
My routes:
const routes = [...,
{
path: '/update-song',
name: "updateSong",
component: UpdateSong
}
]
Related
I am new to Vue JS and have been learning it from the documentation provided. My project is a simple task adding web-app. On using the v-model directive, I'm not getting any output. My javascript function to add the task is apparently not being called.
<template>
<div id="text">
TASKS:
<form onsubmit="return addTodo()">
<input type="text" class="todo-input" placeholder="What's up" v-model="message">
<input type="date" class="todo-input" v-model="ddate" >
<input type="submit" value="Add">
</form>
<div v-for="(todo, index) in todos" :key="todo.id" class="todo-item">
<div>
{{todo.id}}{{todo.title}}{{todo.date}}
</div>
</div>
</div>
</div>
</template>
export default {
name: 'todo-list',
data () {
return {
message: '',
ddate: '',
idForTodo: 1,
todos: [
]
}
},
methods: {
addTodo(){
if(this.message.trim().length == 0){
return
}
this.todos.push({
id: this.idForTodo,
title: this.message,
completed: false,
editing: false,
date: this.ddate,
})
this.ddate = ''
this.message = ''
this.idForTodo++
},
}
}
Looks like someone edited the question with correct code while I was writing the answer. I tried and tested same code in code snippet and it's working.
const app = new Vue({
el: '#text',
data() {
return {
message: '',
ddate: '',
idForTodo: 1,
todos: [
]
}
},
methods: {
addTodo(){
console.log(this.message)
if(this.message.trim().length == 0){
return
}
this.todos.push({
id: this.idForTodo,
title: this.message,
completed: false,
editing: false,
date: this.ddate,
})
this.ddate = ''
this.message = ''
this.idForTodo++
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.0/vue.js"></script>
<div id="text">
TASKS:
<form>
<input type="text" class="todo-input" placeholder="What's up" v-model="message">
<input type="date" class="todo-input" v-model="ddate" >
<button v-on:click.prevent="addTodo">Add</button>
</form>
<div v-for="(todo, index) in todos" :key="todo.id" class="todo-item">
<div>
{{todo.id}} {{todo.title}} {{todo.date}}
</div>
</div>
</div>
Hi and sorry for the Newbie-Question
I am trying to push a HTML-Input into an existing array on Button-click, but i cannot find my mistake.
Can anyone spot the mistake? The console.log(user) stays undefined and I don't know why the let newUser() I create does not get pushed into the array.
<template>
<div>
<form #submit.prevent="customSubmit">
<label>Name</label>
<input type="text" required name="name" id="name">
<label>E-mail:</label>
<input type="email" required name="email" id="email">
<label>Mobile Number</label>
<input type="number" required name="number" id="number">
</form>
<button type="submit" class=buttonSignup #click="customSubmit">Submit</button>
</div>
</template>
<script>
export default {
data() {
return{
user:[{
name: '',
email:'',
number:''
}]
};
},
methods: {
customSubmit(){
let newUser = {
name: document.getElementById('name').value,
email: document.getElementById('email').value,
number: document.getElementById('number').value
}
this.user.push(newUser)
console.log(this.user.value)
},
}
}
</script>
With Vue, you use v-model instead of directly accessing the DOM. For example, you can re-write your code by:
Change name=name to v-model=user.name
Use user and users. user collects one user's data and users collects all user input into an array. This is reflected in the modified customSubmit.
Reset user after each input.
There are more elegant ways to do this but this is the clearest and close enough to your original code.
<template>
<div>
<form #submit.prevent="customSubmit">
<label>Name</label>
<input type="text" required v-model="user.name" id="name">
<label>E-mail:</label>
<input type="email" required v-model="user.email" id="email">
<label>Mobile Number</label>
<input type="number" required v-model="user.number" id="number">
</form>
<button type="submit" class=buttonSignup #click="customSubmit">Submit</button>
<br/>
You typed:<br/>
name: {{user.name}}<br/>
email: {{user.email}}<br/>
number: {{user.number}}
</div>
</template>
<script>
export default {
data() {
return {
users: [],
user: {
name: '',
email: '',
number: ''
}
};
},
methods: {
customSubmit() {
// do some checking here
this.users.push(this.user)
this.user = {name:'', email:'', number:''};
console.log(this.users)
},
}
}
</script>
I have a basic input that should update a data on input change, but it doesn't because it returns Uncaught TypeError: Cannot read property 'settings' of undefined
Vue component
<template>
<div>
<div class="inner_container">
<p>
URL:
<span>{{settings.url}}</span>
</p>
<div class="input_row">
<input
class="input_text"
id="getURL"
type="url"
inputmode="url"
placeholder="Enter URL"
title="URL"
#input="changeUrl"
/>
<label class="label_" for="getURL">URL Link</label>
</div>
<button class="button" #click="saveSettings">Save all Values</button>
</div>
<div>
</template>
<script>
import axios from "axios";
import _ from "lodash";
export default {
name: "Home",
data() {
return {
settings: {
brightness: "",
},
};
},
methods: {
changeUrl: _.debounce((e) => {
this.settings.url = e.target.value;
}, 500),
},
};
</script>
On each input change I receive the above error.
What am I doing wrong ?
The problem is that this in the arrow function is not referring to the object you want. One solution is to use a normal function and predefine the property url in settings:
new Vue({
el: '#app',
data() {
return {
settings: {
brightness: "",
url: ""
},
};
},
methods: {
changeUrl: _.debounce(function(e) {
this.settings.url = e.target.value;
}, 500),
saveSettings(){
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app">
<div class="inner_container">
<p>
URL: <span>{{settings.url}}</span>
</p>
<div class="input_row">
<input
class="input_text"
id="getURL"
type="url"
inputmode="url"
placeholder="Enter URL"
title="URL"
#input="changeUrl"
/>
<label class="label_" for="getURL">URL Link</label>
</div>
<button class="button" #click="saveSettings">Save all Values</button>
</div>
</div>
A simpler approach you may find useful is to set the variable using v-model:
new Vue({
el: '#app',
data() {
return {
settings: {
brightness: "",
},
};
},
methods: {
saveSettings(){
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app">
<div class="inner_container">
<p>
URL: <span>{{settings.url}}</span>
</p>
<div class="input_row">
<input
class="input_text"
id="getURL"
type="url"
inputmode="url"
placeholder="Enter URL"
title="URL"
v-model="settings.url"
/>
<label class="label_" for="getURL">URL Link</label>
</div>
<button class="button" #click="saveSettings">Save all Values</button>
</div>
</div>
Ciao, try to use debounce like this:
_.debounce(function(e) {
this.settings.url = e.target.value;
}, 500)
The problem is that you are using this in a statement that is not being called on a JS class. Fix this by changing the this to a variable name, and setting that variable name to a class.
My values on my vue js form are blank or undefined when i submit them for some reason. I am trying to log e.target.name.value to the console to check my form values.
Is there an easier way to do this in vue for this setup? I've been trying different methods and I fear i'm trying to homogenize my vanilla js with vue and creating more problems for myself.
my vue data:
new Vue({
el: '#grocery_list',
data: {
selected: null,
list: [
{
id: 0,
category: 'Baked goods',
food: ['bread','cookie','butter','powder']
},
{
id: 1,
category: 'meats',
food: ['chicken','turkey','beef']
},
{
id: 2,
category: 'fruits',
food: ['bannana','apple','pineapple']
},
{
id: 3,
category: 'canned goods',
food: ['tomatoes','green beans','corn']
},
{
id: 4,
category: 'veggies',
food: ['broccoli','celery','lettuce']
},
{
id: 5,
category: 'pantry',
food: ['broom','mop','dried beans']
},
],
isHidden: true,
form: {},
},
methods:{
addItem: function(e){
console.log(form)
},
viewItemsinCat: function(){
this.isHidden = false
},
checkItem: function(){
}
}
})
my html
<div class="addItem" id="addItem" #submit.prevent="addItem">
<form>
<label for="addItem">Add food item</label>
<input v-model="form.foodName" type="text" name="foodName"></input>
<div>
<select v-model="form.category" id="food">
<option v-for="item in list" name="item">{{item.category}}</option>
</select>
</div>
<div>
<button type="submit">Add Item</button>
</div>
</form>
</div>
In vuejs you don't have to use the names or ids to get value of an input all you have is to use v-model which is reactive and will update all the form values instantly
check this out
<template>
<div class="addItem" id="addItem" #submit.prevent="addItem">
<form>
<label for="addItem">Add food item</label>
<input v-model="form.foodName" type="text" name="foodName"></input>
<div>
<select v-model="form.category" id="food">
<option v-for="item in list" name="item">{{item.category}}</option>
</select>
</div>
<div>
<button type="submit">Add Item</button>
</div>
</form>
</div>
</template>
<script>
export default {
data: () => ({
form: {}
}),
methods: {
addItem: function(){
console.log(this.form)
}
}
}
</script>
How can I have different V-MODEL on every object that i generate
I am trying to make an sample cupcake website that can generate multiple forms in one submit.
But when I generate 2 field, the inputs of the 2 generated field bound by each other inputs.
This is the code I am trying to generate:
<template>
<div>
<button #click="cupcakes.push(def)">Add Cup Cake</button>
<div v-for="(cupcake, index) in cupcakes" :key="index">
<input type="text" v-model="cupcakes[index].name">
<input type="text" v-model="cupcakes[index].description">
<input type="text" v-model="cupcakes[index].type">
<input type="text" v-model="cupcakes[index].prize">
<input type="text" v-model="cupcakes[index].color">
</div>
<button #click="onSubmit">Create Cupcate</button>
</div>
</template>
<script>
export default {
data() {
return {
cupcakes: [],
def: {
name: '',
description: 'Originals',
type: 'small',
prize: 500,
color: 'color'
}
}
},
methods: {
onSubmit() {
console.log(this.cupcakes);
}
}
}
</script>
I tried to do other things but it doesn't work.
How can I dis bind the 2 field and when I submit it will take the inputs that I type or input.
You are pushing n times the same objet (def) into your cupcakes Array. def is a reference to an object. So when you update cupcakes[n], you are just updating the def values.
What you need to do is send a copy of that object into the cupcakes object:
<button #click="cupcakes.push(JSON.parse(JSON.stringify(def)))">Add Cup Cake</button>
I think a better pattern would be to make a method that returns you a new cupcake:
<template>
<div>
<button #click="cupcakes.push(getNewCupcake())">Add Cup Cake</button>
<div v-for="(cupcake, index) in cupcakes" :key="index">
<input type="text" v-model="cupcakes[index].name">
<input type="text" v-model="cupcakes[index].description">
<input type="text" v-model="cupcakes[index].type">
<input type="text" v-model="cupcakes[index].prize">
<input type="text" v-model="cupcakes[index].color">
</div>
<button #click="onSubmit">Create Cupcate</button>
</div>
</template>
<script>
export default {
data() {
return {
cupcakes: []
};
},
methods: {
onSubmit() {
console.log(this.cupcakes);
},
getNewCupcake() {
return {
name: "",
description: "Originals",
type: "small",
prize: 500,
color: "color"
}
}
}
};
</script>