link1370 link1371 link1372 link1373 link1374 link1375 link1376 link1377 link1378 link1379 link1380 link1381 link1382 link1383 link1384 link1385 link1386 link1387 link1388 link1389 link1390 link1391 link1392 link1393 link1394 link1395 link1396 link1397 link1398 link1399 link1400 link1401 link1402 link1403 link1404 link1405 link1406 link1407 link1408 link1409 link1410 link1411 link1412 link1413 link1414 link1415 link1416 link1417 link1418 link1419 link1420 link1421 link1422 link1423 link1424 link1425 link1426 link1427 link1428 link1429 link1430 link1431 link1432 link1433 link1434 link1435 link1436 link1437 link1438 link1439 link1440 link1441 link1442 link1443 link1444 link1445 link1446 link1447 link1448 link1449 link1450 link1451 link1452 link1453 link1454 link1455 link1456 link1457 link1458 link1459 link1460 link1461 link1462 link1463 link1464 link1465 link1466 link1467 link1468 link1469 link1470 link1471 link1472 link1473 link1474 link1475 link1476 link1477 link1478 link1479 link1480 link1481 link1482 link1483 link1484 link1485 link1486 link1487 link1488 link1489 link1490 link1491 link1492 link1493 link1494 link1495 link1496 link1497 link1498 link1499 link1500 link1501 link1502 link1503 link1504 link1505 link1506

[Vue.js] Why does this.form.post(URI) can find one route but not the others ?

there is a API Resource Routes with multiple Controllers but only one (‘project’ => ‘API\ProjectController’) can be reach. I used the good URI(In the route list) for the others API Resource Routes(example: ‘api/userEdit’) but still get the error:

POST http://127.0.0.1:8000/profile/api/userEdit 404 (Not Found)

{message: “”, exception: “Symfony\Component\HttpKernel\Exception\NotFoundHttpException”,}
exception: “Symfony\Component\HttpKernel\Exception\NotFoundHttpException”
file: “C:\Users\PC-HP\Desktop\myapp\mywebsite\vendor\laravel\framework\src\Illuminate\Routing\RouteCollection.php”
line: 179
message: “”
trace: [{,}, {,}, {,}, {,}, {,},]

All my Controllers exist in Http/Controllers/API. This is very strange.

Thanks for the help.

CreateProject.vue.js (Work with ‘project’ => ‘API\ProjectController’)

<template>
<div>

<form @submit.prevent=”addProject”>

<div class=”create-form” id=”” style=”margin-left:40%;margin-top:80px;”>

<div class=”mt-4”>
<label for=”usr”>Project Name:</label><br>
<input type=”text” v-model=”form.title” class=”form-control” :class=”{ ‘is-invalid’: form.errors.has(‘title’) }” required>
<has-error :form=”form” field=”title”></has-error>
</div>

<div class=”mt-4”>
<label for=”usr”>Description:</label><br>
<textarea v-model=”form.desc” name=”desc” class=”form-control” :class=”{ ‘is-invalid’: form.errors.has(‘desc’) }” required></textarea>
<has-error :form=”form” field=”desc”></has-error>
</div>

<div class=”mt-4”>
<label for=”usr”>Keys words:</label><br>
<input type=”text” v-model=”form.keyword” name=”keyword” class=”form-control” v-on:keyup.space=”addKeywords”>
<li v-for=”(keyw,index) in form.keywords” :key=”index”>{keyw}<a href=”#” @click.prevent=”deleteKeywords(index)”>x</a></li>
</div>

<div class=”” id=””>
<label for=”usr”>Category</label><br>
<select v-model=”form.category” class=”form-control”>
<option value=”1” selected=”selected”>Select a choice</option>
<option value=”2”>gfdg</option>
<option value=”3”>gffdg</option>
<option value=”4”>fdsfd</option>
<option value=”5”>gfdgfd</option>
<option value=”6”>gfdgf</option>
<option value=”7”>gfddfg</option>
<option value=”8”>wewerw</option>
</select>
</div>

<label class=”mt-4”>Images</label><br>

<div class=”uploader-create-project” @dragenter=”OnDragEnter” @dragleave=”OnDragLeave” @dragover.prevent @drop=”onDrop” :class=”{ dragging: form.isDragging }”>

<div class=”upload-control” v-show=”form.images.length”>
<label for=”file”>Select a file</label>
</div>

<div v-show=”!form.images.length”>
<i class=”fa fa-cloud-upload”></i>
<p>Drag the images here</p>
<div>OR</div>
<div class=”file-input”>
<label for=”file”>Select a file</label>
<input type=”file” id=”file” @change=”onInputChange” multiple>
</div>
</div>

<div class=”images-preview” v-show=”form.images.length”>
<div class=”img-wrapper” v-for=”(image,index) in form.images” :key=”index”>
<img :src=”image” :alt=”`Image Uploader ${index}`“>
<div class=”details”>
<span class=”name” v-text=”form.files[index].name” ></span>
</div>
<a href=’#’ @click.prevent=”deleteImage(index)” class=”delete-link”>Delete</a>
</div>
</div>
</div>

<span>{(form.sizefiles/1000000).toFixed(2)} Mo</span>

<div class=”mt-4”>
<label for=”usr”>Poste</label><br>

<input type=”text” v-model=”form.task_name” class=”form-control” name=”task”>

