vue-multiselect not displaying array ( options: Array [0] ) - javascript

I am attempting to add a vue-multiselect into an existing form, however, the dropdown is empty. This is more than a display issue as Vue devtools shows me my array is empty. I get no issues in the console.
The value for my select is from my API, I'm 99% sure my code there works, as it's exactly the same as I use elsewhere in my app to display a loop of the same values.
I'm using Nux.js.
Following the docs and other questions on SO, I feel I'm pretty close with the below code, but something must be amiss, I just can't spot it.
html
<template>
<section class="container">
<div>
<h1>Gins</h1>
<form #submit.stop.prevent="addGin">
<h2>New Gin</h2>
<p>
<label for="gin_name" class="input-label">Title:</label>
<input id="gin_name" v-model="gin_name" type="gin_name" name="gin_name" class="input">
</p>
<p>
<label for="description" class="input-label">Description:</label>
<input id="description" v-model="description" type="description" name="description" class="input">
</p>
<div>
<label for="distillery" class="input-label">Distillery:</label>
<multiselect
v-model="distillery_id"
track_by="id"
:options="options"
:searchable="true"
placeholder="Choose One Distillery"
>
</multiselect>
</div>
<p>
<input type="submit" value="Submit" class="button">
</p>
</form>
</div>
</section>
</template>
javascript
<script>
import axios from 'axios'
import Multiselect from 'vue-multiselect'
export default {
components: { Multiselect },
data() {
return {
gin_name: '',
description: '',
distillery_id: '',
options: []
}
},
methods: {
addGin() {
axios.post('http://localhost:4000/api/v1/gins', {
gin_name: this.gin_name, description: this.description
})
.then((response) => {})
},
getDistilleries() {
axios.get('/api/v1/distilleries')
.then((res) => {
this.options = res.data
})
.catch((error) => {
console.log(error)
})
}
}
}
</script>

Related

nuxtjs with simple-vue-validator as plugin

I am new to Vue and Nuxt and I am building simple forms with simple-vue-validator for validating the form before I submit it to the back-end. I did follow the Nuxtjs plugin's documentation but I am getting some errors 😞
The error I am getting is TypeError: Cannot read property 'Validator' of undefined.
I can't find any $SimpleValidator on this. Not sure if I did something wrong or forgot something, but I keep reading the documentation and this is all I understand. Thanks in advance.
./plugins/simple-validator.js
import Vue from 'vue'
import SimpleValidator from 'simple-vue-validator'
Vue.use(SimpleValidator)
./nuxt.config.js
export default {
...
plugins: [
{ src: '#/plugins/simple-validator.js', ssr: true }
],
...
}
./pages/index.vue*
<template>
<form>
<div class="field-holder">
first name *
<input type="text" v-model="formValues.firstName" :value="formValues.firstName" />
<span v-if="validation.hasError('firstName')">
{{ validation.firstError('firstName') }}
</span>
</div>
<div class="field-holder">
middle name
<input type="text" v-model="formValues.middleName" :value="formValues.middleName" />
</div>
<div class="field-holder">
last name *
<input type="text" v-model="formValues.lastName" :value="formValues.lastName" />
<span v-if="validation.hasError('lastName')">
{{ validation.firstError('lastName') }}
</span>
</div>
<button #click="submit">Submit</button>
</form>
</template>
<script>
export default {
data () {
formValues: {
firstName: '',
middleName: '',
lastName: ''
}
},
validators: {
'formValues.firstName' (value) {
return this.$SimpleValidator.Validator.value(value).required()
},
'formValues.lastName' (value) {
return this.$SimpleValidator.Validator.value(value).required()
}
},
methods: {
submit (event) {
event.preventDefault()
this.$validate()
.then(function (success) {
if (success) {
console.log('Validation succeeded!')
}
})
}
}
}
</script>
I fixed my issue! 🎊
We just need to add import { Validator } from 'simple-vue-validator' to the component that requires it. So the updated component will look like this:
./pages/index.vue
<template>
<form>
<div class="field-holder">
first name *
<input type="text" v-model="formValues.firstName" :value="formValues.firstName" />
<span v-if="validation.hasError('firstName')">
{{ validation.firstError('firstName') }}
</span>
</div>
<div class="field-holder">
middle name
<input type="text" v-model="formValues.middleName" :value="formValues.middleName" />
</div>
<div class="field-holder">
last name *
<input type="text" v-model="formValues.lastName" :value="formValues.lastName" />
<span v-if="validation.hasError('lastName')">
{{ validation.firstError('lastName') }}
</span>
</div>
<button #click="submit">Submit</button>
</form>
</template>
<script>
import { Validator } from 'simple-vue-validator'
export default {
data () {
formValues: {
firstName: '',
middleName: '',
lastName: ''
}
},
validators: {
'formValues.firstName' (value) {
return Validator.value(value).required()
},
'formValues.lastName' (value) {
return Validator.value(value).required()
}
},
methods: {
submit (event) {
event.preventDefault()
this.$validate()
.then(function (success) {
if (success) {
console.log('Validation succeeded!')
}
})
}
}
}
</script>

