Vuejs + Laravel array issue - laravel

My problem is I'm trying to loop and array from Axios query into my blade template, query is giving me no errors but tells me is undefined multiple times on my select tag.
I have a simple Axios query from my Laravel Controller:
public function consultaPersonas()
{
$consulta = persona::all();
if(!$consulta) {
$consulta = ['error' => 'No hay registros'];
}
return $consulta;
}
this query will bring me this little array:
[
{"cedula":"15678453","nombre":"LUIS CHACON","edad":30},
{"cedula":"2536524","nombre":"MARIO ORTEGA","edad":21},
{"cedula":"25632541","nombre":"VANESSA ALCALA","edad":24}
]
This is the Select Tag i want to loop:
<select class="form-control" v-model="nombre">
<option v-for="nom in nombre">#{{ nombre }}</option>
</select>
Here's my Vuejs code:
var app = new Vue({
el: '#root',
data: {
cedula: '',
nombre: [],
},
watch: {
cedula: function() {
this.nombre = ''
if (this.cedula.length == 1) {
this.buscarCedula()
this.nombre = "Consultando cédula...";
}
}
},
methods: {
buscarCedula: _.debounce(function() {
axios.get('http://localhost/miapp/public/personas/mostrar')
.then(function(response) {
let datos = response.data;
let validar = datos.error;
if (!validar) {
app.nombre =
datos.cedula + ' - ' +
datos.nombre + ' - ' +
datos.edad;
} else {
app.nombre = validar;
}
})
.catch(function(error) {
app.nombre = error;
})
}, 500)
}
What am I doing wrong? Thanks.

js:
created():
axios.get('http://localhost/miapp/public/personas/mostrar')
.then(function (response){
this.nombre = response.data;
}).catch(function (error) {
console.log(error);
})
html:
<select class="form-control" v-model="nombre">
<option v-for="nom in nombre">#{{ nom.nombre }}</option>
</select>
Next, you transfer from the created method call axios to methods, and in created call this method. This initializes your initial data

I find out what was wrong,
I had two problems, one was my view tags variables, this is the right way since i need to loop through my nom object with his index like this:
<select class="form-control" v-model="nombre">
<option v-for="nom in nombre">#{{ nom.cedula }}</option>
</select>
the second problem was my return at my vuejs file, i was returning one single output into a loop, this is the right way:
var app = new Vue({
el: '#root',
data: {
cedula: '',
nombre: [],
},
watch: {
cedula: function() {
this.nombre = ''
if (this.cedula.length == 1) {
this.buscarCedula()
this.nombre = "Consultando cédula...";
}
}
},
methods: {
buscarCedula: _.debounce(function() {
axios.get('http://localhost/miapp/public/personas/mostrar')
.then(function(response) {
if (!response.data.error) {
return app.nombre = response.data;
} else {
return app.nombre = response.data.error;
}
})
.catch(function(error) {
app.nombre = error;
})
}, 500)
}
)};

Related

How to disable select option in Vuejs

Good day! I am new in Vuejs. Please help me.
I want to disable the select option after I select and set the select to default value.
for example
<select name="recipient" #change="changeFunc($event)">
<option>--Select--</option>
<option v-for="recipient in recipients" :key="recipient.id" :value="recipient.id" :disabled="recipient.disabled">{{ recipient.name }}</option>
</select>
export default {
data: function() {
return {
recipients: [
{'id':3, 'name':'aaa'},
{'id':5, 'name':'bbb'},
{'id':8, 'name':'ccc'}
],
}
},
method: {
changeFunc(e) {
//TODO disable the select value and set to default value
}
}
}
Please help how to do it. Thank you.
Try the following code
<select name="recipient" v-model="selected" #change="changeFunc($event)">
<option>--Select--</option>
<option v-for="recipient in recipients" :key="recipient.id" :value="recipient.id" :disabled="recipient.disabled">{{ recipient.name }}</option>
</select>
export default {
data: function() {
return {
selected: {},
recipients: [
{'id':3, 'name':'aaa', 'disabled': false},
{'id':5, 'name':'bbb', 'disabled': false},
{'id':8, 'name':'ccc', 'disabled': false}
],
}
},
method: {
changeFunc(e) {
const index = this.recepients.findIndex((el) =>{
if(el.id == this.selected){
return true;
}
});
if(index){
this.recepeints[index].disabled = true;
this.selected = "";
}
}
}
}
The changeFunc() find index of selected value and set disabled to true and reset selected value
You can achieve this with a simple approach by iterating the input array on option change.
this.recipients.forEach(obj => {
obj['disabled'] = (obj.id === this.recipient)
});
Live Demo :
new Vue({
el: '#app',
data: {
recipient: '',
recipients: [
{'id':3, 'name':'aaa'},
{'id':5, 'name':'bbb'},
{'id':8, 'name':'ccc'}
]
},
methods: {
changeFunc() {
this.recipients.forEach(obj => {
obj['disabled'] = (obj.id === this.recipient)
});
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select v-model="recipient" #change="changeFunc">
<option value="">--Select--</option>
<option v-for="recipient in recipients" :key="recipient.id" :value="recipient.id" :disabled="recipient.disabled">{{ recipient.name }}</option>
</select>
</div>

How to check if a laravel validator response is an error or not with Vue.js

I am using Laravel 7 and Vue.js 2.
I make a delete call with axios and if everything is correct I receive as a response the new data in the related tables to update a select and if there is an error I receive the errors of the Laravel validator.
The problem is that I have to understand with javascript if the response is an error or not... but I don't know how to do that.
This is my Vue component:
<template>
<form method="DELETE" #submit.prevent="removeTask">
<div class="form-group">
<title-form v-model="titleForm" :titleMessage="titleForm"></title-form>
</div>
<hr>
<div class="form-group">
<label for="tasks">Tasks:</label>
<select required v-model="user.tasks" class="form-control" id="tasks" #mouseover="displayResults(false, false)">
<option v-for="task in tasks_user" :value="task.id" :key="task.id">
{{ task.task_name }} - {{ task.task_description }}
</option>
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
<hr>
<div class="form-group">
<validated-errors :errorsForm="errors" v-if="displayErrors===true"></validated-errors>
<!--<success-alert :success_message="successMessage" v-if="displaySuccess===true"></success-alert>-->
</div>
</form>
</template>
<script>
import ValidatedErrors from "./ValidatedErrors.vue"
import SuccessAlert from "./SuccessAlert.vue"
import TitleForm from "./TitleForm.vue"
export default {
components: {
'validated-errors': ValidatedErrors,
'success-alert': SuccessAlert,
'title-form': TitleForm
},
mounted() {
console.log('Component mounted.');
},
props: {
tasks_user: {
type: Array,
required: true,
default: () => [],
}
},
computed: {
titleForm: function () {
return "Remove a task from " + this.tasks_user[0].user_name;
}
},
data: function() {
return {
user: {
tasks: ""
},
errors: {},
displayErrors: false,
displaySuccess: false,
successMessage: "The task has been removed."
}
},
methods: {
removeTask: function() {
alert(this.user.tasks);
//axios.delete('/ticketsapp/public/api/remove_task_user?id=' + this.user.tasks)
axios.delete('/ticketsapp/public/api/remove_task_user?id=' + 101)
.then((response) => {
console.log(response.data);
if(typeof response.data[0].task_id !== "undefined") {
alert("There are no errors.");
} else {
alert("There are errors.");
}
if (typeof response.data[0].task_id === "undefined") { //problem
alert('noviva');
console.log(response.data);
this.errors = response.data;
this.displayErrors = true;
} else {
alert('viva');
this.tasks_user = response.data;
this.errors = {};
}
})
.catch(error => {
alert(noooooo);
console.log(error);
});
},
displayResults(successShow, errorShow) {
this.displayErrors = errorShow;
this.displaySuccess = successShow;
}
},
}
</script>
This is my method in the controller:
public function remove(Request $request) {
$validator = Validator::make($request->all(), [
'id' => 'required|exists:task_user,id'
]);
if ($validator->fails()) {
return response($validator->errors()); //problem
}
$task_user_id = $request->id;
$user_id = TaskUser::where('id', $task_user_id)->pluck('user_id')->first();
TaskUser::find($task_user_id)->delete();
$tasks_user = TaskUser::with(['user', 'task'])->get();
$tasks_user = TaskUser::where('user_id', $user_id)->get();
$tasks_user = TaskUserResource::collection($tasks_user);
return json_encode($tasks_user);
}
To distinguish the type of return I created this condition: if (typeof response.data[0].task_id === "undefined") but when that condition is true everything falls down and I receive the following error in the console:
Uncaught (in promise) ReferenceError: noooooo is not defined
So how can I do to distinguish the type of return of the API call?

TypeError: _this2.categoryOptions.find is not a function

I'm trying to create a select option that will show the category when it's been saved. The problem I'm having is that I'm getting this error in my console
[Vue warn]: Error in render: "TypeError: _this2.categoryOptions.find is not a function"
Here is my code
<template>
<div>
<select class="form-control" v-model="addCategory" name="category">
<option v-for="category in categoryOptions" :value="category.id">{{ category.name }}</option>
</select>
</div>
</template>
<script>
export default {
props: ['product', 'categories'],
data() {
return {
addCategory: null,
categoryOptions: []
}
},
mounted() {
axios.get('/admin/products/'+this.product.id+'/category').then((response) => {
this.categoryOptions = response.data;
});
},
computed: {
categoryOptions(){
let options = [];
options.push({id:0, text: "Please select one"});
let filteredCategory = this.categories.filter(category => {
return this.categoryOptions.find(selected => categoryOptions.category_id === category.id) == null;
});
filteredCategory.forEach(sc => {
options.push({id: sc.id, text: sc.name});
});
return options;
}
},
}
</script>
Replace:
let filteredCategory = this.categories.filter(category => {
return this.categoryOptions.find(selected => categoryOptions.category_id === category.id) == null;
});
per
let filteredCategory = this.categories.filter(category => {
return this.categoryOptions.find(selected => selected.category_id === category.id) == null;
});
note that you just forgot to replace categoryOptions with selected. But to ensure that the component is loaded, I advise you to make the props categories required, and ensure that it is persisted for the component before rendering.
<script>
export default {
props: {
'product',
'categories': {
type: [Array, Object],
required: true,
},
},
...
}
</script>
Another tip if you use the chrome browser, is to use a very cool extension which is Vue.js devtools to follow the status of your application.

Laravel 5.7, Update <options> in a select drop-down with Vue

I'm writing my first Laravel Vue component and I have this error in console.
[Vue warn]: Computed property "options" was assigned to but it
has no setter.
The code is about two select dropdowns, one with continents and one with countries. I want that when I update the continent the countries get updated.
I just miss to update the options of the second select with the updated values that I have in this.countries.
After the continent change the this.countries variable get updated but the values of the options of the country_id select are not changing.
I've tried adding computed but I get this error.
What am I doing wrong?
<template>
<div>
<div class="form-group continent_id">
<select name="continent_id" v-model="continent_selected" id="continent_id" class="selectpicker" data-live-search="false" title="Pick a continent" v-on:change="getAllCountries(continents)">
<option v-if="continents.length>0" v-for="continent in continents" v-bind:value="continent.id">
{{ continent.name }}
</option>
</select>
</div>
<div class="form-group country_id">
<select name="country_id" v-model="country_selected" id="country_id" class="selectpicker" data-live-search="true" title="Pick a country">
<option v-for="(country, index) in countries" v-bind:value="country.id" >
{{ country.name }}
</option>
</select>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.');
this.loadData();
},
data() {
return {
continents: [],
countries: [],
continent_selected: '',
country_selected: '',
}
},
computed: {
get: function () {
return this.countries;
},
set: function (newValue) {
this.countries = newValue;
}
},
methods: {
loadData: function() {
axios.get('/api/continents')
.then((response) => {
// handle success
this.continents = response.data.data;
this.getAllCountries(this.continents);
})
.catch((error) => {
// handle error
console.log(error);
})
.then(() => {
// always executed
});
},
getAllCountries: function(continents) {
console.log(this.continent_selected);
console.log(continents);
var j = 0;
this.countries = [];
for (var i = 0, len = continents.length; i < len; i++) {
if (!this.continent_selected){
for (var key in continents[i].active_countries) {
this.countries[j] = {id: continents[i].active_countries[key], name: key};
j++;
}
}
else{
console.log("continent selected: "+ this.continent_selected);
for (var key in continents[i].active_countries) {
if (continents[i].id == this.continent_selected){
this.countries[j] = {id: continents[i].active_countries[key], name: key};
j++;
}
}
}
}
}
},
}
</script>
I have solved my issue that was mainly related to the computed set method of the variable optionCountries.
The dropdown was not updating because it use Bootsrap Select, so in order to show the new options it needs to be refreshed.
I've also figure out that I need to add a timeout to the refresh request.
This is the final code.
<template>
<div>
<div class="form-group continent_id">
<select name="continent_id" v-model="continent_selected" id="continent_id" class="selectpicker" data-live-search="false" title="Pick a continent" v-on:change="getAllCountries(continents)">
<option v-if="continents.length>0" v-for="continent in continents" v-bind:value="continent.id">
{{ continent.name }}
</option>
</select>
</div>
<div class="form-group country_id">
<select name="country_id" v-model="country_selected" id="country_id" class="selectpicker" data-live-search="true" title="Pick a country">
<option v-for="(country, index) in optionCountries" v-bind:value="country.id" >
{{ country.name }}
</option>
</select>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.');
this.loadData();
},
data() {
return {
continents: [],
countries: [],
continent_selected: '',
country_selected: '',
}
},
computed: {
optionCountries:{
get: function () {
return this.countries;
},
set: function (newValue) {
this.countries = newValue;
setTimeout(() => {
jQuery('.selectpicker').selectpicker('refresh');
}, 500);
}
}
},
methods: {
loadData: function() {
axios.get('/api/continents')
.then((response) => {
// handle success
this.continents = response.data.data;
this.getAllCountries(this.continents);
})
.catch((error) => {
// handle error
console.log(error);
})
.then(() => {
// always executed
});
},
getAllCountries: function(continents) {
var j = 0;
this.countries = [];
for (var i = 0, len = continents.length; i < len; i++) {
if (!this.continent_selected){
for (var key in continents[i].active_countries) {
this.countries[j] = {id: continents[i].active_countries[key], name: key};
j++;
}
}
else{
for (var key in continents[i].active_countries) {
if (continents[i].id == this.continent_selected){
this.countries[j] = {id: continents[i].active_countries[key], name: key};
j++;
}
}
this.optionCountries = this.countries;
}
}
}
},
}
</script>
In this line you are setting the value of options attribute:
this.options = this.options;
, but, this property is computed:
computed: {
options: function(event) {
return this.countries
}
},
In this case you can:
create a computed setter: https://v2.vuejs.org/v2/guide/computed.html#Computed-Setter
computed: {
options: {
get: function () {
return this.countries;
},
set: function (newValue) {
this.countries = newValue;
}
}
},
Set the value directly:
this.countries = this.options;

Get Double values from my Select Form using Vuejs

I put here a picture to see my Vue App.
In my Select form, i have two values :
-$keys which get me the amout referenced to my id
-$values which get me the ID in my options.
I wrote my code like that :
<select data-validation="number" class="form-control" style="width:200px" v-model="cash.bank">
#foreach ($users as $keys => $values)
<option value="{{ $keys }}" > {{ $values }}</option>
#endforeach
</select>
My v-model=cash.bank return the value of $keys. i need to return also for cash.id the value of $value.
My double post and put function script :
addCash: function () {
axios.post('/addglentrycash', this.cash)
.then(response => {
console.log(response.data);
if (response.data.etat) {
this.cash = {
id: 0,
codeentry: response.data.etat.codeentry,
description: response.data.etat.description,
cash: response.data.etat.cash,
};
}
})
.catch(error => {
console.log('errors: ', error)
})
updateBank:function(){
axios.put('/updatebank', this.cash)
.then(response => {
if (response.data.etat) {
this.cash = {
id: (I need to write something)
cash: response.data.etat.cash,
bank:response.data.etat.bank,
};
}
})
.catch(error => {
console.log('errors: ', error)
})
},
This is my vue app :

Resources