link548 link549 link550 link551 link552 link553 link554 link555 link556 link557 link558 link559 link560 link561 link562 link563 link564 link565 link566 link567 link568 link569 link570 link571 link572 link573 link574 link575 link576 link577 link578 link579 link580 link581 link582 link583 link584 link585 link586 link587 link588 link589 link590 link591 link592 link593 link594 link595 link596 link597 link598 link599 link600 link601 link602 link603 link604 link605 link606 link607 link608 link609 link610 link611 link612 link613 link614 link615 link616 link617 link618 link619 link620 link621 link622 link623 link624 link625 link626 link627 link628 link629 link630 link631 link632 link633 link634 link635 link636 link637 link638 link639 link640 link641 link642 link643 link644 link645 link646 link647 link648 link649 link650 link651 link652 link653 link654 link655 link656 link657 link658 link659 link660 link661 link662 link663 link664 link665 link666 link667 link668 link669 link670 link671 link672 link673 link674 link675 link676 link677 link678 link679 link680 link681 link682 link683 link684

[Vue.js] How can I filter a VueJS loop by using checkboxes to show different results?For multiple items Working Example Based On Your Posted Code.

when having trouble with applying filters whilst using checkboxes to a list of results and need some help.

Currently, only the ‘All’ option seems to apply any filtering logic.

My HTML containing my filters and loop is as follows:

<div class=”container” id=”clubs”>
<div class=”filter”>
<label><input type=”checkbox” v-model=”selectedCategory” value=”All” /> All</label>
<label><input type=”checkbox” v-model=”selectedCategory” value=”Parking” /> Parking</label>
<label><input type=”checkbox” v-model=”selectedCategory” value=”Toilets” /> Toilets</label>
<label><input type=”checkbox” v-model=”selectedCategory” value=”Floodlights” /> Floodlights</label>
</div>

<ul class=”clubs-list”>
<li v-for=”club in filteredClubs”>{ club.clubName }</li>
</ul>
</div>

Then, the code inside my VueJS app is as below:

var vm = new Vue({
el: “#clubs”,
data: {
clubs: [
{ clubName: “Club One”, clubParking: true, clubToilets: false, clubFloodlights: true },
{ clubName: “Club Two”, clubParking: true, clubToilets: false, clubFloodlights: false },
{ clubName: “Club Three”, clubParking: false, clubToilets: true, clubFloodlights: true },
],
selectedCategory: “All”
},
computed: {
filteredClubs: function() {
var vm = this;
var category = vm.selectedCategory;

if(category === “All”) {
return vm.clubs;
} else {
return vm.clubs.filter(function(club) {
return club.clubParking === category;
});
}
}
}
});

Any help welcome as there is been stuck for hours.

Solution :

You need to update the filter to check the category, then filter on the field.

return vm.clubs.filter(function(club) {
switch(category){
case ‘Toilets’:
return club.clubToilets;
case ‘Parking’:
return club.clubParking;
// etc…
}
});

You can refactor this a bit by setting a field name.

return vm.clubs.filter(function(club) {
let fname;
switch(category){
case ‘Toilets’:
fname =’clubToilets’;
case ‘Parking’:
fname = ‘clubParking’;
// etc…
}
return club[fname]
});

You can also simply have the value of the select be the field name and use it directly. This may restrict you from additional logic however.

<label><input type=”checkbox” v-model=”selectedCategory” value=”clubParking” /> Parking</label>