<label style=”margin-left:20px;”>person required</label>
<select v-model=”form.nbr_person” form=”carform” class=”form-control”>
<option value=”1” selected=”selected”>1</option>
<option value=”2”>2</option>
<option value=”3”>3</option>
<option value=”4”>4</option>
<option value=”5”>5</option>
<option value=”6”>6</option>
<option value=”7”>7</option>
<option value=”8”>8</option>
</select>

<button type=”button” class=”btn btn-primary” @click=”addTask”>+</button>

</div>
<li v-for=”(task,index) in form.tasks” :key=”index”>0/{task.nbr_person_max} {task.name} <a href=”#” @click.prevent=”deleteTask(index)”>x</a></li>

<div class=”mt-4”>
<input type=”checkbox” v-model=”form.private” id=”private” name=”private”>
<label for=”scales”>Private</label>
</div>

<div class=”mt-4”>
<input type=”submit”>
</div>

</div>

</form>

</div>
</template>

<script>

export default{

data(){
return{
form: new Form({
title:’’,
desc:’’,
nbr_person:’’,
category:’’,
keyword:’’,
private:’’,
task_name:’’,
tasks:[],
keywords:[],
isDragging: false,

dragCount:0,
files:[],
images:[],
sizefiles:0,

})
}
},

methods:{

addTask(){
if(this.form.task_name != ‘’){
if(this.form.tasks.length < 4){
if(this.form.nbr_person == ‘’){this.form.nbr_person= 1;}
this.form.tasks.push({
name:this.form.task_name,
nbr_person_max:this.form.nbr_person
});
}else{ this.$toastr.e(‘The maximum of tasks is reach’);}
}else{
this.$toastr.e(‘Please write a task in the empty field’);
}
this.form.task_name=’’;
this.form.nbr_person=’’;
},
deleteTask(index){
this.form.tasks.splice(index,1);
},

addKeywords(){
if(this.form.keyword == ‘ ‘){this.form.keyword = ‘’};
if(this.form.keywords.length < 4){
if(this.form.keyword != ‘’){
this.form.keywords.push(this.form.keyword);
this.form.keyword=’’;
}else{
this.$toastr.e(‘Please write a keyword in the empty field’);
}
}else{ this.$toastr.e(‘The maximum (4) keywords is reach’); }
},
deleteKeywords(index){
this.form.keywords.splice(index,1);
},

addProject(){
if(this.form.category == ‘’){this.form.category = ‘none’;}
this.form.post(‘api/project’);

},

//Upload image setting
onInputChange(e){
const files = e.target.files;
Array.from(files).forEach(file => this.addImage(file));
},
OnDragEnter(e){
e.preventDefault();

this.form.dragCount++;
this.form.isDragging=true;

return false;
},
OnDragLeave(e){
e.preventDefault();

this.form.dragCount–;
if(this.form.dragCount <= 0)
this.form.isDragging=false;

},
onDrop(e){
e.preventDefault();
e.stopPropagation();

this.form.isDragging = false;

const files = e.dataTransfer.files;

Array.from(files).forEach(file => this.addImage(file));

},
addImage(file){

if(!file.type.match(‘image.*‘)){
this.$toastr.e(`${file.name} is not an image ${file.size}`);
return;
}else if( (this.form.sizefiles + file.size) <= 1000000){

this.form.sizefiles += file.size;

this.form.files.push(file);

const reader = new FileReader();

reader.onload = (e) => this.form.images.push(e.target.result);

reader.readAsDataURL(file);

}else{
this.$toastr.e(`The maximum of space(1 Mo) have been reach `);
}
},
getFileSize(size) {
const fSExt = [‘Bytes’, ‘KB’, ‘MB’, ‘GB’];
let i = 0;

while(size > 900) {
size /= 1024;
i++;
}
return `${(Math.round(size * 100) / 100)} ${fSExt[i]}`;
},
deleteImage(index){

this.form.sizefiles = this.form.sizefiles - this.form.files[index].size;
this.form.images.splice(index,1);
this.form.files.splice(index,1);

},

},

computed:{

}

}

</script>

Profile.vue.js (Doesn’t work with any post/get call Controller)

<template>
<div class=”container”>

<div class=”profile-box” id=””>

<form @submit.prevent=”finishEdit”>

<div class=”edit-profile mt-5 mb-5” v-show=”form.active_user_edit”>

<h4>Edit Profile</h4>

<div class=”change-image” id=””>
<label>Profile picture</label><br>
<input type=”file” id=”file” @change=”processImg”>
</div>

<div class=”change-name” id=””>
<label>Name</label><br>

<p>Name : {actual_user} <button type=”button” class=”btn btn-primary” @click.prevent=”Edit(‘name’)”>O</button></p>

<input type=”text” class=”form-control” v-show=”form.inputName” v-model=”form.change_name”>
</div>

<div class=”change-desc” id=””>

<p>Description <button type=”button” class=”btn btn-primary” @click.prevent=”Edit(‘desc’)”>O</button></p>

<textarea class=”form-control” v-model=”form.change_desc” v-show=”form.inputDesc”></textarea>
</div>

<div class=”change-profession” id=””>

<p>Speciality : {spec} <button type=”button” class=”btn btn-primary” @click.prevent=”Edit(‘spec’)”>O</button></p>

<input type=”text” class=”form-control” v-model=”form.change_spec” v-show=”form.inputSpec”>
</div>

<div class=”email” id=””>

<p>Email : {email} <button type=”button” class=”btn btn-primary” @click.prevent=”Edit(‘email’)”>O</button></p>

