link1644 link1645 link1646 link1647 link1648 link1649 link1650 link1651 link1652 link1653 link1654 link1655 link1656 link1657 link1658 link1659 link1660 link1661 link1662 link1663 link1664 link1665 link1666 link1667 link1668 link1669 link1670 link1671 link1672 link1673 link1674 link1675 link1676 link1677 link1678 link1679 link1680 link1681 link1682 link1683 link1684 link1685 link1686 link1687 link1688 link1689 link1690 link1691 link1692 link1693 link1694 link1695 link1696 link1697 link1698 link1699 link1700 link1701 link1702 link1703 link1704 link1705 link1706 link1707 link1708 link1709 link1710 link1711 link1712 link1713 link1714 link1715 link1716 link1717 link1718 link1719 link1720 link1721 link1722 link1723 link1724 link1725 link1726 link1727 link1728 link1729 link1730 link1731 link1732 link1733 link1734 link1735 link1736 link1737 link1738 link1739 link1740 link1741 link1742 link1743 link1744 link1745 link1746 link1747 link1748 link1749 link1750 link1751 link1752 link1753 link1754 link1755 link1756 link1757 link1758 link1759 link1760 link1761 link1762 link1763 link1764 link1765 link1766 link1767 link1768 link1769 link1770 link1771 link1772 link1773 link1774 link1775 link1776 link1777 link1778 link1779 link1780

[Vue.js] The localStorage is not refreshing in Vuex

I write codes with Vuex to login and logout in my Laravel single page application it’s working well but when i login to an account the profiles information (name, address, Email, …)doesn’t show in profile but after i reload the page the profile information loads, and when another user try the profile the data of the last person that login shown to him/her

auth.js:

export function registerUser(credentials){
return new Promise((res,rej)=>{
axios.post(‘./api/auth/register’, credentials)
.then(response => {
res(response.data);
})
.catch(err => {
rej(‘Somthing is wrong!!’)
})
})
}

export function login(credentials){
return new Promise((res,rej)=>{
axios.post(‘./api/auth/login’, credentials)
.then(response => {
res(response.data);
})
.catch(err => {
rej(‘The Email or password is incorrect!’)
})
})
}

export function getLoggedinUser(){
const userStr = localStorage.getItem(‘user’);

if(!userStr){
return null
}

return JSON.parse(userStr);
}

store.js:

import {getLoggedinUser} from ‘./partials/auth’;
const user = getLoggedinUser();
export default {
state: {
currentUser: user,
isLoggedIn: !!user,
loading: false,
auth_error: null,
reg_error:null,
registeredUser: null,
},
getters: {
isLoading(state){
return state.loading;
},
isLoggedin(state){
return state.isLoggedin;
},
currentUser(state){
return state.currentUser;
},
authError(state){
return state.auth_error;
},
regError(state){
return state.reg_error;
},
registeredUser(state){
return state.registeredUser;
},

},
mutations: {
login(state){
state.loading = true;
state.auth_error = null;
},
loginSuccess(state, payload){
state.auth_error = null;
state.isLoggedin = true;
state.loading = false;
state.currentUser = Object.assign({}, payload.user, {token: payload.access_token});

localStorage.setItem(“user”, JSON.stringify(state.currentUser));
},
loginFailed(state, payload){
state.loading = false;
state.auth_error = payload.error;
},
logout(state){
localStorage.removeItem(“user”);
state.isLoggedin = false;
state.currentUser = null;
},
registerSuccess(state, payload){
state.reg_error = null;
state.registeredUser = payload.user;
},
registerFailed(state, payload){
state.reg_error = payload.error;
},
},
actions: {
login(context){
context.commit(“login”);
},
}
};

general.js:

export function initialize(store, router) {
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const currentUser = store.state.currentUser;

if(requiresAuth && !currentUser) {
next(‘/login’);
} else if(to.path == ‘/login’ && currentUser) {
next(‘/‘);
} else {
next();
}

if(to.path == ‘/register’ && currentUser) {
next(‘/‘);
}

});

axios.interceptors.response.use(null, (error) => {
if (error.resposne.status == 401) {
store.commit(‘logout’);
router.push(‘/login’);
}

return Promise.reject(error);
});

if (store.getters.currentUser) {
setAuthorization(store.getters.currentUser.token);
}
}

export function setAuthorization(token) {
axios.defaults.headers.common[“Authorization”] = `Bearer ${token}`
}