Request aborted when trying to post data from vue js to laravel backend

I have been struggling with an issue for like the whole day now. Every time I want to post data to my laravel back end from my vue js component, it says that the request has been aborted. I really can't see what's wrong with my code. Any help is greatly appreciated. I have CORS installed so that' not the problem. I have tried to clear the route cache and that didn't work either.
Controller store method. Here is where I make a check whether the title exists and if not, proceed to save the story in the database:
public function store(
AuthenticatedUserId $authenticatedUserId,
CreateNewRecordInDatabase $createNewRecordInDatabase,
FindDataById $findDataById,
RetrieveAllData $retrieveAllData,
Request $request,
$writer
)
{
$writer = $findDataById->findDataById(User::class, $writer);
$stories = $retrieveAllData->retrieveAllData(Story::class);
foreach ($stories as $check_title) {
if ($check_title->title == $request->title) {
return redirect()
->route('writer.create', ['writer' => $authenticatedUserId->authId()])
->with('title_exists', 'Title already exists');
}
}
$createNewRecordInDatabase->createRecord($writer->stories(), [
'title' => $request->title,
'story' => $request->story,
'published_on' => date('m-d-Y'),
'category_id' => $request->category_id
]);
return response()->json('success');
}
API route:
Route::post('/dashboard/writer/{writer}/store', 'Story\StoryController#store');
Vue component:
<template>
<div class="row">
<form class="col s12">
<input type="hidden" name="_token" :value="csrf">
<div class="row">
<div class="col s12">
<input v-model="title" type="text"
class="input-field"
placeholder="Give it a catchy title"
required
>
<label for="title">Give it a catchy title</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<select v-model="category_id" name="category_id">
<option
v-for="category in categories"
v-bind:key="category.id"
v-bind:value="category.id"
>{{ category.category }}
</option>
</select>
</div>
</div>
<div class="white col s12" id="editorjs"></div>
<div class="col s12">
<button #click="publishStory" class="btn waves-effect waves-light">Publish</button>
</div>
</form>
</div>
<script>
import EditorJS from '#editorjs/editorjs';
import Header from '#editorjs/header';
import Link from '#editorjs/link';
import List from '#editorjs/list';
import Quote from '#editorjs/quote';
export default {
props: ['categories', 'writer'],
data() {
return {
title: null,
category_id: null,
story: [],
editor: new EditorJS({
tools: {
header: {
class: Header,
inlineToolbar: true
},
list: {
class: List,
inlineToolbar: true
},
link: {
class: Link,
inlineToolbar: true
},
quote: {
class: Quote,
inlineToolbar: true
}
}
}),
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
},
methods: {
publishStory() {
this.editor.save()
.then(outputData => this.story = outputData.blocks)
.catch(err => console.log(err))
axios.post(`http://localhost:8000/api/dashboard/writer/${this.writer}/store`, {
title: this.title,
story: this.story,
category_id: this.category_id,
})
.then(res => console.log(res))
.catch(err => console.log(err))
}
},
mounted() {}
}
</script>
Try to increase php.ini settings
max_input_time
upload_max_filesize
post_max_size
memory_limit
max_input_vars
PHP Truncating POST Data
I had the same problem. Changing the <form> tag to <div> tag worked for me.

How can I use field validation in my Vue wizard form?

In an example of a Vue wizard form I tried to add form validation with Joi. How do I set this up logically? The goal is to controll the fields before moving to the second and last page with the next() method. Because of the simplicity of this wizard form, I don't want to change to VueFormWizard. To increase the code I erased a lot of fields etc..
<template>
<div>
<div v-if="errorMessage" class="alert alert-danger" role="alert">
{{errorMessage}}
</div>
<form>
<div v-if="step ===1 ">
<div class="form-group">
<label for="title">Title</label>
<input v-model="example.title"
type="text"
class="form-control"
id="title" />
</div>
<button #click.prevent="next()">Next step</button>
</div>
<div v-if="step === 2">
<div class="form-group">
<label for="userName">Email.</label>
<input v-model="example.userName"
type="email"
class="form-control"
id="userName" />
</div>
<button #click.prevent="prev()">Go back</button>
<button #click.prevent="createExample" type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</template>
<script>
import Joi from 'joi'
const schema = Joi.object().keys({
title: Joi.string().alphanum().min(2).max(40).required(),
userName: Joi.string().email(),
})
export default {
data: () => ({
step: 1,
errorMessage: false,
example: {
title: '',
userName: ''
}
}),
watch: {
example: {
handler () {
this.errorMessage = ''
},
deep: true
}
},
methods: {
prev () {
this.step--
},
next () {
this.step++
if (this.validUser()) {
return false
}
},
createExample () {
// Post request
},
validUser () {
const result = Joi.validate(this.huismap, schema)
return true
if (result.error.message.includes('title')) {
this.errorMessage = 'Vul een titel in van min 2 karakters'
return false
}
}
}
</script>
You can make use of browser validation if you set it up like this:
<form #submit.prevent="submitMyForm">
<input v-model="form.title" required minlength="4" maxlength="20" />
<button type="submit">Submit</button>
</form>
Now your browser will prevent you from submitting the form if title is empty, if the length is less than 4 or greater than 20.
This solution can do a lot of stuff, even regex checking:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation#Validating_against_a_regular_expression
However this is limited to a small set of checks and is not supported by older browsers. If you need very specific validation you'd have to use a custom solution, which is described here https://v2.vuejs.org/v2/cookbook/form-validation.html.

Why i can't filter local json file in this case (vuejs2)

Before i set vue cli-3 in my project, the filter could work. After I set it up, I cannot reach any result. What am I doing wrong? There isn't any error in the console. I'll share the codes below.
Thanks in advance.
<template>
<div id="preview" class="nested">
<div class="card-body" v-for="item in items" :key="item.id">
<h5 class="card-title">{{item.companyName}}</h5>
<p class="card-text">{{item.positionName}}</p>
<p class="card-text">{{item.cityName}}</p>
<p class="card-text">{{item.townName}}</p>
<p class="card-text">{{item.distance}}</p>
Go!
</div>
</div>
</template>
<script>
export default {
data() {
return {
filteredFounded: [],
founded: [],
items: [],
search: "",
show: false,
city: ""
};
},
created() {
this.$http
.get("http://www.json-generator.com/api/json/get/cguWKZoQMO?indent=2")
.then(res => {
return res.json();
})
.then(res => {
this.founded = res.items;
});
},
methods: {
setFounded() {
this.filteredFounded = this.founded.filter(items => {
return (
items.cityName.toLowerCase() === this.city.toLowerCase() &&
items.positionName.toLowerCase().match(this.search.toLowerCase())
);
});
}
}
};
</script>
i forgot add this code. sorry. everythings look fine but. Cannot read property 'filter' of undefined error fetch now.
<template>
<div id="app" class="nested">
<div class="card w-50">
<div class="search">
<input type="text" class="job" v-model="search" placeholder="Job...">
<select name="" class="city" id="">
<option value="Seçiniz">Seçiniz</option>
<option value="İstanbul">İstanbul</option>
<option value="Ankara">Ankara</option>
<option value="İzmir">İzmir</option>
<option value="Çanakkale">Çanakkale</option>
</select>
</div>
<div class="find">
<button v:on-click="setFounded">Find!</button>
</div>
</div>
</div>
Your problem is not related to Vue Cli 3.x, you had done some mistakes in the promise scope such as return res.json() and this.founded = res.items; but the res object have the following keys :config data headers request status and statusText.
In this situation we need only the data property which is an array of objects (items), so change return res.json() to return res.data and this.founded = res.items; to this.founded = res.data;
add v-model="city" to the select as follow <select name="" class="city" id="" v-model="city"> and you had written v:on-click incorrectly, change it to #click
Finally change return ( items.cityName.toLowerCase() === this.city.toLowerCase() && items.positionName.toLowerCase().match(this.search.toLowerCase()) ); to return ( items.cityName === this.city && items.positionName===this.search );

passing data between components in vuejs

I've got my expense tracker app. I've got problem with adding Expense.
I've got two components responsible for this: addCategory.vue and selectCategory.vue.
This is my selectCategory.vue component:
<template>
<div>
<select class="custom-select" #selected="this.$emit('select-cat',category)">
<option v-for="category in categories">{{ category.title }}</option>
</select>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
categories: [],
errors: []
}
},
created() {
axios.get(`http://localhost:3000/categories`)
.then(response => {
this.categories = response.data;
console.log(response.data);
})
.catch(e => {
this.errors.push(e)
})
}
}
</script>
and this is my addExpense.vue component:
<template>
<div class="card">
<div class="card-header">
<h4>Dodaj nowy wydatek</h4>
</div>
<form v-on:submit.prevent="addExpense">
<div class="card-body">
<div class="form-group">
<label for="expense-name">Nazwa wydatku</label>
<input type="text" class="form-control" id="expense-name" v-model="Expense.title">
</div>
<div class="form-group">
<label for="expense-amount">Wartość</label>
<input type="number" class="form-control" id="expense-amount" v-model="Expense.amount">
</div>
<div class="form-group">
<label for="expense-date">Data wydatku</label>
<input type="date" class="form-control" id="expense-date" v-model="Expense.date">
</div>
<div class="form-group">
<label for="expense-category">Kategoria</label>
<select-category #select-cat="chooseCategory" v-model="Category.id"></select-category>
</div>
<br>
<div class="form-group">
<button class="btn btn-primary" #click="showAlert">Dodaj nowy wydatek</button>
</div>
</div>
</form>
</div>
</div>
</template>
<script>
import axios from 'axios';
import selectCategory from './selectCategory.vue';
export default {
components: {
'select-category': selectCategory
},
data(){
return {
Expense: {
title:'',
amount: '',
date:'',
categoryId:''
},
}
},
methods : {
chooseCategory(){
this.Expense.categoryId = this.Category.id
},
showAlert(){
this.$alert.success({
message: 'Wydatek dodany poprawnie'
})
},
addExpense(){
let newExpense = {
title : this.Expense.title,
amount : this.Expense.amount,
date : this.Expense.date,
categoryId: this.Expense.categoryId
}
console.log(newExpense);
axios.post(`http://localhost:3000/expenses`, newExpense)
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
})
}
}
}
</script>
I need help because when I try to add the Expense, field with 'categoryId' remains empty.
I use Events to pass the name of categories but I dont know how to add category.id to Expense.
The issues in your codes:
you need to add one data property to save which option the user selected, so add one data property=selectedCategory
you didn't bind the value for the options of the select, and you didn't bind the value of the select, so add v-model="selectedCategory" for <select> and add :value="category" for <option>
It seems you bind wrong event (event=selected more likely is the event name you customized) for <select>, change to #change="selectChange(selectedCategory)"
Finally, in addExpense.vue, listen event=select-cat.
Like below demo:
Vue.config.productionTip = false
Vue.component('select-category', {
template: `<div>
<select class="custom-select" v-model="selectedCategory" #change="selectChange(selectedCategory)">
<option v-for="category in categories" :value="category">{{ category.title }}</option>
</select>
</div>`,
data() {
return {
categories: [],
errors: [],
selectedCategory: null
}
},
mounted() {
this.categories = [
{'id':1, 'title': 'abc'},
{'id':2, 'title': 'xyz'}
]
},
methods: {
selectChange: function(newCatetory) {
this.$emit('select-cat',newCatetory)
}
}
})
new Vue({
el: '#app',
data() {
return {
categorySelected: null
}
},
watch: {
categorySelected: function (newVal, oldVal) {
console.log('changed to ' + newVal.id + ' from ' + (oldVal ? oldVal.id : oldVal))
}
},
methods:{
chooseCategory: function(data) {
this.categorySelected = data
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div class="form-group">
<label for="expense-category">Kategoria</label>
<select-category #select-cat="chooseCategory($event)"></select-category>
</div>
</div>

Categories

Resources