return vm.clubs.filter(function(club) {
return club[category];
}

The bottom line is the category must be mapped to a field name in the object.

For multiple items:

// Map the field names depending on the checkbox values. `selectedCategory` should be an array.

const selectedFieldNames = selectedCategory.map(category=>{
switch(category){
case ‘Toilets’:
return ‘clubToilets’;
case ‘Parking’:
return ‘clubParking’;
// etc…
}
})

// selectedFieldNames now contains the names of the object fields

// This will now return all items that have all those fields set to ‘true’
return vm.clubs.filter(function(club) {
return selectedFieldNames.every(fname=>club[fname])
}

Working Example Based On the Posted Code.

Note: This really could use some cleaning up, but I left it in a format that you can compare the work and ours.

var vm = new Vue({
el: “#clubs”,
data: {
clubs: [
{
clubName: “Club One”,
clubParking: true,
clubToilets: false,
clubFloodlights: true
},
{
clubName: “Club Two”,
clubParking: true,
clubToilets: false,
clubFloodlights: false
},
{
clubName: “Club Three”,
clubParking: false,
clubToilets: true,
clubFloodlights: true
}
],
selectedCategory: []
},
computed: {
filteredClubs: function() {
var vm = this;
var categories = vm.selectedCategory;

if (categories.includes(“All”)) {
return vm.clubs;
} else {
const selectedFieldNames = categories.map(category => {
switch (category) {
case “ClubToilets”:
return “clubToilets”;
case “ClubParking”:
return “clubParking”;
case “ClubFloodlights”:
return “clubFloodlights”;
}
});

return vm.clubs.filter(function(club) {
return selectedFieldNames.every(fname=>club[fname])
})
}
}
}
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class=”container” id=”clubs”>
<div class=”filter”>
<label><input type=”checkbox” v-model=”selectedCategory” value=”All” /> All</label>
<label><input type=”checkbox” v-model=”selectedCategory” value=”ClubParking” /> Parking</label>
<label><input type=”checkbox” v-model=”selectedCategory” value=”ClubToilets” /> Toilets</label>
<label><input type=”checkbox” v-model=”selectedCategory” value=”ClubFloodlights” /> Floodlights</label>
</div>

<ul class=”clubs-list”>
<li v-for=”club in filteredClubs”>{ club.clubName }</li>
</ul>
</div>

[Vue.js] Nuxt.js router doesn't seem to load the correct component

We are trying out Nuxt.js for an app am having a bit of a problem getting their router to load the correct component. there is structured our directory to generate the following:

path: “/articles/:id?”,
component: _241eccb7,
name: “articles-id”,
children: [{
path: “edit”,
component: _4bdace12,
name: “articles-id-edit”
}]
}, {

The issue is that the articles-id-edit never get invoked. For articles/123, the article-id route is invoked and associated component. For articles/123/edit, the article-id route is invoked and the same component when I’d expect the article-id-edit route to be invoked with its corresponding component.

What am I not understanding? What would be a decent way to debug this (like rake routes in Rails or something). Is there a way I can make more explicit my routes rather than automagically creating?

Solution :

Is the file structure set up properly? Per the docs:

To define the parent component of a nested route, you need to create a
vue.js file with the same name as the directory which contain your
children views.

https://nuxtjs.org/guide/routing#nested-routes

[Vue.js] Is it possible to call a REST API on vuetify datatable on data loading, searching, paging and sorting?

when using the datatable from vuetify

when wondering whether on this example there is something that can be done to call a REST api to perform the different operations instead of having everything in-memory when the table is loading data, paging, searching or sorting data?

The html:

<div id=”app”>
<v-app id=”inspire”>
<v-card>
<v-card-title>
Nutrition
<v-spacer></v-spacer>
<v-text-field
v-model=”search”
append-icon=”search”
label=”Search”
single-line
hide-details
\></v-text-field>
</v-card-title>
<v-data-table
:headers=”headers”
:items=”desserts”
:search=”search”
\>
<template v-slot:items=”props”>
<td>{ props.item.name }</td>
<td class=”text-xs-right”>{ props.item.calories }</td>
<td class=”text-xs-right”>{ props.item.fat }</td>
<td class=”text-xs-right”>{ props.item.carbs }</td>
<td class=”text-xs-right”>{ props.item.protein }</td>
<td class=”text-xs-right”>{ props.item.iron }</td>
</template>
<template v-slot:no-results>
<v-alert :value=”true” color=”error” icon=”warning”>
the search for “{ search }” found no results.
</v-alert>
</template>
</v-data-table>
</v-card>
</v-app>
</div>

The javascript:

new Vue({
el: ‘#app’,
data () {
return {
search: ‘’,
headers: [
{
text: ‘Dessert (100g serving)’,
align: ‘left’,
sortable: false,
value: ‘name’
},
{ text: ‘Calories’, value: ‘calories’ },
{ text: ‘Fat (g)’, value: ‘fat’ },
{ text: ‘Carbs (g)’, value: ‘carbs’ },
{ text: ‘Protein (g)’, value: ‘protein’ },
{ text: ‘Iron (%)’, value: ‘iron’ }
],
desserts: [
{
name: ‘Frozen Yogurt’,
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: ‘1%’
},
{
name: ‘Ice cream sandwich’,
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: ‘1%’
},
{
name: ‘Eclair’,
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: ‘7%’
},
{
name: ‘Cupcake’,
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: ‘8%’
},
{
name: ‘Gingerbread’,
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
iron: ‘16%’
},
{
name: ‘Jelly bean’,
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
iron: ‘0%’
},
{
name: ‘Lollipop’,
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
iron: ‘2%’
},
{
name: ‘Honeycomb’,
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
iron: ‘45%’
},
{
name: ‘Donut’,
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
iron: ‘22%’
},
{
name: ‘KitKat’,
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
iron: ‘6%’
}
]
}
}
})

Solution :

If I understand correctly, pagination.sync is what you are looking for

Basically, there are three key parts:

1) Add a pagination obj to data and a watcher:

watch: {
pagination: {
handler() {
this.fetchDesserts();
},
deep: true
}
},

and in data:

pagination: {
rowsPerPage: 100,
descending: false,
sortBy: “name”,
page: 1
},

2) Preload the desserts from memory or api:

mounted() {
this.fetchDessert();
}

3) update the datatable props to include pagination.sync, total-items and display pagination:

:headers=”headers”
:items=”desserts”
:pagination.sync=”pagination”
:rows-per-page-items=”rowsPerPageItems”
:total-items=”totalItems”

Here is an update codepen, that shows the general idea and includes the use of search:
https://codepen.io/retrograde/pen/pmzQNP?editors=1010

[Vue.js] Vuex Action - Returning Axios return Error

vue.jsx Action - Returning Axios return Error.

What am I doing wrong that the promise is not returning the correct values?

Someone could help with this doubt.

to display the error message behind the server.

From now on when very grateful for the attention.
Thank you.

Component

<q-form
@submit=”onSubmit”
@reset=”onReset”
\>
<q-input outlined v-model=”username” label=”User” />
<br>
<q-input outlined v-model=”password” type=”password” label=”Pass” />
<br>
<q-btn unelevated type=”submit” color=”primary full-width” label=”Enter” />
</q-form>

methods: {
…mapActions(‘auth’, [‘login’]),
onSubmit () {
this.login({ ‘username’: this.username, ‘password’: this.password }).then(obj => {
console.log(obj)
}).catch(obj => {
console.log(obj)
})
}
}

function login ({ commit, state, getters }, data) {
return axios.post(`/api/token`, {
username: data.username,
password: data.password
})
.then(response => {
commit(‘setToken’, response.data)
})
.catch(error => {
return error
})
}

POST http://localhost/api/token 400 (Bad Request)

Solution :

You need to define the function instead of pasting it directly into the methods object:

methods: {
…mapActions(‘auth’, [‘login’]),
myLogin() {
this.login({ ‘username’: this.username, ‘password’: this.password }).then(obj => {
console.log(obj)
}).catch(obj => {
this.error = obj;
})
},
}

Also, you are mapping an action of the same name: login, so you would need to change the local method to a different name, which is why I called it myLogin.

Create a data property called error and use: { error } in the component where you intend to show the error.

[Vue.js] Vue-bootstrap nav link to 'external application'

there is an application I decide to use vue-bootstrap over just bootstrap for the added features like tabs. Since I already have vue-bootstrap in the project, I decided to also rewrite the nav into it. Right now there is a problem where the links in the navigation point to the correct URL, however when I click them, nothing happens. I suspect vue.js internally takes control over the request to follow the link.

there is the following code in Latte templating language:

<nav class=”navbar navbar-expand-lg navbar-dark bg-dark fixed-top”>
<div>
<b-nav n:if=”$menu->hasVisibleItemsOnMenu()”>
{foreach $menu->getVisibleItemsOnMenu() as $itemsParent}
{if $itemsParent->hasVisibleItemsOnMenu() === false}
<b-nav-item n:attr=”active => $itemsParent->isActive()”>
<a href=”{$itemsParent->getRealLink()}”>{$itemsParent->getRealTitle()}</a>
</b-nav-item>
{else}
<b-nav-item-dropdown
text=”{$itemsParent->getRealTitle()}”
extra-toggle-classes=”nav-link-custom”
right
\>
{foreach $itemsParent->getVisibleItemsOnMenu() as $item}
<b-dropdown-item n:attr=”active => $item->isActive()” >
<a href=”{$item->getRealLink()}”>{$item->getRealTitle()}</a>
</b-dropdown-item>
{/foreach}
</b-nav-item-dropdown>
{/if}
{/foreach}
</b-nav>
</div>
</div>
</nav>

The link in the dropdown should redirect me to the page/URL in the link. Right now, nothing happens.

vue.js set up
in <head>

<!– Load required Bootstrap and Bootstrapvue.js CSS –>
<link type=”text/css” rel=”stylesheet” href=”//unpkg.com/bootstrap/dist/css/bootstrap.min.css”/>
<link type=”text/css” rel=”stylesheet” href=”//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css”/>

<!– Load polyfills to support older browsers –>
<script src=”//polyfill.io/v3/polyfill.min.js?features=es2015%2CMutationObserver” crossorigin=”anonymous”></script>
<!– Load vue.js followed by Bootstrapvue.js –>
<script src=”//unpkg.com/vue@latest/dist/vue.min.js”></script>
<script src=”//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js”></script>

in footer

<script>
window.app = new Vue({
el: ‘#app’,
})
</script>

Solution :

I think I get it. The <b-nav-item> component has a href property. Inserting the code inside it, it works.

So I remove all the conditionals and just cloned the items.

window.app = new Vue({
el: ‘#app’,
})
<!DOCTYPE html>
<html lang=”en”>

<head>
<!– Required meta tags –>
<meta charset=”utf-8” />
<meta name=”viewport” content=”width=device-width, initial-scale=1, shrink-to-fit=no” />
<meta http-equiv=”content-type” content=”text/html; charset=UTF-8” />

<title>My first Bootstrapvue.js app</title>

<!– Required Stylesheets –>
<link type=”text/css” rel=”stylesheet” href=”https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type=”text/css” rel=”stylesheet” href=”https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" />

<!– Required scripts –>
<script src=”https://unpkg.com/vue"></script>
<script src=”https://unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src=”https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
</head>

<body>
<!– Our application root element –>
<div id=”app”>
<b-container>
<nav class=”navbar navbar-expand-lg navbar-dark bg-dark fixed-top”>
<div>
<b-nav n:if=”$menu->hasVisibleItemsOnMenu()”>

<b-nav-item href=”https://google.com" n:attr=”active => $itemsParent->isActive()”>
Google
</b-nav-item>

<b-nav-item href=”https://bing.com" n:attr=”active => $itemsParent->isActive()”>
Bing
</b-nav-item>
<b-nav-item href=”https://yahoo.com" n:attr=”active => $itemsParent->isActive()”>
Yahoo
</b-nav-item>
<b-nav-item-dropdown text=”Dropdown” extra-toggle-classes=”nav-link-custom” right>

<b-dropdown-item href=”https://google.com" n:attr=”active => $item->isActive()”>
Google
</b-dropdown-item>
<b-dropdown-item href=”https://bing.com" n:attr=”active => $item->isActive()”>
Bing
</b-dropdown-item>
<b-dropdown-item href=”https://yahoo.com" n:attr=”active => $item->isActive()”>
Yahoo
</b-dropdown-item>
</b-nav-item-dropdown>

</b-nav>
</div>
</nav>
</b-container>
</div>

</body>

</html>

There is an extra </div> in the code, I don’t think that was interfering.

It’s hard to say without the correct CSS, but the links seems to be working.

[Vue.js] want to show loading text before submitting

to show loading text when click submit button and before the form submit. i tried this code.

<button type=”button” @click=”addCustomers”
:disabled=”disableSubmitButton” class=”btn btn-primary” style=”float:
right;” value=”ADD CUSTOMER”>{customer.loading ? “Loading…” : “ADD
CUSTOMER”}</button>

after i add a loading object in data.

data(){
return {
loading: false,
}
}

when i call to my click event function i add “loading = true” to display my loading text.

but this process not working. how can i show it. i don’t want any spinner loading packages in vuejs. this is my click event function.

addCustomers(){
customer.loading = true;
axios.post(){
….
}
}

Solution :

the customer data element is not mentioned in data object property, so the code could should be like :

<button type=”button” @click=”addCustomers”
:disabled=”disableSubmitButton” class=”btn btn-primary” style=”float:
right;” value=”ADD CUSTOMER”>{loading ? “Loading…” : “ADD
CUSTOMER”}</button>

and in the methods:

addCustomers(){
this.loading = true;
axios.post().then(res=>{
this.loading=false;
}).catch(err=>{
//handle error
})
}

[Vue.js] Edit items in v-for

I’m trying to edit items within a v-for directive, however this doesn’t seem to work as I expected. First of, here’s the markup and the component methods:

<div class=”card goal-item” v-for=”goal in goals”>
<div v-if=”!goal.edit” class=”card-body”>
<p>
{ goal.value }
<span class=”far fa-fw fa-edit float-right action” v-on:click=”editGoal(index)”></span>
</p>
</div>
<div v-else class=”card-body”>
<div class=”input-group”>
<input class=”form-control” type=”text” v-model=”goal.value” v-on:keyup.enter=”submitEditGoal(index)” />
<div class=”input-group-append”>
<button class=”btn btn-primary” type=”button” v-on:click=”submitEditGoal(index)”><span class=”far fa-fw fa-check”></span></button>
</div>
</div>
</div>
</div>

methods: {
editGoal(index){
this.goals[index].edit = true;
},
submitEditGoal(index){
this.goals[index].edit = false;
}
}

Whenever the user presses the button to edit, the v-else is not triggering. If I log the edit property after altering it in my editGoal(index) it does say true but if I print out the property ({ goal.edit }) it still says false.

Is this not possible or am I doing something wrong?

Solution :

The idea of what you’re trying to do should work fine. You’re getting strange behavior because you are referencing the methods with : instead of @, which is causing those methods to actually execute when the template is processed instead of binding them to the event you want.

Check out this fiddle: https://jsfiddle.net/e7jv0wyc/

You’ll want to change the code like so. Note there are 3 replacements of : with @:

<div class=”card goal-item” v-for=”goal in goals”>
<div v-if=”!goal.edit” class=”card-body”>
<p>
{ goal.value }
<span class=”far fa-fw fa-edit float-right action” @click=”editGoal(index)”></span>
</p>
</div>
<div v-else class=”card-body”>
<div class=”input-group”>
<input class=”form-control” type=”text” v-model=”goal.value” @keyup.enter=”submitEditGoal(index)” />
<div class=”input-group-append”>
<button class=”btn btn-primary” type=”button” @click=”submitEditGoal(index)”><span class=”far fa-fw fa-check”></span></button>
</div>
</div>
</div>
</div>

Solution 2:

I managed to solve my issue.

The problem was that the edit property is not present on the initial data. This is my initial data:

data: function (){
return {
goals: [
{
id: 1,
value: “item 1”
},
{
id: 2,
value: “item 2”
}
]
}
}

Therefore I cannot watch on the edit property.

I solved my issue by adding the following methods and temp variable, to store the index of the items I’m currently editing:

data: function () {
goals: …,

editIndex: null
},
methods: {
editGoal(index){
this.editIndex = index;
},
submitEditGoal(){
this.editIndex = null;
}
}

I can then rewrite my markup to check for this editIndex property like so:

<div class=”card goal-item” v-for=”(goal, index) in goals”>
<div class=”card-body”>
<div v-if=”editIndex != null && editIndex === index” class=”input-group”>
<input class=”form-control” type=”text” v-model=”goal.value” v-on:keyup.enter=”submitEditGoal()” />
<div class=”input-group-append”>
<button class=”btn btn-primary” type=”button” v-on:click=”submitEditGoal()”><span class=”far fa-fw fa-check”></span></button>
</div>
</div>
<p v-else>
{ goal.value }
<span class=”far fa-fw fa-edit float-right action” v-on:click=”editGoal(index)”></span>
</p>
</div>
</div>

[Vue.js] Checkbox list without using v-model

vue.js has a good example of using multiple checkboxes with the same name attribute bound to the same array using v-model

However, I can’t use v-model for some reason so I must use @input to emit checked while keeping the value unchanged.

Its not working for me though, all the checkboxes are checked/unchecked at the same time or there is to change the value which I don’t want.

Is there a workaround?

Code: https://codesandbox.io/s/71pm2wllp1?fontsize=14

Solution :

vue.js generates special code when compiling a template containing checkboxes bound in this way. Since you’re not using v-model, you’ll have to handle this functionality yourself.

Try something like this:

new Vue({
el: ‘#app’,
data: {
checkboxes: [
{ name: ‘jack’, value: ‘Jack’ },
{ name: ‘bob’, value: ‘Bob’ },
{ name: ‘alice’, value: ‘Alice’ },
],
model: [],
},
computed: {
modelJson() {
return JSON.stringify(this.model);
},
},
methods: {
handleChange(value, checked) {
if (checked) {
this.model = this.model.concat(value);
} else {
this.model = this.model.filter(x => x !== value);
}
},
},
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id=”app”>
<div v-for=”checkbox of checkboxes” :key=”checkbox.name”>
<input
type=”checkbox”
:id=”checkbox.name”
:name=”checkbox.name”
:value=”checkbox.value”
:checked=”model.includes(checkbox.value)”
@change=”handleChange(checkbox.value, $event.target.checked)”
/>
<label :for=”checkbox.name”>{ checkbox.value }</label>
</div>
<pre>{ modelJson }</pre>
</div>

[Vue.js] Vue object changes, but doesn't re-render

When I press right arrow key, it changes the object, but not re-render it :

<div class=”map”>
<div class=”map-page” tabindex=”0” @keyup.arrow-keys=”show” ref=”mapPage”>
<template v-for=”mapRow in mapMatrix”>
<div v-for=”cell in mapRow” @click=”(cell.view === ‘1’) ? showAlert() : false “ v-bind:class=”[‘map-cell’,{‘cell-active’ : cell.active}]“>
{cell.view}
</div>
</template>
</div>
<div>

By key pressed(@keyup.arrow-keys=”show”) want to change the active cell.

show: function (event) {
if(event.keyCode === 39){
if (this.selectedCellId !== CELL_NUMBER){
this.moveRight();
}
}
},
moveRight: function(){
this.$set(this.mapMatrix[this.selectedRowId][this.selectedCellId],’active’,false);
this.selectedCellId++;
this.$set(this.mapMatrix[this.selectedRowId][this.selectedCellId],’active’,true);
},

it worked nice with the static object:

mapMatrix: {
0 : {
0 : {
“view” : “-1”,
“available” : true,
“active”: false
},
1 : {
“view” : “1”,
“available” : true,
“active”: false
},
2 : {
“view” : “1”,
“available” : true,
“active”: false
},

},

}

But doesn’t work with:

fillMatrix: function(){
var i;
var g;
for(i = 0; i <= CELL_NUMBER; i++){
this.mapMatrix[i] = {};
for(g = 0; g <= CELL_NUMBER; g++){
var view = this.setVeiw(g);
this.mapMatrix[i][g] =
{
“view” : view,
“available” : true,
“active”: false
};
}
}
}

It changes the object properly, but no reaction on html render. What is the difference?

Solution :

The way you’re building the matrix object won’t work correctly with Vue; it likely won’t end up being reactive (see Change Detection Caveats).

Either use this.$set when building the matrix, or build it first in a local variable then assign it to this.mapMatrix last to ensure that the whole object will be reactive.

Something like this:

fillMatrix() {
// This is a fresh new unobserved object
const mapMatrix = {};

for (let i = 0; i <= CELL_NUMBER; i++) {
mapMatrix[i] = {};

for(let g = 0; g <= CELL_NUMBER; g++) {
mapMatrix[i][g] = {
view: this.setView(g),
available: true,
active: false,
};
}
}

// Since the this.mapMatrix property is reactive, vue.js will detect this
// assignment and make the new mapMatrix object reactive
this.mapMatrix = mapMatrix;
}

Solution 2:

Should change object-fill function to more reactive way (as in the @jcbdrn comment):

fillMatrix: function(){
var i;
var g;
for(i = 0; i <= CELL_NUMBER; i++){
this.$set(this.mapMatrix,i,{});
for(g = 0; g <= CELL_NUMBER; g++){
var view = this.setVeiw(g);
this.$set(this.mapMatrix[i],g,
{
“view” : view,
“available” : true,
“active”: false
}
);

}
}
},

That solved the problem.

[Vue.js] Error Request object that has already been used

I keep getting this error in the console log

Uncaught (in promise) TypeError: Failed to execute ‘fetch’ on ‘ServiceWorkerGlobalScope’: Cannot construct a Request with a Request object that has already been used.

I tried changing my service worker but it doesn’t work

self.addEventListener(‘install’, (event) => event.waitUntil(preLoad()));

const preLoad = function () {
return caches.open(‘cc-offline’).then((cache) => {
return cache.addAll([‘/offline.html’, ‘/index.html’]);
});
}

self.addEventListener(‘fetch’, (event) => {
event.respondWith(checkResponse(event.request).catch(function () {
return returnFromCache(event.request)
}));
event.waitUntil(addToCache(event.request));
});

const checkResponse = (request) => {
return new Promise((fulfill, reject) => {
fetch(request).then((response) => {
(response.status !== 404) ? fulfill(response) : reject()
}, reject)
});
};

const addToCache = (request) => {
return caches.open(‘cc-offline’).then((cache) => {
return fetch(request).then((response) => {
return cache.put(request, response);
});
});
};

const returnFromCache = (request) => {
return caches.open(‘cc-offline’).then((cache) => {
return cache.match(request).then((matching) => {
return (!matching || matching.status == 404) ? cache.match(‘offline.html’) : matching
});
});
};

Solution :

fetch don’t allow you to use a request twice, at least at current version :). Using the same request object in both checkResponse and addToCache maybe the case. You can try to clone the request object before calling fetch as mention in here Why does this code fail to execute ‘fetch’?