Use props with forEach in vuejs - javascript

I'm desperately trying to use my props 'datas' with a foreach.
When I put my data in a "test" data, it works.
Example :
data() {
return {
postForm: this.$vform({}),
test: [{"name":"Couleur yeux","id":3,"answer":null},{"name":"Hanches","id":6,"answer":"'Test'"}],
}
},
computed: {
},
methods: {
createForm() {
this.test.forEach((data) => {
if (data.answer) {
this.$set(this.postForm, data.id, data.answer)
}
})
}
},
But if I use my props directly, it doesn't work. I have a message "this.datas.forEach is not a function".
But my props has exactly the same data and the same structure as my "test" data.
Don't work:
this.datas.forEach((data) => {
if (data.answer) {
this.$set(this.postForm, data.id, data.answer)
}
})
I also tried to transform my props into data() but it doesn't work
data() {
return {
postForm: this.$vform({}),
test: this.datas
},

"this.datas.forEach is not a function"
This mean that datas is not an Array instance because forEach is method from array prototype.

Right now, this.datas does not exist. You never give this the state with the key datas.
It looks like you're trying to go through this.test, which is an array of objects. Is that right?
If that's the goal, you can do so:
data() {
return {
postForm: this.$vform({}),
test: [{"name":"Couleur yeux","id":3,"answer":null},{"name":"Hanches","id":6,"answer":"'Test'"}],
}
},
methods: {
createForm() {
let arrayOfAnswers = []
this.test.forEach((data) => {
if (data.answer) {
arrayOfAnswes.push(data.answer)
}
})
this.arrayOfanswers = arrayOfAnswers
}
},

Related

Convert api response array to another array to pass to Vue prop

I want to use this vue flipbook component and it needs a array of image urls for the prop "pages". My posts response is coming from the wordpress rest api.
I need to get the "image" property from the response array and convert it into another array of image urls. Normally I would use the posts() in computed like v-for=post in posts in my template and display the image like post.image_full in the loop..
Flipbook component:
<Flipbook
class="flipbook"
:pages="imagesArray" <--- images array here
v-slot="flipbook"
ref="flipbook"
>
</Flipbook>
My Posts.vue component:
export default {
name: 'GridOne',
props: {
page: {
type: Number,
required: true
}
},
data() {
return {
request: {
type: 'posts',
params: {
per_page: this.$store.state.site.posts_per_page,
page: this.page
},
showLoading: true
},
totalPages: 0
}
},
computed: {
posts() {
return this.$store.getters.requestedItems(this.request) <--- my response array
}
},
methods: {
getPosts() {
return this.$store.dispatch('getItems', this.request)
},
setTotalPages() {
this.totalPages = this.$store.getters.totalPages(this.request)
}
},
created() {
this.getPosts().then(() => this.setTotalPages())
}
}
You can use JavaScript "map" function. This function takes one array and return a new one.
// If this is the response array....
const response = [{name: 'image 1', url: 'https://uri.com/img1'}, ...]
// Then you return something like this
response.map(item => {
return {
...item,
image_full: item.url
}
})

Use object properties as parameters to GET request

Right now I have this two components:
pesquisar.vue
form.mb-3(#submit.prevent="getPessoaFisica(object)")
Search(:object='object')
button.btn.btn-sm.btn-success.d-none(type="submit")
.fa.fa-search
...
data() {
return {
object: {
Cd_Pessoa: null,
Nm_Pessoa: null,
Nm_Apelido: null,
Nr_Documento: null,
Nm_Officer: null,
Tp_Registro: null,
Cd_TipoID: null,
},
page: undefined,
list: undefined,
};
},
methods: {
getPessoaFisica(obj, page = 1, count = 18) {
this.$axios
.get("/pessoaFisica", {
params: {
obj,
page,
count
}
})
.then(res => {
this.list = res.data;
});
}
},
search.vue
<template lang="pug">
.row(#input="$emit('input', object)")
.col-md-4.mb-1(v-for='property in Object.keys(object)')
.row
.col-auto.pr-0 {{property}}:
.col
input.form-control.form-control-sm.py-0(v-model='object[property]')
</template>
<script>
export default {
props: ['object']
}
</script>
I'm using the object object in pesquisar.vue to dynamically create inputs in my view.
When I submit the form with random data, I'm getting this request:
http://localhost/abc?obj=%7B%22Cd_Pessoa%22:null,%22Nm_Pessoa%22:%22her%22,%22Nm_Apelido%22:null,%22Nr_Documento%22:null,%22Nm_Officer%22:null,%22Tp_Registro%22:null,%22Cd_TipoID%22:null%7D&page=1&count=18
What I really wanted was this:
http://localhost/abc?Nm_Pessoa:"her"&page=1&count=18
Basically what I wanted was to use the object properties as parameters to GET request.
Any help, please?
Try spreading the object properties using the object spread operator ...obj:
// ...
this.$axios
.get("/pessoaFisica", {
params: {
...obj,
page,
count
}
})
.then(res => {
this.list = res.data;
});

Vue.js. Data property undefined

I'm trying to access my data property in my Vue.js component. Looks like I'm missing something obvious.
Here is a short version of my code. StoreFilter.vue is a wrapper for matfish2/vue-tables-2.
<template>
<store-filter :selected.sync="storeIds"></store-filter>
</template>
<script>
import StoreFilter from './Filters/StoreFilter';
export default {
components: {
StoreFilter
},
data() {
return {
options : {
requestFunction(data) {
console.log(this.storeIds); //undefined
return axios.get('/api/orders', {
params: data
}).catch(function (e) {
this.dispatch('error', e);
}.bind(this));
},
},
storeIds: [],
}
},
watch : {
storeIds(storeIds) {
this.refreshTable();
}
},
methods : {
refreshTable() {
this.$refs.table.refresh();
}
}
}
</script>
How to get storeIds from requestFunction?
Use a closure, see rewrite below.
data() {
let dataHolder = {};
dataHolder.storeIds = [];
dataHolder.options = {
requestFunction(data) {
// closure
console.log(dataHolder.storeIds); // not undefined
return axios.get('/api/orders', {
params: data
}).catch(function (e) {
this.dispatch('error', e);
}.bind(this));
}
}
return dataHolder;
}
I recommend using the created() way to handle this.
export default {
// whatever you got here
data () {
return {
options: {}
}
},
created () {
axios.get('/api/orders', { some: params }).then(response => this.options = response.data)
}
}

Vue v-for on first item containing property X call a method

Let's say I have a component which repeats with a v-for loop like so:
<hotel v-for="(hotel, index) in hotels"></hotel>
And my hotels array would look like so:
[
{
name: false
},
{
name: false
},
{
name: true
},
{
name: true
}
]
How could I perform an action when my v-for loop encounters the property name set to true only on the very first time it encounters this truthy property?
I know I could probably cache a property somewhere and only run something once and not run again if it has been set but this does not feel efficient.
Use a computed to make a copy of hotels where the first one has an isFirst property.
computed: {
hotelsWithFirstMarked() {
var result = this.hotels.slice();
var first = result.find(x => x.name);
if (first) {
first.isFirst = true;
}
return result;
}
}
Just use computed source
HTML
<div v-for="(hotel, index) in renderHotels"></div>
JS
export default {
name: 'message',
data () {
return{
hotels:[
{
name: false
},
{
name: false
},
{
name: true
},
{
name: true
}
] ,
wasFirst : false
}
},
methods:{
},
computed:{
renderHotels(){
return this.hotels.map((hotel)=>{
if(hotel.name && !this.wasFirst){
this.wasFirst = true;
alert('First True');
console.log(hotel);
}
})
}
}
}
Best way is to use filter function.
data() {
return {
firstTime: false,
};
},
filters: {
myFunc: function (hotel) {
if (hotel.name && !this.firstTime) {
//perform some action
this.firstTime = true;
}
}
}
<hotel v-for="(hotel, index) in hotels | myFunc"></hotel>

Update data property / object in vue.js

is there a way I can programmatically update the data object / property in vue.js? For example, when my component loads, my data object is:
data: function () {
return {
cars: true,
}
}
And after an event is triggered, I want the data object to look like:
data: function () {
return {
cars: true,
planes: true
}
}
I tried:
<script>
module.exports = {
data: function () {
return {
cars: true
}
},
methods: {
click_me: function () {
this.set(this.planes, true);
}
},
props: []
}
</script>
But this gives me the error this.set is not a function. Can someone help?
Thanks in advance!
Vue does not allow dynamically adding new root-level reactive properties to an already created instance. However, it’s possible to add reactive properties to a nested object, So you may create an object and add a new property like that:
data: function () {
return {
someObject:{
cars: true,
}
}
and add the property with the vm.$set method:
methods: {
click_me: function () {
this.$set(this.someObject, 'planes', true)
}
}
for vue 1.x use Vue.set(this.someObject, 'planes', true)
reactivity

Categories