Vuejs2 - How to compare elements in two array with computed properties? - javascript

I'm working on a computed function for comparing two arrays... one keywords in data and another returned by computed keywords_list. When computed compare, he doesn't take in count values getting before by Axios in the first array ...
I don't know what to do ...
my code:
{
beforeCreate() {
this.$axios({
method: 'get',
url: '/api/rest/alerts/'
}).then(response => {
if ((response.data.keywords.length == 0) && (response.data.countries.length == 0)) {
this.alertEmpty = 'Aucune alerte de créée'
} else {
this.alert = response.data
this.keywords = response.data.keywords
this.countriesKeywords = response.data.countries
this.allSectorsSelected = response.data.all_sectors
}
})
},
data() {
return {
categories: "",
alert: '',
alertEmpty: '',
countriesKeywords: [],
countrySelected: '',
keywords: [],
update: false,
sectorSelected: "",
alerts: [],
keywordSelected: "",
errorKeyword: '',
successModification: '',
allSectorsSelected: null,
};
},
computed: {
keywords_list: function() {
for (var i = 0; i < this.sectors.length; i++) {
if (this.sectors[i].id == this.sectorSelected) {
return this.sectors[i].keywords;
}
}
},
allKeywordsInSector: function() {
if (this.keywords_list.every(item => this.keywords.indexOf(item) >= 0)) {
return true;
}
return false;
},
}
}
thanks for your help

very little information and it is unclear how the api result affects your computed values
The only thing i can say, properties in Vue doesn't reactive. So if sections isn't static, computed property sectorSelected will change only if sectorSelected changes
https://v2.vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

Related

How does if else works?

I'm trying to figure out where my problem comes from in my algorithm.
I am trying to give the information about the connection status of a data sender with its data table.
I have translated it like this:
if new data is received ( new_id different from id_from_last_request) then I set the connection status to "connected" otherwise I set it to "disconnected"
<script>
export default {
data() {
return {
search: '',
tag_id: ['bts_d02c2b7d9098aaa2', 'bts_c077ffaa9098aaa2'],
headers: [
{
text: 'Tags',
align: 'start',
sortable: false,
value: 'name',
},
{ text: 'wifi', value: 'wifi' },
],
val_ia: 0,
desserts: [],
id_memory: [],
}
},
mounted() {
this.CreateTable();
setInterval(this.getDatafor, 1000)
},
methods: {
CreateTable() {
for (let i = 0; i < this.tag_id.length; i++) {
this.desserts.push(
{
name: this.tag_id[i],
},
)
}
},
async getDatafor() {
for (let i = 0; i < this.desserts.length; i++) {
this.val_ia = i;
await Promise.all([this.getAllData()]);
}
},
async getAllData() {
const tag_id_name = encodeURIComponent(this.tag_id[this.val_ia]);
const url = this.$api.getRESTApiUri() + `/all/last_id/${tag_id_name}`;
return fetch(url)
.then(res => res.text())
.then((result) => {
console.log(tag_id_name)
console.log(this.id_memory[this.val_ia]);
console.log(data[0].id)
const b = this.Test(this.id_memory[this.val_ia], data[0].id);
console.log(b)
if(b){
this.desserts[this.val_ia].wifi = 'connecté'
console.log('connecté')
}else{
this.desserts[this.val_ia].wifi = 'déconnecté'
console.log('déconnecté')
}
this.id_memory[this.val_ia] = data[0].id
})
.catch((error) => {
console.log(error)
});
},
Test(x, y) {
const a = x !== y
return a
},
}
}
</script>
Only in case I have no new data
const b = false
here is my console:
I should have the disconnected status only it shows me the connected status
There should be a logical explanation to it but I can't see it..
You are using equality without type coersion (x !== y) in your Test method.
Probably this.id_memory[this.val_ia] and data[0].id have different types - one is number, second one is string or otherwise.
The best solution is to convert those values to the same type before comparing like so:
Test(x,y){
return String(x) !== String(y)
}
Some use cases:
'123' === 123 // false
'123' == 123 // true
When creating my table, I forgot to push variables wifi and bluetooth so they did not update themselves.
CreateTable(){
for(let i = 0; i < this.tag_id.length; i++){
this.desserts.push(
{
name: this.tag_id[i],
wifi: 'déconnecté',
bluetooth: 0,
tension: 0,
courant: 0,
temperature: 0,
acceléromètre: 0,
pression_sys: 0,
pression_dias: 0,
frequence_cardiaque: 0,
taux_oxygène: 0,
},
)
}
},