I think that this issue is relate to my localstorage, how can i fix this?
I’m novice at the vue.js and don’t have any idea what is the problem.

Login Component:

<template>
<main>
<form @submit.prevent=”authenticate”>
<div class=”grid-x grid-padding-x”>

<div class=”small-10 small-offset-2 cell” v-if=”registeredUser”>
<p class=”alert success”>Welcome {registeredUser.name}</p>
</div>
<div class=”small-10 small-offset-2 cell” v-if=”authError”>
<p class=”alert error”>
{authError}
</p>
</div>

<div class=”small-2 cell”>
<label for=”email” class=”text-right middle”>Email:</label>
</div>
<div class=”small-10 cell”>
<input type=”email” v-model=”formLogin.email” placeholder=”Email address”>
</div>

<div class=”small-2 cell”>
<label for=”password” class=”text-right middle”>Password:</label>
</div>
<div class=”small-10 cell”>
<input type=”password” v-model=”formLogin.password” placeholder=”Enter password”>
</div>

<div class=”small-10 small-offset-2 cell”>
<div class=”gap”></div>
<input type=”submit” value=”Login” class=”button success expanded”>
</div>
</div>

</form>

</main>

</template>

<script>
import {login} from ‘../../partials/auth’;
export default {
data(){
return {
formLogin: {
email: ‘’,
password: ‘’
},
error: null
}
},
methods:{
authenticate(){
this.$store.dispatch(‘login’);

login(this.$data.formLogin)
.then(res => {
this.$store.commit(“loginSuccess”, res);
this.$router.push({path: ‘/profile’});
})
.catch(error => {
this.$store.commit(“loginFailed”, {error});
})
}
},
computed:{
authError(){
return this.$store.getters.authError
},
registeredUser(){
return this.$store.getters.registeredUser
}
}
}
</script>

Solution :

Localstorage data is once loaded on page load, so when you use setItem, this won’t be visible until the next time.

You should store the data to vuex store, and use that as the source. Only set and get the data from localstorage on page loads.

Otherwise use something like: https://github.com/robinvdvleuten/vuex-persistedstate

[Vue.js] Sub-components in Vue functional components

As I was playing around with functional components in Vue, I realized that the components property isn’t supported to declare sub-components for functional components. Trying do so will result in an Unknown custom element exception.

Except for using global components, is there any way to use sub-components in functional components?

Solution :

It is a bit of a workaround, but this Github comment suggest using inject instead to inject the component.

<template functional>
<div>
<component :is=”injections.components.SomeChildren”></component>
</div>
</template>

<script>
import SomeChildren from “./SomeChildren.vue”;
export default {
inject: {
components: {
default: {
SomeChildren
}
}
}
};
</script>

Not as simple as for regular components, but it does the job.

[Vue.js] Javascript array issue with vue-infinite-loading

when trying to implement Infinite Loading using vue-InfiniteLoading component.
when getting an array everytime I scroll and I try to push the contents from the array to another array when I get the data. When I used push, I see new elements on screen but no images and infomation..

I tried push, concat and foreach, none of them worked for me. response.data.data.data is the array containin new elements and dorms is the main array shown on UI.

I also tried push (…response.data.data.data)

.get(`/site/cities/dorms/istanbul?page=${self.page}`)
.then(response => {
if (response.data.data.data) {
this.page += 1;
// var myArray = self.dorms;
// self.dorms = myArray .concat(response.data.data.data);
// self.dorms.push(response.data.data.data[1]);
/* response.data.data.data.forEach(item => {
self.dorms.push(item);
}); */
self.dorms.push(…response.data.data.data);

//self.dorms = response.data.data.data;
self.popupDorms = response.data.data.popups;
$state.loaded();
} else {
$state.complete();
}
});

I expect all informatin within array pushed but it doesnt work.

Solution :

We can write a small function that checks scroll position and fires an ajax call to get more data or just get the next slot of data from the JSON object and bind it to HTML. something as below:

$(window).scroll(function() {
if($(window).scrollTop() == $(document).height() - $(window).height()) {
// ajax call or some other logic to show data here
}
});

Or you can use one of the plugins that are available, when myself using “Waypoint” for one of the same things.

Solution 2:

You could do:

self.dorms = […self.dorms, …response.data.data.data]

or

self.dorms = [].concat(self.dorms, response.data.data.data)

or

self.dorms.push(…response.data.data.data)

