When I log in with nuxt auth, I redirect the user to his profile page. But after reload on the profile page I get an error like the screenshot:
I have searched this problem related to #nuxtjs/auth-next ssr problem. Most of the solution is to downgrade the #nuxtjs/axios version. I have already tried this but not fixed.
Here is my profile page code:
<template>
<div v-show="$auth.user">
<!-- profile image -->
<div class="w-full flex">
<div>
<div class="bg-gray-200 p-5 w-40 h-44"></div>
</div>
<div class="ml-6">
<h2 class="font-bold text-2xl mb-4">Profile Details</h2>
<h6 class="font-semibold text-lg">{{$auth.user.name}}</h6>
<p><span class="font-medium">Email: </span>{{$auth.user.email}}</p>
<p><span class="font-medium">Phone: </span>{{$auth.user.phone}}</p>
<p><span class="font-medium">Last Login: </span>{{$auth.user.lastLoginForHuman}}</p>
<nuxt-link to="/customer/change-password" class="block mt-3 text-primary-500 text-sm hover:underline">Change Password</nuxt-link>
</div>
</div>
<!-- details -->
<div class="w-full mt-5">
<div class="grid grid-cols-2 sm:grid-cols-2 gap-4">
<input-field label="First name"></input-field>
<input-field label="Last name"></input-field>
<input-field type="email" label="Email"></input-field>
<input-field label="Phone"></input-field>
</div>
<div class="flex justify-end">
<button-field label="Update" class="bg-primary-500 text-white py-3 px-10"></button-field>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Profile",
data() {
return {
form: {
firstName: this.$auth.user?.firstName,
lastName: this.$auth.user?.lastName,
email: this.$auth.user?.email,
phone: this.$auth.user?.phone,
},
photo: null,
};
},
};
</script>
"#nuxtjs/auth-next": "^5.0.0-1624817847.21691f1",
"#nuxtjs/axios": "^5.13.6",
"nuxt": "^2.15.7"
Related
I have a navbar and login components in vue. So my target is when if the user login, on the dropdown in navbar, I want to show Profile as an item, and if the user is not login I want to show Sign In/Register item as an item. So I want to manipulate the dropdown that you see on the picture below:
And here is my Navbar component:
<template>
<nav class="navbar navbar-expand-lg shadow">
<div class="container navbar-container">
<div class="navbar navbar-profile">
<div class="dropdown">
<button class="btn dropdown-toggle" type="button" id="dropdownProfile" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<i class="fa fa-fw fa-user"></i>
</button>
<ul class="dropdown-menu dropdown-menu-left">
<!-- User is not authenticated so show login/register-->
<li v-if="authenticated"><router-link :to="{ name: 'login' }">Login/Register</router-link></li>
<!-- User is authenticated so show profile-->
<li v-if="authenticated"><router-link :to="{ name: 'profile' }">Profile</router-link></li>
</ul>
</div>
</div>
</div>
</nav>
</template>
<script>
export default {
data() {
return {
authenticated: false,
authenticationFailed: false,
};
},
};
</script>
So in the code I didnt make anything with the authenticated/authenticationFailed values because I dont know how can I check it from the Login component. And here is my login component:
<template>
<div id="login" class="card-container">
<div class="card col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="headers">
<h3 class="card-header text-center active">LOGIN</h3>
<router-link :to="{name: 'register'}"><h4 class="card-header text-center non-active">REGISTER</h4></router-link>
</div>
<div class="card-body">
<div class="form-row">
<div class="form-group">
<input type="text" class="form-control" v-model="email" placeholder="Email" id="email" #keyup.enter="signIn" >
</div>
<div class="form-group">
<input type="password" class="form-control" v-model="password" placeholder="Password" id="password" #keyup.enter="signIn">
</div>
<div class="form-group form-check">
<input type="checkbox" id="rememberMeSignIn" class="form-check-input">
<label class="form-check-label" for="rememberMeSignIn">Remember Me</label>
</div>
<div class="form-group links">
<router-link :to="{name: 'forget-password'}">Forget Password?</router-link>
</div>
</div>
<div class="button-area">
<button v-on:click="signIn()" type="submit" class="btn button">Sign In</button>
</div>
</div>
</div>
</div>
</template>
<script>
import authHelper from "../helpers/authHelper";
import GENERAL_APP_CONSTANTS from "../constants/GeneralAppConstants";
export default {
name: 'Login',
beforeMount() {
this.authenticated = authHelper.validAuthentication();
},
mounted() {
EventBus.$on(GENERAL_APP_CONSTANTS.Events.CheckAuthentication, () => {
this.authenticated = authHelper.validAuthentication();
if (this.authenticated) {
this.email = this.password = "";
this.authenticationFailed = false;
}
});
EventBus.$on(GENERAL_APP_CONSTANTS.Events.LoginFailed, () => {
this.authenticationFailed = true
});
},
data () {
return {
authenticated: false,
authenticationFailed: false,
email: '',
password: '',
rememberMe: false,
}
},
methods: {
signIn: function () {
authHelper.signIn(this.email, this.password, () => {
this.$router.push({name: 'home'});
});
}
}
}
</script>
I tried to make it as simple as possible and if you can help me with this , I would be really glad.
PS: this is my index.vue that you can see the relation between Navbar and Login page and my login component is displaying when router-view changed:
<div id="app">
<Topnav/>
<Navbar/>
<router-view></router-view>
<Footer/>
</div>
I wrote the following code for my navbar:
<template>
<div>
<div v-if="!$auth.loggedIn" data-tip="Login" class="tooltip tooltip-bottom">
<nuxt-link to="/login" class="btn btn-square btn-ghost">
<solid-login-icon class="w-6 h-6" />
</nuxt-link>
</div>
<div v-else class="flex items-stretch">
<a class="pr-2 btn btn-ghost rounded-btn"> Welcome, {{ this.$auth.user.username }}! 👋 </a>
<div data-tip="Logout" class="tooltip tooltip-bottom">
<button class="pr-2 btn btn-square btn-ghost" #click="logout()">
<solid-login-icon class="w-6 h-6" />
</button>
</div>
</div>
</div>
</template>
Which is include in the following login page:
<template>
<div class="h-screen shadow bg-base-200 drawer drawer-mobile">
<input id="my-drawer-2" type="checkbox" class="drawer-toggle" />
<div class="drawer-content">
<NavBar />
<div class="grid grid-cols-1 p-5 md:grid-cols-6">
<div class="col-span-1 md:col-span-2 md:col-start-3">
<div class="bg-white shadow card">
<div class="card-body">
<h2 class="text-left card-title">Login</h2>
<form #submit.prevent="userLogin">
<div class="form-control">
<label class="label">
<span class="label-text">Username</span>
</label>
<input
v-model="login.username"
type="text"
placeholder="Username"
class="input input-bordered"
/>
</div>
<div class="form-control">
<label class="label">
<span class="label-text">Username</span>
</label>
<input
v-model="login.password"
type="password"
placeholder="Password"
class="input input-bordered"
/>
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary btn-md">Login</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<SideBar />
</div>
</template>
<script>
export default {
data() {
return {
login: {
username: '',
password: '',
},
}
},
methods: {
async userLogin() {
try {
const response = await this.$auth.loginWith('local', { data: this.login })
} catch (err) {}
},
},
}
</script>
Upon loggin in with correct credentials the page keeps dispalying the "Login"-icon instead of the Welcome message.
I've tried to replace !$auth.loggedIn with loggedIn (coming from the data function) and with !this.$auth.loggedIn" but both don't seem to solve the issue
I have four components Dashboard.vue(parent component) it contains Three child components(DisplayBooks.vue,sortBooksHightoLow,sortBooksLowtoHigh).
Now i want to import one more component called Cart.vue inside the Dashboard.vue .By default only DisplayBooks.vue component is only visible,if i click on cart-icon inside the Dashboard component it displays the Cart.vue component and hides the DisplayBooks.vue component .
How to acheive this thing please help me to fix this thing..
Dashboard.vue
<template>
<div class="main">
<div class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header">
<img src="../assets/education.png" alt="notFound" class="education-image" />
</div>
<ul class="nav navbar-nav">
<li>
<p class="brand">Bookstore</p>
</li>
</ul>
<div class="input-group">
<i #click="handlesubmit();" class="fas fa-search"></i>
<div class="form-outline">
<input type="search" v-model="name" class="form-control" placeholder='search...' />
</div>
</div>
<ul class="nav navbar-nav navbar-right" id="right-bar">
<li><a> <i class="far fa-user"></i></a></li>
<p class="profile-content">profile</p>
<li><a><i class="fas fa-cart-plus"></i></a></li>
<p class="cart-content" >cart <span class="length" v-if="booksCount">{{booksCount}}</span></p>
</ul>
</div>
<div class="mid-body">
<h6>Books<span class="items">(128items)</span></h6>
<select class="options" #change="applyOption">
<option disabled value="">Sort by relevance</option>
<option value="HighToLow">price:High to Low</option>
<option value="LowToHigh">price:Low to High</option>
</select>
</div>
<div v-if="flam==false">
<h2>Hello</h2>
</div>
<DisplayBooks v-show="flag==='noOrder'" #update-books-count="(n)=>booksCount=n"/>
<sortBooksLowtoHigh v-show="flag==='lowToHigh'" />
<sortBooksHightoLow v-show="flag==='highToLow'" />
<Cart />
</div>
</template>
<script>
import sortBooksLowtoHigh from './sortBooksLowtoHigh.vue'
import sortBooksHightoLow from './sortBooksHightoLow.vue'
import DisplayBooks from './DisplayBooks.vue'
import Cart from './Cart.vue'
export default {
components: {
DisplayBooks,
sortBooksLowtoHigh,
sortBooksHightoLow,
Cart
},
data() {
return {
booksCount:0,
flag: 'noOrder',
brand: 'Bookstore',
name: '',
flam: true,
visible: true,
}
},
methods: {
flip() {
this.flam = !this.flam;
},
applyOption(evt) {
if (evt.target.value === "HighToLow") {
this.flag = 'highToLow';
} else this.flag = 'lowToHigh';
},
}
}
</script>
Cart.vue
<template>
<div class="main">
<div v-for="book in books" :key="book.id" class="container">
<div class="content">
<h5>My Cart({{booksCount}})</h5>
</div>
<div class="mid-section">
<img v-bind:src="book.file" alt="not found">
<p class="title-section">{{book.name}}</p>
</div>
<div class="author-section">
<p>by {{book.author}}</p>
</div>
<div class="price-section">
<h6>Rs.{{book.price}}</h6>
</div>
<button class="close-btn" #click="handlesubmit();" type="submit">close</button>
<div class="btn-grps">
<button class="btn" type="submit" >Place Order</button>
</div>
</div>
</div>
</template>
<script>
import service from '../service/User'
export default{
data(){
return {
booksCount:0,
books: [{
id: 0,
file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
name: 'Dont Make me think',
author: 'Sai',
price: '1500'
},]
}
},
methods:{
}
}
</script>
It's recommended to use vur-router, but for a simple situation you could define a property called shownComp then update when you click on cart icon :
data() {
return {
shownComp:'DisplayBooks',
booksCount:0,
flag: 'noOrder',
then <li #click="shownComp='Cart'"><a><i class="fas fa-cart-plus"></i></a></li>
and :
<DisplayBooks v-show="flag==='noOrder' && shownComp==='DisplayBooks'" #update-books-count="(n)=>booksCount=n"/>
<Cart v-show=" shownComp==='Cart'" />
...
Ok, I have a problem, here I make a data post with a tag, and when I click the tag the other data posts are not updated by the tag.
i'm get the api with created function, Do I have to use vuex?
can everyone help me, thanks very much
this is my template
<div class="col-md-4 mb-4" v-for="post in posts" :key="post.id">
<div class="card h-100 shadow-sm border-0 rounded-lg">
<div class="card-img">
<img :src="path+'/storage/posts/'+post.image" class="w-100"
style="height: 200px;object-fit: cover;border-top-left-radius: .3rem;border-top-right-radius: .3rem;">
</div>
<div class="card-body">
<router-link :to="{name: 'detail_post', params: {slug: post.slug}}"
class="text-dark text-decoration-none">
<h6>{{ post.title }}</h6>
</router-link>
</div>
<div class="card-footer bg-white">
<i class="fa fa-calendar" aria-hidden="true"></i> {{ post.created_at }}
</div>
</div>
</div>
this is my JavaScript
<script>
//import axios
import axios from 'axios'
export default {
name: 'PostIndex',
data() {
return {
path: axios.defaults.baseURL,
posts: []
}
},
created() {
//get post homepage
axios.get(`/api/tag/${this.$route.params.slug}`).then(response => {
this.posts = response.data.data.data;
})
}
}
</script>
I'm currently stuck on a task on VueJS. Basically I'm trying to create an array from multiple select inside a form to get all the data as an array or Object to process it further. I just searched but got no results or an idea on how to solve my issue.
Parent Component
<template>
<div id="product" class="mt-12">
<div class="flex flex-wrap mb-4">
<div class="w-1/2 pr-12">
<img src="https://placehold.it/800" alt="">
</div>
<div class="w-1/2">
<div class="flex justify-between content-center h-12 mb-4">
<div class="text-gray-700 py-2">
<h2 v-if="product.brand" class="leading-none font-bold text-sm">{{ product.brand }}</h2>
<h1 class="text-xl leading-snug">{{ product.name }}</h1>
</div>
<div class="text-gray-700 py-2">
<p class="text-xl font-bold leading-none">{{ product.price }}</p>
<p class="text-xs text-right leading-none">Inkl. 19% MwSt.</p>
</div>
</div>
<div class="divider bg-gray-400 mt-4 mb-4" />
<div id="variations">
<form action="">
<ProductVariation v-for="(variations, type) in product.variations" :type="type" :variations="variations" :key="type" v-model="form.variation"/>
<div class="flex w-full">
<button class="w-full leading-none bg-blue-500 hover:bg-blue-600 text-white py-2 rounded" type="submit">Add to cart</button>
</div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import ProductVariation from '#/components/products/ProductVariation'
export default {
data () {
return {
product: null,
form: {
variation: null
}
}
},
components: {
ProductVariation
},
async asyncData({ params, app }) {
let response = await app.$axios.$get(`products/${params.slug}`)
return {
product: response.data
}
}
}
</script>
ProductVariation Component
<template>
<div class="flex mb-4">
<div class="w-full">
<label class="block text-gray-700 w-full text-sm font-bold">{{ type }}</label>
<select class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight" :name="type">
<option value="0">Please select</option>
<option v-for="variation in variations" :key="variation.id" :value="variation.id">{{ variation.name }} <span>( +{{ variation.price }} )</span></option>
</select>
</div>
</div>
</template>
<script>
export default {
props: {
type: {
required: true,
type: String
},
variations: {
required: true,
type: Array
}
},
}
</script>