link1781 link1782 link1783 link1784 link1785 link1786 link1787 link1788 link1789 link1790 link1791 link1792 link1793 link1794 link1795 link1796 link1797 link1798 link1799 link1800 link1801 link1802 link1803 link1804 link1805 link1806 link1807 link1808 link1809 link1810 link1811 link1812 link1813 link1814 link1815 link1816 link1817 link1818 link1819 link1820 link1821 link1822 link1823 link1824 link1825 link1826 link1827 link1828 link1829 link1830 link1831 link1832 link1833 link1834 link1835 link1836 link1837 link1838 link1839 link1840 link1841 link1842 link1843 link1844 link1845 link1846 link1847 link1848 link1849 link1850 link1851 link1852 link1853 link1854 link1855 link1856 link1857 link1858 link1859 link1860 link1861 link1862 link1863 link1864 link1865 link1866 link1867 link1868 link1869 link1870 link1871 link1872 link1873 link1874 link1875 link1876 link1877 link1878 link1879 link1880 link1881 link1882 link1883 link1884 link1885 link1886 link1887 link1888 link1889 link1890 link1891 link1892 link1893 link1894 link1895 link1896 link1897 link1898 link1899 link1900 link1901 link1902 link1903 link1904 link1905 link1906 link1907 link1908 link1909 link1910 link1911 link1912 link1913 link1914 link1915 link1916 link1917

[Vue.js] Laravel Passport with Vue.js SPA

If I use create fresh API token, do I (not) need to set the token in a cookie from Vue.js app? I saw many examples with Laravel Passport, but all of them show back feature only, without front.

Solution :

There are various ways of doing the same, you can use cookies or local storage,
Laravel Password mostly validates the request using token so if you are using vue.js Auth at front end you can define a constructor to send the token every time you send a request.