all result in the same result. the error should be somewhere else.

[Vue.js] Find duplicates in Laravel Eloquent

The following code there is on the controller is below.

public function add(Request $request)
{
$request->validate([
‘userSelected’ => ‘required’,
‘projectSelected’ => ‘required’,
]);

$researcherToProject = new ProjectResearchers();
$researcherToProject->user_id = $request->userSelected;
$researcherToProject->project_id = $request->projectSelected;
$researcherToProject->created_at = Carbon::now();
$researcherToProject->updated_at = Carbon::now();
$researcherToProject->save();

return new ProjectsResearchersResource($researcherToProject);
}

Should I make another validation or create a function?

Ex: I create a user id “5” with project id “13” and user id “2” with project id “17”. If I try creating again a user id “5” with project id “13” it allows me, so I get two times the same data in the database. How do I avoid duplicate entries?

Solution :

You can do it using updateOrCreate method, the first array is the unique values that you are looking for, if not found it will create the entry, if it finds them it will just update the fields in the second array so do this instead:

public function add(Request $request){

$request->validate([
‘userSelected’ => ‘required’,
‘projectSelected’ => ‘required’,
]);

$researcherToProject = ProjectResearchers::updateOrCreate(
[‘user_id’ => $request->userSelected, ‘project_id’ => $request->projectSelected],
[‘created_at’ => Carbon::now(), ‘updated_at’ => Carbon::now()]
);

return new ProjectsResearchersResource($researcherToProject);
}

or if you don’t want to update at all, you can just check if it exists before storing:

public function add(Request $request){

$request->validate([
‘userSelected’ => ‘required’,
‘projectSelected’ => ‘required’,
]);

$researcherToProject = new ProjectResearchers();

if( ! ProjectResearchers::where(‘user_id’, $request->userSelected)->where(‘project_id’, $request->projectSelected)->exists()) {
$researcherToProject = new ProjectResearchers();
$researcherToProject->user_id = $request->userSelected;
$researcherToProject->project_id = $request->projectSelected;
$researcherToProject->created_at = Carbon::now();
$researcherToProject->updated_at = Carbon::now();

$researcherToProject->save();
} else {
$researcherToProject = ProjectResearchers::where(‘user_id’, $request->userSelected)->where(‘project_id’, $request->projectSelected)->first();
}

return new ProjectsResearchersResource($researcherToProject);
}

Solution 2:

Additionaly to @nakov answer:

firstOrCreate() can combine 2 ways and looks cleaner:

public function add(Request $request){
$request->validate([
‘userSelected’ => ‘required’,
‘projectSelected’ => ‘required’,
]);

$researcherToProject = ProjectResearchers::firstOrCreate([
‘user_id’ => $request->userSelected,
‘project_id’ => $request->projectSelected
]);

$researcherToProject->created_at = Carbon::now();
$researcherToProject->updated_at = Carbon::now();
$researcherToProject->save();

return new ProjectsResearchersResource($researcherToProject);
}

Or if you don’t want to update:

public function add(Request $request){
$request->validate([
‘userSelected’ => ‘required’,
‘projectSelected’ => ‘required’,
]);

$researcherToProject = ProjectResearchers::firstOrCreate([
‘user_id’ => $request->userSelected,
‘project_id’ => $request->projectSelected
]);

if(!$researcherToProject->id){
$researcherToProject->created_at = Carbon::now();
$researcherToProject->updated_at = Carbon::now();
$researcherToProject->save();
}

return new ProjectsResearchersResource($researcherToProject);
}

Solution 3:

change the following:

$request->validate([
‘userSelected’ => ‘required’,
‘projectSelected’ => ‘required’,
]);

to

$request->validate([
‘userSelected’ => ‘required’,
‘projectSelected’ => ‘required|unique:ProjectResearchers,project_id,NULL,id,user_id,’.$request->userSelected
]);

this will work check if the combination of user-project already exists inthe table called ProjectResearchers.
for more information about the unique validation rule visit the Laravel Documentation.

[Vue.js] VueJS block activity on not active browser tab

there is a web app written in Typescript and VueJS that execute a collection of tasks (ajax requests) and to track the whole process (and to execute one task after another) I use a vue.js instance as bus to notify changes between components.
If the user open a new browser tab, the process stop. If the user come back, the process resumes.