<input type=”text” class=”form-control” v-model=”form.change_email” v-show=”form.inputEmail”>
</div>

<div class=”mt-4”>
<button type=”submit” class=”btn btn-primary” >Edit</button>
</div>

</div>

</form>

</div>

</div>
</template>

<script>

//date setting
var moment = require(‘moment’);

export default {

props: [‘username’,’desc’,’email’,’actual_user’,’sub_date’,’id’,’spec’,’love’],

data(){
return{
form: new Form({

moment:moment,
sameUser:false,
id_user:0,
active_user_edit:’’,
editBut:’’,
selected_img:’’,
showLove:’’,

inputName:false,
inputEmail:false,
inputSpec:false,
inputDesc:false,

change_name:’’,
change_email:’’,
change_desc:’’,
change_spec:’’,

})
}
},

methods:{

editProfile(){
const check = this.form.active_user_edit;

if(check){
this.form.active_user_edit = false;
console.log(this.form.active_user_edit);
}else{
this.form.active_user_edit = true;
console.log(this.form.active_user_edit);
}

},

processImg() {
//this.form.selected_img = this.$refs.file.form.selected_img[0];
//console.log(event.target.files[0]);
},

Edit(part){
if(part == ‘name’){

if(this.form.inputName == false){
this.form.inputName = true;
}else{
this.form.inputName = false;
}

}else if(part == ‘desc’){

if(this.form.inputDesc == false){
this.form.inputDesc = true;
}else{
this.form.inputDesc = false;
}

}else if(part == ‘email’){

if(this.form.inputEmail == false){
this.form.inputEmail = true;
}else{
this.form.inputEmail = false;
}

}else if(part == ‘spec’){

if(this.form.inputSpec == false){
this.form.inputSpec = true;
}else{
this.form.inputSpec = false;
}

}
},

finishEdit(){

if(this.form.change_name == ‘’){
this.form.change_name = this.actual_user;
}
if(this.form.change_email == ‘’){
this.form.change_email = this.email;
}
if(this.form.change_spec == ‘’){
this.form.change_spec = this.spec;
}
if(this.form.change_desc == ‘’){
this.form.change_desc = ‘Nothing for the moment..’;
}

this.form.post(‘api/userEdit’);

},

},

}

</script>

api.php

/////

<?php

use Illuminate\Http\Request;

Route::middleware(‘auth:api’)->get(‘/user’, function (Request $request) {
return $request->user();
});

Route::apiResources([
‘project’ => ‘API\ProjectController’,
‘userEdit’ => ‘API\UserEditController’,
‘tasks’ => ‘API\TaskController’,
‘contact’ => ‘API\ContactController’

]);

Solution :

you should know if you call api route the url should be like this:

localhost/api/..

but the url /api/ is after profile:

http://127.0.0.1:8000/profile/api/userEdit

in the vuejs code replace

this.form.post(‘api/userEdit’);

with :

this.form.post(‘/api/userEdit’);

/ first of url

[Vue.js] Preloader v-cloak not showing text loading

there is in css:

[v-cloak]::before { content: “loading”; display: block; text-align: center; width: 300px; height: 600px; margin: 0 auto; font-size: 60px; }

When page loading, I don’t get loading… Why? I get white background.. I need do preloader v-cloak, show on user, that page is loading..

Solution :

The ::before pseudo-element is inserted as the first child of the [v-cloak] element, which is hidden.

The fix would be to create an adjacent element for the loading indicator, and apply the intended CSS there:

<div id=”app” v-cloak></div>
<div id=”loader”></div>

<style>
[v-cloak] + .loader::before {
/* … */
}
</style>