constructor() {

let userToken = window.localStorage.getItem(‘token’);
let userData = window.localStorage.getItem(‘user’);
if (typeof userToken !== ‘undefined’ || typeof userData !== ‘undefined’) {
this.user = userData;
this.token = userToken;
} else {
this.user = null;
this.token = null;
}
if (this.token !== null && this.token !== ‘undefined’) {
axios.defaults.headers.common[‘Authorization’] = ‘Bearer ‘ + this.token;

} else {
this.authenticated = false;
this.logout();
}

Solution 2:

i use this in app.js

if (store.state.user.token !== undefined) {
axios.defaults.headers.common[‘Authorization’] = “Bearer “ + store.state.user.token
}

but for what createFreshApiToken then?

[Vue.js] Dropdown not being populated from HTTP response

when new to making HTTP calls. when trying to populate (specific) properties of each object into the dropdown but it is not being populated, I tried a couple of things i.e for loop

created(){
axios
.get(“https://jsonplaceholder.typicode.com/posts")
.then(res => {
let result = res.data
for(i = 0; i <= result.length;i++){
this.todos = result[i];
}
})
}

Meanwhile I also tried to log out one single value in the response in <li> which display fine.

<ul>
{user.todos}
</ul>

but when I try to use v-for in select of the dropdown, it doesn’t e.g

<select name=”” id=””>
<option value=”” selected disabled>Please Select..</option>
<option value=”” v-for=”todo in user.todos”>{todo}</option>
</select>

Here is my full codepen. What am I missing/doing wrong?

Solution :

This is how you can make it work:

new Vue({
el: “#app”,
data: {
user: {
todos: []
}
},
created(){
axios
.get(“https://jsonplaceholder.typicode.com/posts")
.then(res => {
cosnt result = res.data

for(i = 0; i <= result.length;i++){
this.user.todos.push(result[i].title);
}
})
}
})

this.user.todos should be an array, if you assign a single value to it you won’t be able to loop it to populate the select options.

[Vue.js] Vue Component, assign computed property to data

i’m trying to set a component’s data to a computed property value, as this fetches some localStorage data and manipulates it slightly.

I would then once the component is mounted listen for changes within the localStorage, and if my key is updated then fetch this value again, run it through my computed property and pass it back to the view.

However i’m getting the following error:

ReferenceError: ids is not defined
at a.render (vue.js:4)
at a.e._render (vue:6)
at a.r (vue:6)
at un.get (vue:6)
at new un (vue:6)
at vue:6
at a.bn.$mount (vue:6)
at a.bn.$mount (vue:6)
at init (vue:6)
at vue:6

This is my component:

Vue.component(‘favourites-button’, {
render() {
return this.$scopedSlots.default({
count: this.ids.length
});
},
data: function() {
return {
ids: this.getFavourites()
}
},
mounted() {
const self = this;
Event.listen(‘favourites-updated’, function (event) {
console.log(‘updated external’);
});
window.addEventListener(‘storage’, function (e) {
if (e.key === ‘favourites’) {
console.log(‘updated’);
self.ids = self.getFavourites();
}
});
},
methods: {
getFavourites: function() {
let favourites = localStorage.getItem(‘favourites’);
return favourites.split(‘,’).filter(id => !!id);
}
}
});

Edit:

Updated my code, getting the same error however when the storage change event is fired.

Edit 2:

Turns out my template was expecting toggle within my scope but I removed this from my $scopedSlots.

Solution :

Computed properties work on data/props, so you cant use them in data itself.

Instead, just set the default value of the data key to whats in local storage:

data: function () {
return {
ids: function() {
let favourites = localStorage.getItem(‘favourites’);
return favourites.split(‘,’).filter(id => !!id);
}
};
}

Solution 2:

You can use computed properties for this, but you’d have to define a getter and a setter.

computed: {
fullName: {
// getter
get: function () {
return localStorage.getItem(‘favourites’)
},
// setter
set: function (newValue) {
localStorage.setItem(‘favourites’, newValue)
}
}
}

Much cleaner imo than using the mounted callback, setting data and then watching for changes.

[Vue.js] Draw data in graphics generated by Chart JS

Good afternoon.
I’m working with Chart JS and I’m trying to show the existing total per column in a bar graph.

In the backend I use Laravel as a framework and the data I pass from the controller through the $datacount variable.

This is my query in the controller:

$datacount = DB::table(‘topics’)
->leftJoin(‘proposals_topics’, ‘topics.id’, ‘=’, ‘proposals_topics.topic_id’)
->select(‘topics.name as tpcname’, ‘proposals_topics.topic_id’, \DB::raw(‘count(topic_id) as total’))
->groupBy(‘topics.name’, ‘proposals_topics.topic_id’)
->orderBy(‘topic_id’, ‘desc’)
->get();

The data of the variable I receive in this script:

<script>
var datacount = <?= json_encode($datacount, JSON_PRETTY_PRINT); ?>;

console.log(datacount);

// Bar chart
new Chart(document.getElementById(“bar-chart”), {
type: ‘bar’,
data: {
labels: [“Compras y Contrataciones”, “Acceso a la Informacin”, “Educacin”, “Organismos de Control”, “Servicio Civil”, “Infraestructura”, “Energa”, “Gestin Financiera”, “Salud”, “Agua”],
datasets: [
{
label: “Cantidad generada”,
backgroundColor: [“#3e95cd”, “#8e5ea2”,”#3cba9f”,”#e8c3b9”,”#c45850”,”#ffc344”,”#ff8e17”, “#ff4cd8”,”#ffea4c”,”#b7ff4c”],
data: [datacount.total]
}
]
},
options: {
legend: { display: false },
title: {
display: true,
text: ‘Datos generados por eje temtico.’
}
}
});
</script>

when receiving the results in the console, but I can not show the data of the array.

Solution :

You can put the data from the PHP script in the data fields with:

Solution 2:

After reading a bit about Laravel documentation and Javascript, I found a solution to draw the data on the graph.

In the script I structured the foreach based on the documentation on loops at https://laravel.com/docs/5.7/blade#if-statements.

<script>
//console.log(datacount);

// Bar chart
new Chart(document.getElementById(“bar-chart”), {
type: ‘bar’,
data: {
labels: [
@foreach($datacount as $dt)
“{ $dt->tpname }”,
@endforeach
],
datasets: [
{
label: “Cantidad generada”,
backgroundColor: [“#3e95cd”, “#8e5ea2”,”#3cba9f”,”#e8c3b9”,”#c45850”,”#ffc344”,”#ff8e17”, “#ff4cd8”,”#ffea4c”,”#b7ff4c”],
data: [
@foreach($datacount as $dt)
{!! $dt->total !!},
@endforeach
],
}
]
},
options: {
legend: { display: false },
title: {
display: true,
text: ‘Ejes temticos por cantidad de propuestas.’
}
}
});
</script>

Also seeing some examples at: https://quickadminpanel.com/pages/reports-generator-module

[Vue.js] How to do a search filter on a multidimensional json object with vue.js

there is a structure in json this way (I can not change the data in this json):

itens: {“countcats”:2,”countsubcats”:7,
“catsubcatsdata”:{
“15978738e6cd1e”:{“title”:”Test 1”,”description”:”blablabla”,
“subcats”:{
“1597873b1653d9”: {“codurl”:”t01url”,”title”:”Teste subiten 1”,”description”:””},
“1597873bd76c80”: {“codurl”:”t01url2”,”title”:”Testing sub two”,”description”:””},
“1597873c9d4a81”: {“codurl”:”t01url3”,”title”:”Test sub 3”,”description”:”blablabla 01”},
},
“15978745b32c1b”:{“title”:”Loren Ipsun”,”description”:”lamet dectoid samet”,
“subcats”:{
“159787464bc887”:{“codurl”:”maecenas”,”title”:”Maecenas pulvinar”,”description”:”orci non volutpat varius”},
“159787472eb5e6”:{“codurl”:”donecorci “,”title”:”Donec hendrerit orci”,”description”:””},
“15978748b89bca”:{“codurl”:”massadictum”,”title”:”Nullam eu massa dictum”, “description”:””},
“159787495492f4”:{“codurl”:”ultricies”,”title”:”Etiam massa arcu”,”description”:”Donec ultricies porttitor augue quis dictum. Quisque efficitur nec sapien eu ultricies”}
}
}

there is the following code:

<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”v-for-sectors”>
<input type=”text” placeholder=”Search” v-model=”searchQuery”>

<ul>
<li v-for=”(value, key) in filteredList”>
<b>{ value.title }</b><br>{ value.description }
<ul>
<li v-for=”(vsub, keysub) in value.subcats”><a v-bind:href=”‘http://www.teste.com/'+vsub.codurl">{ vsub.title } - { vsub.description }</a></li>
</ul>
</li>
</ul>
</div>

<script>
new Vue({
el: ‘#v-for-sectors’,
data: {
searchQuery: ‘’,
itens: {“catsubcatsdata”:{“15978738e6cd1e”:{“title”:”Test 1”,”description”:”blablabla”,”subcats”:{“1597873b1653d9”:{“codurl”:”t01url”,”title”:”Teste subiten 1”,”description”:””},”1597873bd76c80”:{“codurl”:”t01url2”,”title”:”Testing sub two”,”description”:””},”1597873c9d4a81”:{“codurl”:”t01url3”,”title”:”Test sub 3”,”description”:”blablabla 01”}},”15978745b32c1b”:{“title”:”Loren Ipsun”,”description”:”lamet dectoid samet”,”subcats”:{“159787464bc887”:{“codurl”:”maecenas”,”title”:”Maecenas pulvinar”,”description”:”orci non volutpat varius”},”159787472eb5e6”:{“codurl”:”donecorci”,”title”:”Donec hendrerit orci”,”description”:””},”15978748b89bca”:{“codurl”:”massadictum”,”title”:”Nullam eu massa dictum”,”description”:””},”159787495492f4”:{“codurl”:”ultricies”,”title”:”Etiam massa arcu”,”description”:”Donec ultricies porttitor augue quis dictum.”}}}
},
computed: {
filteredList: function () {
var filterKey = this.searchQuery && this.searchQuery.toLowerCase()
var data = this.itens.catsubcatsdata
var dataarray = Object.keys(data)

if (!filterKey) { return data; }

return dataarray
.filter(function(key) {
var row = data[key];

return Object.keys(row)
.some(function(key) {
return String(row[key])
.toLowerCase()
.indexOf(filterKey) > -1;
})
})
.reduce(function(acc, key) {
acc[key] = data[key];

return acc;
}, {})
}
}
});
</script>

I would like it when typing in the search something about the title or description of the category displaying something like this:

(This is already working.)

But when the word was from the title or description of a subcategory, it should show:

(This is not working.)

Can anyone help me on how to make this work?

Solution :

As I understand it, you want to filter by the search term, including the entire entry for any that match title or description in the top-level, or including the top-level and only matching sub-levels that match if the match is in a sub-level and not in the top level.

So first I made a method matches so that code isn’t messy.
Then I made a computed to return the values of interest as a list.
Then I made a computed to filter those values based on the criteria above, constructing a new object with only matching subcats when that was where the match was.

new Vue({
el: ‘#v-for-sectors’,
data: {
searchQuery: ‘’,
itens: {
“catsubcatsdata”: {
“15978738e6cd1e”: {
“title”: “Test 1”,
“description”: “blablabla”,
“subcats”: {
“1597873b1653d9”: {
“codurl”: “t01url”,
“title”: “Teste subiten 1”,
“description”: “”
},
“1597873bd76c80”: {
“codurl”: “t01url2”,
“title”: “Testing sub two”,
“description”: “”
},
“1597873c9d4a81”: {
“codurl”: “t01url3”,
“title”: “Test sub 3”,
“description”: “blablabla 01”
}
}
},
“15978745b32c1b”: {
“title”: “Loren Ipsun”,
“description”: “lamet dectoid samet”,
“subcats”: {
“159787464bc887”: {
“codurl”: “maecenas”,
“title”: “Maecenas pulvinar”,
“description”: “orci non volutpat varius”
},
“159787472eb5e6”: {
“codurl”: “donecorci”,
“title”: “Donec hendrerit orci”,
“description”: “”
},
“15978748b89bca”: {
“codurl”: “massadictum”,
“title”: “Nullam eu massa dictum”,
“description”: “”
},
“159787495492f4”: {
“codurl”: “ultricies”,
“title”: “Etiam massa arcu”,
“description”: “Donec ultricies porttitor augue quis dictum.”
}
}
}
}
}
},
methods: {
matches(obj) {
const term = this.searchQuery.toLowerCase();

return obj.title.toLowerCase().includes(term) || obj.description.toLowerCase().includes(term);
}
},
computed: {
listValues() {
return Object.values(this.itens.catsubcatsdata);
},

filteredList() {
if (!this.searchQuery) {
return this.listValues;
}

return this.listValues
.map((v) => {
if (this.matches(v)) {
return v;
}

const matchingSubcats = Object.values(v.subcats)
.filter((v) => this.matches(v));

if (matchingSubcats.length > 0) {
return Object.assign({}, v, {subcats: matchingSubcats});
}
})
.filter((v) => v);
}
}
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”v-for-sectors”>
<input type=”text” placeholder=”Search” v-model=”searchQuery”>
<ul>
<li v-for=”value in filteredList”>
<b>{ value.title }</b><br>{ value.description }
<ul>
<li v-for=”(vsub, keysub) in value.subcats”><a v-bind:href=”‘http://www.teste.com/'+vsub.codurl">{ vsub.title } - { vsub.description }</a></li>
</ul>
</li>
</ul>
</div>

[Vue.js] Audio is blocked for 'autoplay' after clicking play?

I’m building a vue.js app that plays music. Here is the relevant HTML

<template>
<div class=”container”>
<button type=”button” ref=”play” class=”btn btn-primary”>
<font-awesome-icon id=”playIcon” icon=”play” />
</button>
<audio ref=”audio”></audio>
</div>
</template>

And here is the method to play music. The source of the audio is correctly set in an earlier function.

togglePlay(update) {
if (this.isLoaded != true) {
return;
}

if (this.isPlaying == true) {
this.audioDOM.pause();
this.isPlaying = false;
if (update) {
this.sendUpdate();
}
} else {
this.audioDOM.play();
this.isPlaying = true;
if (update) {
this.sendUpdate();
}
}
}

In the mounted() portion of the vue.js component, there is this:

this.playBtn.addEventListener(“click”, () => {
this.togglePlay(true);
}, false);

However, it does not start the audio because it throws an autoplay error when it reaches the line this.audioDOM.play() and says I need to prompt the user for input. However, clearly the user is providing input, by clicking the play button! What do I need to change?

Solution :

You need to pass the event to this.togglePlay. The event has to exist in the context of the calling function otherwise it won’t know that it was triggered by the user.

Try this

<template>
<div class=”container”>
<button
type=”button”
@click=”togglePlay($event)” <!– here there is added @click as an event handler –>
class=”btn btn-primary”
\>
<font-awesome-icon id=”playIcon” icon=”play” />
</button>
<audio ref=”audio”></audio>
</div>
</template>
<script>
export default {
methods :{
togglePlay(ev) { //since update is always true we don’t need it,
if (this.isLoaded != true) { // lets get the event instead
return;
}

if (this.isPlaying == true) {
this.audioDOM.pause();
this.isPlaying = false;
this.sendUpdate();
} else {
this.audioDOM.play();
this.isPlaying = true;
this.sendUpdate()
}
}

}
}

<script>

Solution 2:

Awkward. Turns out the error was a DOMException because I had set the source wrong. Whoops!

[Vue.js] I am trying to pass user id from my blade template to Vue for Axios post request to the server

However when I click the button only the first button contains the user id the rest returns null. Also depending on where I place my id tag on HTML the data-id is empty. How can I pass data from my blade view to Vue.js for an Axios post request which contains the post Id ?

const app = new Vue({
el: ‘#like’,
data: {
post_id: ‘’,
},

methods: {
whichId: function(event) {
this.post_id = this.$el.getAttribute(‘data-id’);
console.log(this.$el.getAttribute(‘data-id’));
}
}
})

<div class=”container” id=”like”>
<table class=”table mt-5”>
<tbody>
@foreach ($posts as $post)
<tr>
<td><img src=”images/profil.svg” class=”rounded-circle border border-dark ml-2” width=”60” height=”60” alt=””></td>
<td>{ $post->username->name }</td>
<td>{ $post->content }</td>
<td>
<button v-on:click=”whichId” data-id=”{ $post->id }”>
<img src=”/images/heart.svg” width=”30” height=”30” />
</button>
</td>
<td>{ $post->created_at->diffForHumans() }</td>
</tr>
@endforeach
</tbody>
</table>
</div>

Solution :

The this.$el is going to refer to the element. When using PHP to iterate through records. You should pass the id through the click event handler. Thanks to Wilk Randall on laracast for the help.

methods: {
whichId (postId) {
console.log(postId);
}
}
<td><button v-on:click=”whichId({ $post->id })”<img src=”/images/heart.svg” width=”30”></button></td>

[Vue.js] Do I need a unit-testing framework if I'm already using Cypress in a Vue.js app?

When scaffolding a new project with the Vue.js CLI, it offers a choice of both unit-testing and E2E-testing frameworks.

Unit-testing functionality is perfectly adequate in Cypress. My question, then: is there an advantage to using a distinct unit-testing framework if I’m already using Cypress?

Solution :

Cypress is in the process of tackling unit (aka component) testing, but at the moment Jest has it beat for vuejs unit testing. (React is another story, see cypress-react-unit-test)

check out this tutorial here for unit testing vuejs with Jest

From the link above, some advantages over Cypress are:

Built in code coverage
Snapshot testing
Module mocking utilities

Also see repo for vue-test-utils

[Vue.js] Vue.js component not getting the value from a variable

I’m new to Vue.js and in my laravel app Im using this component https://github.com/saintplay/vue-swatches is working fine the problem is that there is an edit form and to pass the value (color in HEX) from a variable to the component as a selected like value=”{$var->hex_color}.

This is my app.js

const d_app = new Vue({
el:’#d_app’,
components: {
Swatches,
},
data:{
color:’#ffffff’,
},
});

This is my form

<swatches v-model=”color” colors=”text-advanced” value=”{$var->hex_color}”></swatches>

When I load the page it shows the default color #ffffff instead of the $var->hex_color.

Solution :

To pass value from Laravel to vue.js component, encode it first.

Laravel:

<swatches :value=”{ json_encode($var->hex_color) }”></swatches>

notice “:” on the property name.
Now, let’s accept that with Vue.


export default {
props: [‘value’]
}

Now, you should be able to print the prop value:

<p>{ value }</p>

console.log(this.value) // the hexa value passed from Laravel.

Solution 2:

You have v-model indicated which already means that you are passing “value” to it and on change it should emit “input” event

<swatches v-model=”color” colors=”text-advanced” value=”{$var->hex_color}”></swatches>

That’s where the default #ffffff color is coming from, I suppose.

I think, if you remove v-model from there and leave only :value like this:

<swatches colors=”text-advanced” :value=”{$var->hex_color}”></swatches>

It might work. Have you tried it?

Or you can pass color to v-model directly:

<swatches colors=”text-advanced” v-model=”{$var->hex_color}”></swatches>

[Vue.js] Sharing assets and components between Vue projects

there is 2 vue.js applications and they both need to use some common pages and assets (scss files, icons etc.).

The pages they need to share are full pages with access to vuex store and async calls.

What I think to do is to create a single vue.js app (with the cli) and put both the apps in it and have a shared folder:

vue-project
- src
- app1
- app2
- shared

But then there is a problem: How do I build/run each app separately?

Solution :

There will be a file level/source control solution to allow you to synchronise copies of the shared component in the two projects. If you’re using Git, look at shared submodules.

There is strong potential here for a nightmare. You’ve described it so well I think you’re secretly aware. Reusable components (reusable across projects) shouldn’t have a dependency on a vuex store, which is application specific. I would look at putting the store calls in a project-specific wrapper component, then passing them to the shared component as props. Reusable components shouldn’t have any interaction with their environment apart from props and events, according to me.