Vue infinite UI update loop with function as param

I'm new in Vue.js and tried to convert some legacy code for pagination. I've created a pager component which accepts a function as one of its params. But it's causing an infinite UI render loop.
Could you help me to resolve or suggest some solution for such problem?
Here is my pager component js:
const PagerComponent = {
name: "pagerComponent",
template: "#pagerComponent",
props: {
pageSize: Number,
pageIndex: Number,
totalPages: Number,
totalRecords: Number,
pageSlide: Number,
hasNextPage: Boolean,
hasPrevPage: Boolean,
pages: Array,
loadFunc: Function
},
data() {
return {
pager: {
pageSize: 0,
pageIndex: 0,
totalPages: 0,
totalCount: 0,
pageSlide: 1,
hasNextPage: false,
hasPrevPage: false,
pages: [],
loadFunc: function () { }
}
}
},
methods: {
load(index) {
this.pager.pageIndex = index;
if (this.pager.loadFunc != null) {
this.pager.loadFunc();
}
},
isActivePage(page) {
return this.pager.pageIndex + 1 == page;
},
update(newPager) {
this.pager.pageSize = newPager.pageSize;
this.pager.pageIndex = newPager.pageIndex;
this.pager.totalPages = newPager.totalPages;
this.pager.totalCount = newPager.totalCount;
this.pager.hasNextPage = newPager.hasNextPage;
this.pager.hasPrevPage = newPager.hasPrevPage;
this.generatePages();
},
generatePages() {
this.pager.pages = [];
var pageNum = this.pager.pageIndex + 1;
var pageFrom = Math.max(1, pageNum - this.pager.pageSlide);
var pageTo = Math.min(this.pager.totalPages, pageNum + this.pager.pageSlide);
pageFrom = Math.max(1, Math.min(pageTo - this.pager.pageSlide, pageFrom));
pageTo = Math.min(this.pager.totalPages, Math.max(pageFrom + this.pager.pageSlide, pageNum == 1 ? pageTo + this.pager.pageSlide : pageTo));
for (var i = pageFrom; i <= pageTo; i++) {
this.pager.pages.push(i);
}
}
},
computed: {
hasPages() {
if (this.pager.pages == null)
return false;
return this.pager.pages.length > 0;
},
doNotHavePrevPage() {
return !this.pager.hasPrevPage;
},
doNotHaveNextPage() {
return !this.pager.hasNextPage;
}
},
beforeMount() {
this.pager.pageSize = this.pageSize;
this.pager.pageIndex = this.pageIndex;
this.pager.totalPages = this.totalPages;
this.pager.totalCount = this.totalRecords;
this.pager.hasNextPage = this.hasNextPage;
this.pager.hasPrevPage = this.hasPrevPage;
this.pager.loadFunc = this.loadFunc;
this.pager.pages = this.pages || [];
this.generatePages();
},
mounted() {
}
}
Here is how it's used in html:
<pager-Component v-bind="Pager" v-bind:load-Func="GetItems" ref="pager"></pager-Component>
And GetItems funciton:
function () {
var self = this;
const data = {
Pager: self.Pager,
Filter: []
};
$.ajax({
url: self.GetItemsUrl,
type: "POST",
dataType: "json",
busy: self.Loading,
data: data
}).done(function (result) {
if (result.isSuccess) {
self.$refs.pager.update(result.data.pager);
self.Items.splice(0);
result.data.items.map(function (value, key) {
self.Items.push(value);
});
}
else {
alert(result.data.errors[0]);
}
});
}
Finally after tones of tests, the solution was found and it's pretty easy.
I just needed to use v-on:click instead of :click. I just don't know why lot of tutorials suggest to use :click if it doesn't work
So for example use
<div v-on:click="load(pageIndex)">My button</div>
instead of
<div :click="load(pageIndex)">My button</div>

Vue data not updated in created()