The issue is present in Firefox and in Chrome.
I put in my code a simple window.setInterval to log every 2 seconds an ‘Hello’ and…surprise there is an ‘Hello’ every 2 seconds without any temporal ‘hole’.
I see a very old issue in github for a similar situation: https://github.com/vuejs/Discussion/issues/76 but seems to be too old to be this.

I expect that the process doesn’t stop but continues without interruptions..

Solution :

https://developers.google.com/web/updates/2017/03/background\_tabs

Background tabs can have a dramatic negative effect on browser performance, especially on battery life. To mitigate this, Chrome has been placing various restrictions on background tabs for the last several years. Recently theres been a number of efforts to make further improvements, and this document gives an overview of the Chrome policy. This document focuses on describing current policies in Chrome 57. Long-term strategy and further plans can be found in this document.

https://www.chromestatus.com/feature/6172836527865856

As an intervention we want to limit how much CPU a background page is allowed to use and to throttle timer queues when this limit is violated. Current target is that background page CPU load level should be under 1%.

[Vue.js] Get specific value from a Array of JSON object and push it to another array?

when using Vue.js, there is an Array of JSON Object, How can I push the ‘c’ and ‘d’ to selected1 and push the ‘88’ and ‘66’ to selected2?

export default {
arr:[{
“name”: “a”,
“options”: [{
label: “b”,
value: 9,
foodoption: [{ label: “c”, value: 8 }, { label: “d”, value: 6 }],
selected1: [],
show: false
},

]},
{
“name”: “aa”,
“options”: [{
label: “bb”,
value: 9,
foodoption: [{ label: “cc”, value: 88 }, { label: “dd”, value: 66 }],
selected2: [],
show: false
},
]}
]

expect get:

selected1:[c,d]

selected2:[88,66]

I try to use vue.js to get the value in the view:

<div v-for=”(obj, index) in arr” :key=”index” >
<div v-for=”(opt, index) in obj.foodoption” :key=”index”>
{ opt.label } { opt.value}
</div>
</div>

How can I get each expects item by JavaScript?

Solution :

This is purely a JS question, you don’t need VueJS to do that. Simply use a combination of dot and bracket notation to access the foodoption value in the arr, and then use Array.prototype.map to return the desired values based on the key (label or value):

const arr = [{
“name”: “a”,
“options”: [{
label: “b”,
value: 9,
foodoption: [{ label: “c”, value: 8 }, { label: “d”, value: 6 }],
selected1: [],
show: false
},

]},
{
“name”: “aa”,
“options”: [{
label: “bb”,
value: 9,
foodoption: [{ label: “cc”, value: 88 }, { label: “dd”, value: 66 }],
selected2: [],
show: false
},
]}
];

const selected1 = arr[0].options[0].foodoption.map(opt => opt.label);
const selected2 = arr[1].options[0].foodoption.map(opt => opt.value);

console.log(selected1);
console.log(selected2);

[Vue.js] Vue is not updating select in DOM after created method

there is this roles array, in created method I made a call to dispatch and get roles from api call, so I suppose it should load with created function.

Now I use console.log to print roles after dispatching getRoles adn it prints already but it doesn’t update in the DOM.

If you notice this part where I just show {roles} inside the component after form and dropdown, this part and select updates after I make small change in the component and save, after hot reload it shows the data but not with first time with created

The problem is that, data gets fetched and printed in first load but the roles array doesn’t get updated in the DOM.

<template>
<div class=”container”>
<form class=”card offset-3 col-6 text-center border border-light p-5”>
<div class=”form-group”>
<label for=”formGroupExampleInput”>Roles</label>
</div>

<select class=”browser-default custom-select”>
<option selected>Choose a role to assign permissions</option>
<option v-for=”role in roles” key=”role.display_name” value=”1”> {role.name} </option>
</select>

</form>
roles :{ roles }
</div>
</template>

<script>
export default {
data: {
return: {
roles: []
}
},
created() {
this.$store
.dispatch(‘getRoles’)
.then(() => {
this.roles = this.$store.getters.getRoles
console.log(‘roles’, this.roles)
})
.catch(() => {
console.log(‘roles request failed’)
})
}
}
</script>

Solution :

The problem was in returning data so I replaced it with

data: () => ({
roleName: ‘’,
roles: []
})

and it is working fine now

[Vue.js] How to change v-model value from JS

I’m using Google autocomplete address form. I found example at google official web page. Everything is fine. Everything works! but it’s native Javascript,

there is vue.js application and I don’t like how I change text input values from JS script. The idea is that when I change something in main input, JS event listener should change values for other inputs:

document.getElementById(addressType).value = val;

Problem is that I should use “document” to change values:

document.getElementById(‘street_number’).value

I would like to have something like tat:

<input type=”text” v-model=”input.address” ref=”addressRef”>

And to read values:

export default {
data() {
return {
input: {
address: “”,

}

};
},
methods: {
test() {
console.log(this.input.address);
console.log(this.$refs.addressRef);
}
}

So the question is:

How to set the value from JS code to update binding values? Right now values are null because I use “getElementById(“id”).value = val”

Solution :

You can emit input event afterwards which v-model relies on for updating its value:

let el = document.getElementById(“id”);
el.value = val;
el.dispatchEvent(new Event(‘input’));

In action:

Vue.config.devtools = false

const app = new Vue({
el: ‘#app’,

data: {
message: null
},

methods: {
updateBinding() {
let el = document.getElementById(“input”);
el.value = ‘Hello!’;
el.dispatchEvent(new Event(‘input’));
}
}
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”app”>
<button @click=”updateBinding”>Click me </button><br>
<input id=”input” v-model=”message” placeholder=”edit me”>
<p>Message is: { message }</p>
</div>

[Vue.js] Components do not render through <router-view /> in Laravel 5.8 with Vuejswelcome.blade.phpapp.js(./resources/js/app.js)routes.js(./resources/js/routes.js)Home.vue(./resources.components/Home.vue)web.php

I’m trying to create an SPA using Vuejs and Laravel. I’ve installed vue-router to accomplish that. The component that has to be rendered inside the

<router-view />

tag is not rendering.

I’ve tried creating a new project and installing npm and vue-router again.
It still does not work.

Laravel Version : 5.8.18
vue-router : 3.0.6

welcome.blade.php

<!DOCTYPE html>

<html>
<head>
<meta charset=”utf-8”>
<meta name=”viewport” content=”width=device-width, initial-scale=1”>
<title>Laravel</title>
</head>
<body>
<div id = “app”>
<router-view></router-view>
</div>

<script src = “js/app.js”></script>
</body>
</html>

app.js(./resources/js/app.js)

import vue.js from ‘vue’
import VueRouter from ‘vue-router’
import routes from ‘./routes’

Vue.use(VueRouter)

const app = new Vue({
el: ‘#app’,
router: new VueRouter(routes)
});

routes.js(./resources/js/routes.js)

import Home from ‘./components/Home’

export default {
mode: ‘history’,
routes: [
{
path: ‘/‘,
component: Home
}
]
}

Home.vue(./resources.components/Home.vue)

<template>
<p>Home</p>
</template>

<script>
export default {}
</script>

web.php

<?php

Route::get(‘/{any?}’, function () {
return view(‘welcome’);
});

Solution :

the code works for me. Remember to use

npm run watch

[Vue.js] two objects have the same value

Both object is the same when i edit.
show the solution to seprate objects.
there is an object and with v-model i bind it to inputs to update it but when i edit it but don’t save changes the object is changed. for not occurring this situation i use a second object(temporary) when editing i use that object but again it changes the first object.

data(){
return{
user:{
id:’’,
firstname:’’,
lastname: ‘’
},
tuser:{}
}
},
mounted(){
axios.get(‘/user’)
.then((response) => {
this.user = response.data
})
.catch(error)
},
methods:{
edit(){
this.tuser = this.user
},
update(){
axios.patch(`/user/${this.tuser.id}`,this.tuser)
.then((response)=>{
this.user = this.tuser
})
.error()
}
}

Solution :

You are mutating a reference value, it doesn’t matter which one you change - they both get updated as they share the same address in memory heap.

So Use ES6 spread to make clone when you are trying to have copy of any reference value.

this.user = { …this.tuser }

or

this.tuser = { …this.user }

References : spread_es6

Solution 2:

It is most likely because you reference one object to another.
As objects are reference not primitive values.
What it means is:
if you make obj1 = obj2, then actually they both point to the same object, if you change one, another change also.
You need to use something like Object.assign()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/Object/assign

Solution 3:

methods:{
edit(){
this.tuser = this.user
},

I think you just need to pass a cloned copy of this.user, you can achieve that using lodash/underscore.js methods like clone or cloneDeep. If you don’t copy the object they are referencing the same object