setTimeout(() => new Vue({ el: ‘#app’ }), 1500)
[v-cloak] {
display: none;
}

[v-cloak] + #loader::before {
content: “loading”;
display: block;
text-align: center;
width: 300px;
height: 600px;
margin: 0 auto;
font-size: 60px;
}
<script src=”https://unpkg.com/vue@2.6.3/dist/vue.min.js"></script>

<div id=”app” v-cloak>
<p>Hello Vue.js!</p>
</div>
<div id=”loader”></div>

Solution 2:

Try with the example from the documentation:

CSS:
[v-cloak] {
display: none;
}

.vue:
<div v-cloak>
Loading…
</div>

[Vue.js] Vuex state change not updating input field

**** UPDATE ****

Solution : Not bothering to tie the Vuex state to the form. I realized it’s not worth the trouble, and I can still serialize the form data and send it along anyway using the standard conventions. Had a total rethinking of not needing to tie so many elements into JS objects.

**** ORIG ****

Alright, can someone please tell me what I’m missing here.

to update the state in a mutation function, and have the changes reflect in the input fields. Crazy right? I guess there’s trouble with updating object properties, so in the example there is both referencing the object property and defining a specific getter for the property, neither of which are working. Then to represent updating the state outside of the input field, I just have a button below that does this.

Template:

<input :value=”user.first_name” @input=”UPDATE_USER” />
OR
<input :value=”first_name” @input=”UPDATE_USER” />
<button v-on:click=”updateName”>Update</button>

Component:

computed: {
…mapState({
user: state => state.user,
first_name: state => state.user.first_name // specific getter for the property
})
},
methods: {
…mapActions([
UPDATE_USER,
]),
updateName () {
this.$store.dispatch(UPDATE_USER_NAME, “anything”);
}
}

Action:

[UPDATE_USER_NAME] ({commit}, name) {
commit(“updateUserName”, name);
},
// Omitted UPDATE_USER function, just takes e.target.name / value and it works anyway

Mutations:

updateUserName (state, name) {
Vue.set(state.user, “first_name”, name);
}

Expected: Click the button, it updates the state, and the input field value shows “anything”.

Actual: Click the button, it updates the state, but the input field value is not updated. This goes for both input fields, one which references the object property directly, and the other which has its own getter.

Editing the input fields works fine, so it’s like it works top-down but not bottom-up. What the heck am I missing?

Solution :

Note: I tested this locally but I don’t know exactly how the store state looks from the question.

The <input> can be two-way bound with v-model, instead of computed or watched. It can be initialized with a value from the store (I used the mounted lifecycle hook below). The store state is updated only on button click.

<input v-model=”firstName”/>
<button @click=”updateName”>Update</button>

import { mapActions, mapGetters } from ‘vuex’

export default {
data () {
return {
firstName: ‘’
}
},

computed: mapGetters([‘getFirstName’]),

methods: {
…mapActions([‘UPDATE_FIRST_NAME]),

updateName () {
// validations can go here etc
this.UPDATE_FIRST_NAME(this.firstName) // update vuex store state
}
},

mounted () {
this.firstName = this.getFirstName // initialize this.firstName -> <input>
}
}

With this solution, you’d have to make sure to create the getter in the store, as in the following example:

const state = {
user: {
firstName: ‘’
}
}

const getters = {
getFirstName: state => state.user.firstName
}

Solution 2:

You need to watch the state variables. When it change the value, the the watch function will fire.

export default {
data() {
return {
dummy_name: ‘’,
first_name: ‘’,
}
},
created(){
},
computed: {
dummy_name() {
return this.$store.state.user.first_name
},
watch: {
dummy_name() {
this.first_name = this.dummy_name
}
}

Hope this will help, and get some idea how watch and computed work.

[Vue.js] Binding to array fields in vue.js

to make multiple ‘in-place’ editable date fields in table rows.
An example for a single field below works.
I show the currentdate (oldDate) as a label. User clicks on ‘Change’, an input field appears, after editing the user can Accept or Cancel.

https://jsfiddle.net/asrajan55/qv6crg84/

<div id=”root”>
<label>Test Date:</label>
<span v-show=”!makeEditable”> { oldDate } </span>
<span v-show = “makeEditable”>

<input type=”date” v-model=”newDate” required=””/>
<button @click=”acceptClicked”>Accept</button>
<button name=”cancel” @click=”makeEditable=false”>Cancel</button>
</span>
<button v-show=”!makeEditable” @click=”makeEditable=true” >Change</button>
</div>

new Vue({
el: “#root”,
data: {
oldDate: ‘2019-02-04’,
newDate: ‘2019-02-04’,
makeEditable: false,
},

methods: {
acceptClicked(){
if (this.newDate!=’’) {
this.oldDate=this.newDate;
this.makeEditable=false;
}
}
}
});

However if I try multiple(2) fields the click event fires (sometimes) but nothing seems to happen. No errors in console. Also the vue.js debugger in the browser does not immediately update the changed fields. Please help. when desperate and pulling my hair out!

https://jsfiddle.net/asrajan55/9uhkr4w0/3/

<div id=”root”>
<div v-for=”(item,index) in oldDates”>
<label for=””>Test Date:</label>
<span v-show=”!editables[index]“>{item}</span>
<input v-show=”editables[index]“ type=”date” v-model=”oldDates[index]“/>
<button v-show=”editables[index]“>Accept</button>
<button v-show=”editables[index]“ @click=”editables[index]=false”>Cancel</button>
<button v-show=”!editables[index]“ @click=”makeEditable(index)”>Change</button>
<hr />
</div>

</div>

new Vue({
el: “#root”,
data: {
oldDates: [‘2019-01-04’, ‘2019-02-04’],
newDates: [‘2019-01-04’, ‘2019-02-04’],
editables: [false, false]
},

methods: {
makeEditable(index) {
alert(index);
this.editables[index] = true;
}
}
});

Solution :

Try using this.$set(this.editables, index, true);

vue.js can’t detect changes to arrays if you directly access an element using []. Read about it here:

https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating

Solution 2:

The problem was that you were mutating the array in place,
creating a new array reference and passing it would solve the issue

fixed here : https://jsfiddle.net/e3L2zcna/

makeEditable(index) {
this.editables = this.editables.map((val,i) => i===index || val);
}

[Vue.js] How do I fetch JSON data with Vue and Axios

I’m trying to fetch product data from a JSON file, but can’t get it to work.
I’ve tried several things and searched the internet for a solution but none of the examples on the internet equals my situation.
I’m new to both vue.js and axios, so please excuse my ignorance.

This is what there is so far:

Vue.component(‘products’,{
data: {
results: []
},
mounted() {
axios.get(“js/prods.json”)
.then(response => {this.results = response.data.results})
},
template:`
<div id=”products”>
<div class=”productsItemContainer” v-for=”product in products”>
<div class=”productsItem”>
<div class=””>
<div class=”mkcenter” style=”position:relative”>
<a class=”item”>
<img class=”productImg” width=”120px” height=”120px” v-bind:src=”‘assets/products/‘ + product.image”>
<div class=”floating ui red label” v-if=”product.new”>NEW</div>
</a>
</div>
</div>
<div class=”productItemName” >
<a>{ product.name }</a>
</div>
<div class=”mkdivider mkcenter”></div>
<div class=”productItemPrice” >
<a> { product.unit_price }</a>
</div>
<div v-on:click=”addToCart” class=”mkcenter”>
<div class=”ui vertical animated basic button” tabindex=”0”>
<div class=”hidden content”>Koop</div>
<div class=”visible content”>
<i class=”shop icon”></i>
</div>
</div>
</div>
</div>
</div>
</div>
`
})
new Vue({
el:”#app”,
});

The json file is as follows

{
“products”:[
{
“name”: “Danser Skydancer”,
“inventory”: 5,
“unit_price”: 45.99,
“image”:”a.jpg”,
“new”:true
},
{
“name”: “Avocado Zwem Ring”,
“inventory”: 10,
“unit_price”: 123.75,
“image”:”b.jpg”,
“new”:false
}
]
}

The problem is only with the fetching of the data from a JSON file, because the following worked:

Vue.component(‘products’,{
data:function(){
return{
reactive:true,
products: [
{
name: “Danser Skydancer”,
inventory: 5,
unit_price: 45.99,
image:”a.jpg”,
new:true
},
{
name: “Avocado Zwem Ring”,
inventory: 10,
unit_price: 123.75,
image:”b.jpg”,
new:false
}
],
cart:0
}
},
template: etc………

Solution :

As the warnings suggest, please do the following:

Rename the data array from results to products since you are referencing it by the latter one as a name during render.
Make the data option a function returning an object since data option must be a function, so that each instance can maintain an independent copy of the returned data object. Have a look at the docs on this.

Vue.component(‘products’, {
data() {
return {
products: []
}
},

mounted() {
axios
.get(“js/prods.json”)
.then(response => {
this.products = response.data.products;
});
},

template: `
//…
`
}

<div id=”products”>
<div class=”productsItemContainer” v-for=”product in products”>
<div class=”productsItem”>

Also, since you’re not using CDN (I think), I would suggest making the template a component with a separate vue.js file rather than doing it inside template literals, something like that:

Products.vue

<template>
<div id=”products”>
<div class=”productsItemContainer” v-for=”product in products”>
<div class=”productsItem”>
<!– The rest of the elements –>

</div>
</div>
</div>
</template>

<script>
export default {
name: ‘Products’,

data() {
return {
products: []
}
},

mounted() {
axios
.get(“js/prods.json”)
.then(response => {
this.products = response.data.products;
});
}
}
</script>

And then in the main JS file or anywhere else requiring this component:

import Products from ‘./components/Products.vue’;

new Vue({
el: ‘#app’,

data() {
return {
//…
}
},

components: {
Products
}
})

<div id=”app”>

<Products />

</div>

[Vue.js] Data via prop not being displayed

there is managed to get myself slightly confused. there is an app where I can display all user profiles, this component is called all-profiles. An example of this page is

<tr v-for=”profile in profiles.data” :key=”profile.id”>
<td>{ profile.id }</td>
<td>{ profile.user.name }</td>
<td>{ profile.created_at }</td>
<td>
<router-link :to=”{ name: user-profile, params: {
id: profile.id }” tag=”a” exact> View Profile
</router-link>
</td>
</tr>

So nothing fancy here, just a simple loop. When you click on the router-link for a specific profile, it takes you to that page, a component called user-profile. I pass the profile id as a parameter.

So in the user-profile component, I display information about that profile. Most of the work is done in the created function

created() {
let vm = this;

let url = `/api/profile/${this.$route.params.id}`;
axios.get(url)
.then(response => {
this.profile = response.data;
this.fileName = response.data.file_path;
return d3.json(response.data.file_path);
}).then(data => {
//display some data
}).catch(err => {
//log error
});
}

So I firstly make an axios call to pull information about that profile. Each profile has a file_path which contains some processed data, in JSON form. I load this using d3 and display the data. This also works fine, no issues here. The issue is on this page however, within the template tags, I load another component which needs the file_path in order to display some data
within the file in the form of a chart. So there is

<barchart :file-name = this.fileName></barchart>

Now if I output fileName within the user-profile page, I can see it is correct. Now in the barchart component, there is the prop

props: {
fileName: {
type: String,
required: true
}
}

And then in the created function, I have

created() {
console.log(this.fileName);
}

So that should output the fileName when passing via the prop, but it currently outputs nothing. I used to have this working, but I was using route parameters, and wanted to switch things to props instead.

there is a feeling that maybe the barchart component is loaded before the fileName is properly set?

when not sure, is there anything obvious that might cause nothing to get outputted?

Thanks

Solution :

Is it just as simple as: you are using “:filename = this.filename” in the template? The ‘this’ seems to be out of place?

[Vue.js] Jest Vue Expected mock function to have been called with, but not called

when trying to mock an api call using Jest and vue.js but I get the error “Expected mock function to have been called with: … but not called”

there is tried to find a solution but haven’t found anything yet.

import DocumentService from “../../src/services/document”;
import mockedData from “../__mockData__/documents”;
import axios from “axios”;

it(“should call Document Service and download a document”, () => {
let catchFn = jest.fn(),
thenFn = jest.fn();

DocumentService.downloadDocumentById(jwtToken, DocumentURL, id)
.then(thenFn)
.then(catchFn);

// expect(axios.get).toHaveBeenCalledWith(DocumentURL + “/“ + id + “/content”, {
// headers: { Authorization: “Bearer “ + jwtToken, “X-role”: “SuperUser” }
// });

expect(axios.get).toHaveBeenCalledWith(DocumentURL);

let responseObj = { data: mockedData };
axios.get.Mockresponse(responseObj);
expect(thenFn).toHaveBeenCalledWith(mockedData);
expect(catchFn).not.toHaveBeenCalled();
});

Solution :

The test runs synchronously and the expect runs and fails before the Promise callbacks have a chance to run.

Make sure you await the Promise returned by DocumentService.downloadDocumentById to give the callbacks a chance to run:

it(“should call Document Service and download a document”, async () => { // use an async test function
let catchFn = jest.fn(),
thenFn = jest.fn();

const promise = DocumentService.downloadDocumentById(jwtToken, DocumentURL, id)
.then(thenFn)
.then(catchFn); // remember the Promise

expect(axios.get).toHaveBeenCalledWith(DocumentURL);

let responseObj = { data: mockedData };
axios.get.Mockresponse(responseObj);
await promise; // wait for the Promise
expect(thenFn).toHaveBeenCalledWith(mockedData); // SUCCESS
expect(catchFn).not.toHaveBeenCalled(); // SUCCESS
});

[Vue.js] Vue Material Drawer (how to display file.vue inside of md-content)

So I’m trying to build a website that contains 4 files.vue.js (navigation.vue, Home.vue, something1.vue.js something2.vue) each files has their own template and style. Inside of navigation.vue.js there is a temporary drawer in order to navigate on each files vue.
(documentation for temporary drawer: https://vuematerial.io/components/drawer (i’m using vue.js material) there is use the same code).

inside of my drawer i do have the md-toolbar, md-drawer and md-content tags (in wich it create my navigation menu:

So, I was wondering if their is a way to load one of my template (by clicking on list of item in md-drawer) into the md-content tag ?

Solution :

You can use vue-router. To install vue-router, go to the root directory and type this in the terminal:

npm install vue-router

Sample code snippet for App.vue.js or where you want to render the .vue.js files:

<template>
<v-app>
<!– route outlet –>
<!– component matched by the route will render here –>
<router-view></router-view>
</v-app>
</template>

Sample code snippet for routes.js file or where you’ll be registering the routes:

// 0. If using a module system (e.g. via vue-cli), import vue.js and VueRouter
// and then call `Vue.use(VueRouter)`.

// 1. Define route components.
// These can be imported from other files
import Home from ‘./path/to/Home’;
import Something1 from ‘./path/to/Something1’;
import Something2 from ‘./path/to/Something2’;

const routes = [
{
path: ‘/‘,
name: ‘Home’,
component: Home
},
{
path: ‘/something1’,
name: ‘Something1’,
component: Something1
},
{
path: ‘/something2’,
name: ‘Something2’,
component: Something2
},
]

// 3. Create the router instance and pass the `routes` option
const router = new VueRouter({
routes // short for `routes: routes`
})

// 4. Create and mount the root instance.
// Make sure to inject the router with the router option to make the
// whole app router-aware.
const app = new Vue({
router
}).$mount(‘#app’)

// Now the app has started!

You have to put each of the md options inside the vue-router-link like this:

<md-drawer :md-active.sync=”showNavigation”>
<md-toolbar class=”md-transparent” md-elevation=”0”>
<span class=”md-title”>My App name</span>
</md-toolbar>

<md-list>
<md-list-item>
<!– use router-link component for navigation. –>
<!– specify the link by passing the `to` prop. –>
<!– replace “/foo” and “/bar” with the route path (e.g., “/home”, “/something1”, “/something2”) –>
<router-link to=”/foo”>
<md-icon>move_to_inbox</md-icon>
<span class=”md-list-item-text”>Inbox</span>
</router-link>
</md-list-item>

<md-list-item>
<router-link to=”/bar”>
<md-icon>send</md-icon>
<span class=”md-list-item-text”>Sent Mail</span>
</router-link>
</md-list-item>

<md-list-item>
<router-link to=”/foo”>
<md-icon>delete</md-icon>
<span class=”md-list-item-text”>Trash</span>
</router-link>
</md-list-item>

<md-list-item>
<router-link to=”/bar”>
<md-icon>error</md-icon>
<span class=”md-list-item-text”>Spam</span>
</router-link>
</md-list-item>
</md-list>
</md-drawer>

You can know more about vue-router here: vue.js Router Documentation:

Feel free to upvote my answer if it helped you. Hope this helps! :)

[Vue.js] Starting vue js dev server gives eror .plugins may only be a two-tuple or three-tuple

when using vue.js CLI version 3 to run a vue.js application inside a Docker container. To start the development server, I run:

https://cli.vuejs.org/guide/cli-service.html

This gives the following error:

ERROR Failed to compile with 1 errors 17:05:14

error in ./app/main.js

Module build failed (from ./node_modules/@vue/cli-plugin-babel/node_modules/babel-loader/lib/index.js):
Error: .plugins[0] may only be a two-tuple or three-tuple
at assertPluginItem (/home/src/node_modules/@babel/core/lib/config/validation/option-assertions.js:235:13)
at arr.forEach (/home/src/node_modules/@babel/core/lib/config/validation/option-assertions.js:222:30)
at Array.forEach (<anonymous>)
at assertPluginList (/home/src/node_modules/@babel/core/lib/config/validation/option-assertions.js:222:9)
at Object.keys.forEach.key (/home/src/node_modules/@babel/core/lib/config/validation/options.js:107:5)
at Array.forEach (<anonymous>)
at validateNested (/home/src/node_modules/@babel/core/lib/config/validation/options.js:83:21)
at validate (/home/src/node_modules/@babel/core/lib/config/validation/options.js:74:10)
at file (/home/src/node_modules/@babel/core/lib/config/config-chain.js:174:34)
at cachedFunction (/home/src/node_modules/@babel/core/lib/config/caching.js:33:19)
at buildRootChain (/home/src/node_modules/@babel/core/lib/config/config-chain.js:120:36)
at loadPrivatePartialConfig (/home/src/node_modules/@babel/core/lib/config/partial.js:85:55)
at Object.loadPartialConfig (/home/src/node_modules/@babel/core/lib/config/partial.js:110:18)
at Object.<anonymous> (/home/src/node_modules/@vue/cli-plugin-babel/node_modules/babel-loader/lib/index.js:140:26)
at Generator.next (<anonymous>)
at asyncGeneratorStep (/home/src/node_modules/@vue/cli-plugin-babel/node_modules/babel-loader/lib/index.js:3:103)

@ multi (webpack)-dev-server/client/index.js ./node_modules/@vue/cli-service/node_modules/webpack/hot/dev-server.js ./app/main.js

I suspect that the offending code is the following, in my .babelrc file:

“plugins”: [
[“transform-runtime”, “transform-vue-jsx”, “transform-regenerator”, {
“polyfill”: false,
“regenerator”: true
}]

Could someone suggest how I could go about resolving this? Thanks!

Solution :

the [ is in the wrong place. It should be

“plugins”: [
“transform-runtime”,
“transform-vue-jsx”,
[“transform-regenerator”, {
“polyfill”: false,
“regenerator”: true
}]
]

[Vue.js] reactive vuejs array does not display its content using v-for

I’m having trouble showing my array data in an HTML list.
Every time I drop an image on a specific div element, an object is inserted into the array whose position becomes the name of the object and not numbered as is usually the case, if an image is dragged again and the object already exists in the array, the quantity attribute of the object in the array is increased. The problem is when I try to show the contents of that array in an HTML list using v-for, the behavior it has is as if the array were empty. there is already verified that the array is not empty and I do not know what else to do.

<template>
<div>
<div id=”wrapper-ingredients”>
<div id=”base”>
<img src=”../img/base.svg” usemap=”#image-map” alt=”base”>
<drop id=”pizza-base” @drop=”handleDrop”>
<map name=”image-map” id=”image-map”>
<area target=”_self” alt=”pizza-base” title=”pizza-base”
coords=”133,387,93,308,79,217,119,119,168,69,231,32,308,17,381,14,448,36,489,64,526,99,555,142,576,195,586,251,575,314,546,359,488,412,416,446,317,454,205,436”
shape=”poly”>
</map>
</drop>
</div>

<div id=”ingredients”>
<drag class=”drag” :transfer-data=”bellpepper”>
<img src=”../img/bellpepper-512.png” id=”bellpepper” alt=”pimiento amarillo” width=”512”
height=”512”>
</drag>
<drag class=”drag” :transfer-data=”cheese”>
<img src=”../img/cheese-512.png” alt=”queso” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”corn”>
<img src=”../img/corn-512.png” alt=”maiz” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”mushroom”>
<img src=”../img/mushroom-512.png” alt=”seta” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”olive”>
<img src=”../img/olive-512.png” alt=”oliva” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”onion”>
<img src=”../img/onion-512.png” alt=”cebolla” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”pepperoni”>
<img src=”../img/pepperoni-512.png” alt=”pepperoni” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”tomato”>
<img src=”../img/tomato-512.png” alt=”tomate” width=”512” height=”512”>
</drag>
</div>
</div>
<div id=”wrapper-ticket”>
<ul>
<li v-for=”ingRec in ingredientsReceipt” >{ingRec}</li>
</ul>
</div>
</div>
</template>

<script>

import {Ticket} from “../model/Ticket.js”
import {Bellpepper} from “../model/Bellpepper.js”
import {Cheese} from “../model/Cheese.js”
import {Corn} from “../model/Corn.js”
import {Mushroom} from “../model/Mushroom.js”
import {Olive} from “../model/Olive.js”
import {Onion} from “../model/Onion.js”
import {Pepperoni} from “../model/Pepperoni.js”
import {Tomato} from “../model/Tomato.js”
import {Drag, Drop} from ‘vue-drag-drop’

export default {
components: {Drag, Drop},
data() {
return {
ingredientsReceipt: [],
bellpepper: new Bellpepper(2),
cheese: new Cheese(3),
corn: new Corn(1),
mushroom: new Mushroom(2),
olive: new Olive(3),
onion: new Onion(4),
pepperoni: new Pepperoni(5),
tomato: new Tomato(6),
ticket: new Ticket()
}
},
methods: {
handleDrop(data) {
let x = event.clientX
let y = event.clientY
let img = document.createElement(“img”)
img.setAttribute(‘src’, data.img)
img.setAttribute(‘name’, data.name)
img.style.position = ‘absolute’
img.style.width = ‘3.5%’
img.style.height = ‘7%’
img.style.left = x - img.offsetWidth / 2 - 50 + ‘px’
img.style.top = y - img.offsetHeight / 2 - 25 + ‘px’
img.style.zIndex = ‘1’
document.querySelector(‘#pizza-base’).appendChild(img)
if (this.ingredientsReceipt[data.name] !== data) {
this.ingredientsReceipt[data.name] = data

} else {
this.ingredientsReceipt[data.name].quantity++

}
img.addEventListener(“click”, () => {
if (this.ingredientsReceipt[data.name].quantity > 0) {
this.ingredientsReceipt[data.name].quantity–
img.remove()
} else {
img.remove()
delete this.ingredientsReceipt[data.name]
}
})
},
},
}
</script>

I tried to show the array directly without using v-for, showing only an empty array on the screen.
If someone knows where to find the error, it would be very helpful.

Solution :

You add elements to this.ingredientsReceipt[data.name] = data
vue.js can’t detect changes to the array using this direct access, you can read about it here:

https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating

They also offer a solution - try ingredientsReceipt.$set(data.name, data)

Solution 2:

ok, I finally managed to fix it, the problem was that it was renaming each of the positions of the array. To solve it I used some functional programming, there is left the positions of the array numbered and there is applied a .filter() to them and there is worked with that obtained value. Now it works, but I will investigate more to know why it does not work with the renamed array positions.

I leave the new code with the changes made, I will also comment on the code that I had to delete, and which I guess is where the problem lies, in case someone is able to find the error.

<template>
<div>
<div id=”wrapper-ingredients”>
<div id=”base”>
<img src=”../img/base.svg” usemap=”#image-map” alt=”base”>
<drop id=”pizza-base” @drop=”handleDrop”>
<map name=”image-map” id=”image-map”>
<area target=”_self” alt=”pizza-base” title=”pizza-base”
coords=”133,387,93,308,79,217,119,119,168,69,231,32,308,17,381,14,448,36,489,64,526,99,555,142,576,195,586,251,575,314,546,359,488,412,416,446,317,454,205,436”
shape=”poly”>
</map>
</drop>
</div>

<div id=”ingredients”>
<drag class=”drag” :transfer-data=”bellpepper”>
<img src=”../img/bellpepper-512.png” id=”bellpepper” alt=”pimiento amarillo” width=”512”
height=”512”>
</drag>
<drag class=”drag” :transfer-data=”cheese”>
<img src=”../img/cheese-512.png” alt=”queso” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”corn”>
<img src=”../img/corn-512.png” alt=”maiz” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”mushroom”>
<img src=”../img/mushroom-512.png” alt=”seta” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”olive”>
<img src=”../img/olive-512.png” alt=”oliva” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”onion”>
<img src=”../img/onion-512.png” alt=”cebolla” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”pepperoni”>
<img src=”../img/pepperoni-512.png” alt=”pepperoni” width=”512” height=”512”>
</drag>
<drag class=”drag” :transfer-data=”tomato”>
<img src=”../img/tomato-512.png” alt=”tomate” width=”512” height=”512”>
</drag>
</div>
</div>
<div id=”wrapper-ticket”>
<ul>
<li v-for=”ingRec in ingredientsReceipt”>{ingRec.name + “ X “ + ingRec.quantity}</li>
</ul>
</div>
</div>
</template>
<script>
import {Ticket} from “../model/Ticket.js”
import {Bellpepper} from “../model/Bellpepper.js”
import {Cheese} from “../model/Cheese.js”
import {Corn} from “../model/Corn.js”
import {Mushroom} from “../model/Mushroom.js”
import {Olive} from “../model/Olive.js”
import {Onion} from “../model/Onion.js”
import {Pepperoni} from “../model/Pepperoni.js”
import {Tomato} from “../model/Tomato.js”
import {Drag, Drop} from ‘vue-drag-drop’

export default {
components: {Drag, Drop},
data() {
return {
ingredientsReceipt: [],
bellpepper: new Bellpepper(2),
cheese: new Cheese(3),
corn: new Corn(1),
mushroom: new Mushroom(2),
olive: new Olive(3),
onion: new Onion(4),
pepperoni: new Pepperoni(5),
tomato: new Tomato(6),
ticket: new Ticket()
}
},
methods: {
handleDrop(data) {
let x = event.clientX
let y = event.clientY
let img = document.createElement(“img”)
img.setAttribute(‘src’, data.img)
img.setAttribute(‘name’, data.name)
img.style.position = ‘absolute’
img.style.width = ‘3.5%’
img.style.height = ‘7%’
img.style.left = x - img.offsetWidth / 2 - 50 + ‘px’
img.style.top = y - img.offsetHeight / 2 - 25 + ‘px’
img.style.zIndex = ‘1’
document.querySelector(‘#pizza-base’).appendChild(img)
if (this.ingredientsReceipt.indexOf(data) === -1) {
this.ingredientsReceipt.push(data)
} else {
let x = this.ingredientsReceipt.filter(arrayItem =>
arrayItem.name === data.name
)
x[0].quantity++
console.log(x,this.ingredientsReceipt)
}

//HERE IS WHERE THE PROBLEM WILL BE…

/*
this.ingredientsReceipt[data.name] = (this.ingredientsReceipt[data.name] || 0) + 1
if (this.ingredientsReceipt[data.name] !== data) {
this.ingredientsReceipt[data.name] = data

} else {
this.ingredientsReceipt[data.name].quantity++

}
*/
img.addEventListener(“click”, () => {
let x = this.ingredientsReceipt.filter( arrayItem => arrayItem.name === data.name)
if (x[0].quantity > 0) {
x[0].quantity–
img.remove()
} else {
img.remove()
delete this.ingredientsReceipt[data.name]
}
})
/*console.log(this.ingredientsReceipt)*/
},
},
}
</script>

Thank You All for the help!!