I'm trying to transform an API response into a more useful form for building two tables. When I add debugging outputs inside my function in created(), I can see the desired output, but examining the data after the fact, it seems to have not changed. I suspect that something weird is happening with this, but I can't seem to sort it out.
Here's what I have so far:
export default {
name: 'component',
data: function() {
return {
tableOne: [],
}
},
computed: {
...mapState([
'modal'
])
},
created() {
api.get_appointments()
.then(appointments => {
for (var i = 0; i < appointments.length; i++) {
this.tableOne.push(
{
tech: appointments[i].tech_name,
date: appointments[i].scheduled_date
}
)
}
});
},
};
api.get_appointments() includes the following:
get_appointments() {
return axios({
method: "get",
url: '/appointments'
})
.then(res => (res.data.data))
.catch(error => {return error});
};
Since it's doing a request hit..the second console prints before the request is resolved. Try using async-await
async created() {
await api.get_appointments()
.then(appointments => {
for (var i = 0; i < appointments.length; i++) {
this.tableOne.push(
{
tech: appointments[i].tech_name,
date: appointments[i].scheduled_date
}
)
}
// console.log(this.tableOne);
});
// console.log(this.tableOne);
},

List sorting method not updating order

I'm trying to get some insight into why this sort function isn't working.
In theory, it should work the same as this: https://codepen.io/levit/pen/abmXgBR
I have a list I'm grabbing from an API:
<BookCard v-for='book in filteredBooks' :key='book.id' :book='book' />
I've got a filter for search working, but my sort isn't. Here is my data with computed properties/methods:
data() {
return {
books: [],
order: 1, // Ascending
search: '',
};
},
computed: {
filteredBooks() {
return this.filterBySearch((this.sortByRating(this.books)));
},
},
methods: {
filterBySearch(books) {
return books.filter((book) => book.volumeInfo.title
.toLowerCase().match(this.search.toLowerCase()));
},
sortByRating(books) {
return books
.sort((r1, r2) => (r2.volumeInfo.averageRating - r1.volumeInfo.averageRating)
* this.order);
},
sort() {
this.order *= -1;
},
},
Finally, I have a button to switch the order:
<button v-bind:class="order === 1 ? 'descending' : 'ascending'" #click="sort">
Reader Rating
</button>
Any insight into what I might be getting wrong would be very helpful as I'm new to Vue.
Thank you.
Try to not pass the data property as an argument since it's available inside the methods and just sort the filtered books not the original property because the sort affects it :
computed: {
filteredBooks() {
let filtered= this.filterBySearch().slice();
return this.sortByRating(filtered)
},
},
methods: {
filterBySearch() {
return this.books.filter((book) => book.volumeInfo.title
.toLowerCase().match(this.search.toLowerCase()));
},
sortByRating(books) {
return books.sort((r1, r2) => {
if (
typeof r2.volumeInfo.averageRating === "number" &&
typeof r1.volumeInfo.averageRating === "number"
) {
return (
(r2.volumeInfo.averageRating - r1.volumeInfo.averageRating) *
this.order
);
} else {
return this.order * -1;
}
});
},
sort() {
this.order *= -1;
},
},

multiple if condition in for statement for vue.js state management to get data and return

I am using state management in vue.js for fetching products. i am fetching products with ID from data base. i need to make two conditions for return if $state has already products.
first condition is if $state.products has any products than make it return, and
second condition if one ID is passed and related date according to ID is fetched, if again same ID is passed it will return value.
but i am confused how to set condition for multiple match. i also tried logical AND operator for this, but nothing work.
please help me to solve this.
Here is my code.
Product.vue
mounted () {
this.$store.dispatch("loadProducts",this.category);
},
computed:{
...mapState([
'products'
])
},
this is my file where i am handling state management for fetching products.
index.js
const store = new Vuex.Store({
state: {
pageTitle: '',
products: [],
},
mutations: {
setTitle(state, title) {
state.pageTitle = title;
}
},
actions: {
loadProducts({ commit }, id) {
if (this.state.products.length != 0) {
var i;
for (i = 0; i < this.state.products.length; i++) {
var j = this.state.products[i].category_id;
}
} else if (this.state.products.length != 0 && id == j) {
console.log("RETURN");
return;
} else {
axios.get('/loadProducts/' + id)
.then(({ data }) => {
this.state.products = data.items;
console.log(this.state.products);
commit('set_products', data.items)
})
}
},
},
mutations: {
set_products(state, products) {
state.products = products;
}
}
});

Categories

Resources