I have isAdmin boolean property which I am checking user logged in as user or admin.
Backend is .net core 2.2, db - Postgre.
Everything works fine but after refresh I lose isAdmin value.
I have conditional show hide dropdown which is available only for admin roles.
How don't lose data after refreshing?
P.S. How to add logic also to my guard for isAdmin property?
My component looks like:
model: any = {};
constructor(public authService: AuthService, private alertify: AlertifyService, private router:
Router) { }
ngOnInit() {
}
login() {
this.authService.login(this.model).subscribe(next => {
this.model.isAdmin = true;
this.alertify.success('Logged in as Admin')
}, error => {
this.alertify.error(error)
}, () => {
this.router.navigate(['/projects'])
})
}
loginAsUser() {
this.authService.loginAsUser(this.model).subscribe(next => {
this.model.isAdmin = false;
this.alertify.success('Logged in as User')
}, error => {
this.alertify.error(error)
}, () => {
this.router.navigate(['/home'])
})
}
loggedIn() {
return this.authService.loggedIn();
}
logout() {
localStorage.removeItem('token');
this.alertify.message('logged out');
this.router.navigate(['/home'])
}
My html looks like:
<nav class="navbar navbar-expand-md navbar-light fixed-top bg-light">
<div class="container">
<a class="navbar-brand" [routerLink]="['/home']">
<img [src]="iteraLogo" alt="Itera">
</a>
<div *ngIf="loggedIn()" class="dropdown" dropdown [hidden]="!model.isAdmin">
<a class="dropdown-toggle" dropdownToggle>
<strong class="text-primary">Admin Panel</strong>
</a>
<div class="dropdown-menu mt-4" *dropdownMenu>
<ul class="navbar-nav">
<li class="nav-item" routerLinkActive="router-link-active">
<a class="nav-link" [routerLink]="['/projects']">Projects</a>
</li>
<li class="nav-item" routerLinkActive="router-link-active">
<a class="nav-link" [routerLink]="['/hypervisors']">Hypervisors</a>
</li>
<li class="nav-item" routerLinkActive="router-link-active">
<a class="nav-link" [routerLink]="['/management']">Management</a>
</li>
<li class="nav-item" routerLinkActive="router-link-active">
<a class="nav-link" [routerLink]="['/users']">Users</a>
</li>
<li class="nav-item" routerLinkActive="router-link-active">
<a class="nav-link" [routerLink]="['/user-projects']">Users Projects</a>
</li>
</ul>
</div>
</div>
<ul class="navbar-nav mr-auto">
<li class="nav-item" routerLinkActive="router-link-active">
<a class="nav-link" [routerLink]="['/test']">About</a>
</li>
</ul>
<div *ngIf="loggedIn()" class="dropdown" dropdown>
<a class="dropdown-toggle" dropdownToggle>
Welcome <strong>{{ authService.decodedToken?.unique_name | titlecase }}</strong>
</a>
<div class="dropdown-menu mt-3" *dropdownMenu>
<a class="dropdown-item text-primary" [routerLink]="['/projects/',
authService.decodedToken?.nameid ]"><i class="fa fa-archive"> My Projects</i></a>
<div class="dropdown-divider"></div>
<a class="dropdown-item text-danger" (click)="logout()"><i class="fa fa-sign-
out"> Logout</i></a>
</div>
</div>
<form *ngIf="!loggedIn()" #loginForm="ngForm" class="form-inline my-2 my-lg-0">
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fa fa-user-circle-o text-primary" aria-hidden="true"></i>
</div>
</div>
<input class="form-control" placeholder="Username" name="username" required
[(ngModel)]="model.username" />
</div>
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fa fa-unlock text-danger" aria-hidden="true"></i>
</div>
</div>
<input class="form-control" placeholder="Password" name="password" required type="password"
[(ngModel)]="model.password" />
</div>
<div>
<button [disabled]="!loginForm.valid" type="submit" (click)="loginAsUser()" class="btn btn-primary my-2 my-sm-0">
<i class="fa fa-user-circle" aria-hidden="true"></i> User
</button>
<button [disabled]="!loginForm.valid" type="submit" (click)="login()" class="btn btn-success
my-2 my-sm-0">
<i class="fa fa-user-secret" aria-hidden="true"></i> Admin
</button>
</div>
</form>
</div>
</nav>
My guard looks like:
canActivate(): boolean {
if(this.authService.loggedIn()) {
return true
}
this.alertify.error('You have no access to see this page!!!');
this.router.navigate(['/home']);
return false;
}
When you refresh the page it does not persist variable values, you need to store either in local storage or cookie.
A simple way to solve this is to use this lib:
https://www.npmjs.com/package/ng2-cookies
To install this library, run:
npm install ng2-cookies
Component
import { Cookie } from 'ng2-cookies/ng2-cookies';
ngOnInit() {
this.model.isAdmin = Cookie.get('isAdmin');
}
login() {
this.authService.login(this.model).subscribe(next => {
Cookie.set('isAdmin', 'true');
this.alertify.success('Logged in as Admin')
}, error => {
this.alertify.error(error)
}, () => {
this.router.navigate(['/projects'])
})
}
you can use ngx-cookie-service also
https://www.npmjs.com/package/ngx-cookie-service
You will have to store your Auth_Token in localhost/indexDB/SessionStorage and then inside your route guard check if that token is valid or not.
This way your app will not require authentication until your token is valid.
Use this npm module to achieve this : enter link description here
You have to make the auth service API call with ngoninit of the components and get the isAdmin flag. That way when u refresh everytime ngOnInit will get involved and u ll get that flag.
ngOnInit(){ this.authService.login(this.model).subscribe(next => {
this.model.isAdmin = true;
});
}
Set a variable in localStorage upon successful login, like
isloggedIn(authUser) {
return this.httpClient.post<any>(`${this.apiUrl}/api/users/login`, {user: authUser})
.do(res => this.setSession(res.user))
.shareReplay();
}
private setSession = (authResult) => {
localStorage.setItem('TOKEN', authResult.token);
localStorage.setItem('loggedUser', 'y');
this._router.navigate(['dashboard'])
};
Next time when you enter any component, check
if(!localStorage.getItem('loggedUser')){
this._router.navigate(['login']);
return false;
}
return true;
this will authenticate user without calling API again. just get key from LocalStorage.
Related
I am making a newsapp i want it to have different categories, instead of using react-router-dom for navigation what i want to do is create a state object and create a key in it named category and set current category as it's value and i have sent that key as a props to news component where i fetch news and embed that category to the fetch URL
I have made a function to set the category and its in app.js I have sent it to navbar component as props, the issue i am facing is that i can't select a category, because for some reason the onClick of the very last category is being called continuously and I know this because I console logged the category in setCategory function, can anyone tell me why this is happening
code in app.js:
import './App.css';
import React, { Component } from 'react'
import Navbar from './components/Navbar';
import News from './components/News';
export default class App extends Component {
constructor() {
super()
this.state = {
darkMode: "light",
country: "us",
category: "general",
key: "general"
}
}
setCategory = (cat)=> {
this.setState({
category: cat
})
console.log(this.state.category)
}
setCountry = (cntry)=> {
this.setState({
category: cntry
})
}
setDarkMode = () => {
if (this.state.darkMode === "light") {
this.setState({ darkMode: "dark" })
document.body.style.backgroundColor = "black"
} else {
this.setState({ darkMode: "light" })
document.body.style.backgroundColor = "white"
}
}
render() {
return (
<div>
<Navbar setCategory={this.setCategory} setCountry={this.setCountry} setDarkMode={this.setDarkMode} darkMode={this.state.darkMode} />
<News key={this.state.category} category={this.state.category} country={this.state.country} pageSize={18} darkMode={this.state.darkMode} />
</div>
)
}
}
code in Navbar component:
import React, { Component } from 'react'
export default class Navbar extends Component {
constructor(props) {
super(props)
this.setCategory = this.props.setCategory
}
render() {
return (
<div>
<nav className={`navbar navbar-expand-lg navbar-${this.props.darkMode} bg-${this.props.darkMode}`}>
<a className="navbar-brand" href="/">NewsMonkey</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item active">
<a className="nav-link" href="/">Home <span className="sr-only">(current)</span></a>
</li>
<li className="nav-item">
<a className="nav-link" href="/about">About</a>
</li>
<li className="nav-item dropdown">
<a className="nav-link dropdown-toggle" href="/" role="button" data-toggle="dropdown" aria-expanded="false">
Categories
</a>
<div className="dropdown-menu">
<p className="dropdown-item cursor-pointer" onClick={this.setCategory("business")}>Business</p>
<p className="dropdown-item cursor-pointer" onClick={this.setCategory("science")}>Science</p>
<p className="dropdown-item cursor-pointer" onClick={this.setCategory("technology")}>Technology</p>
<p className="dropdown-item cursor-pointer" onClick={this.setCategory("entertainment")}>Entertainment</p>
<p className="dropdown-item cursor-pointer" onClick={this.setCategory("health")}>Health</p>
<p className="dropdown-item cursor-pointer" onClick={this.setCategory("sports")}>Sports</p>
<div className="dropdown-divider"></div>
<p className="dropdown-item cursor-pointer" onClick={this.setCategory("general")}>General</p>
</div>
</li>
</ul>
{/* <form className="form-inline my-2 my-lg-0">
<input className="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" />
<button className="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form> */}
<div className={`custom-control custom-switch text-${this.props.darkMode === "light" ? "dark" : "light"}`}>
<input type="checkbox" className="custom-control-input" onClick={this.props.setDarkMode} id="customSwitch1" />
<label className={`custom-control-label`} htmlFor="customSwitch1">Dark mode</label>
</div>
</div>
</nav>
</div>
)
}
}
This doesn't do what you think it does:
onClick={this.setCategory("business")}
This calls the setCategory function immediately and uses the result of that function as the onClick handler. Don't pass the result of calling a function to onClick, pass a function itself:
onClick={() => this.setCategory("business")}
So I have created a web-site to which you can upload, download, delete and preview files. I also have a java-script function that lets the user search through the files. Only thing is, that the search is case sensitive. Can anyone help me with a sample code on how should I change my script so that it will NOT be case sensitive anymore? I am very new to ASP.NET and still trying to wrap my head around.
Here is the Index page:
#model IEnumerable<Proiect2PracticaClona.Models.Files>
<center>
<h1>Daca nici acu nu merge ... ma sinucid</h1>
<h2>Sa moara mama</h2>
<hr />
#if (User.IsInRole("Admin"))
{
<form methord="post" enctype="multipart/form-data" asp-controller="Home" asp-action="Index">
<input type="file" name="fifile" />
#Html.RadioButton("category", "incepator")
#Html.RadioButton("category", "intermediar")
#Html.RadioButton("category", "admin")
<input type="submit" value="Upload" />
<hr />
</form>}
<div>
File Name:<input id="search" onkeyup="search()" placeholder="cauta"/>
</div>
<table class="table">
#if (User.IsInRole("User"))
{
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link">Incepatori <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link">Avansati</a>
</li>
<li class="nav-item dropdown">
</li>
<li class="nav-item">
<a class="nav-link disabled">Admini</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
}
<tr>
<th>File Name</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.info</td>
<td>Download</td>
#if (User.IsInRole("Admin"))
{
<td>Delete</td>
}
<td>Viewer</td>
</tr>
}
</table>
#section scripts
{
<script>
function search() {
$("tr").each(function (index, value) {
if (index > 0 && !$(this).find("td")[0].innerText.includes($("#search").val())) {
$(this).attr("hidden", true);
} else {
$(this).removeAttr("hidden");
}
console.log(value);
})
}
</script>
}
</center>
Why not convert both sides to lowercase when checking. This case it does not matter what the casing of element in td block is and what is the case of text inserted by user.
We use this a lot in out application to make comparisons.
function search() {
$("tr").each(function (index, value) {
if (index > 0 && !$(this).find("td")[0].innerText.toLowerCase().includes($("#search").val().toLowerCase())) {
$(this).attr("hidden", true);
} else {
$(this).removeAttr("hidden");
}
console.log(value);
})
}
Case sensitivity can be negated by transforming the value on either side of the query to lowercase or to uppercase (according to your preference.
So your search logic needs to change from
if (index > 0 && !$(this).find("td")[0].innerText.includes($("#search").val())) {
To this:
if (index > 0 && !$(this).find("td")[0].innerText.toLowerCase().includes($("search").val().toLowerCase())) {
I have a problem and if you can help me I would be grateful, because I am working with vue for 3 weeks.
I try to create a menu with submenu in vue 2 by two weeks and I can't succeed. the menu is created , but when I go to submenu is won't create it. the code is next:
<script>
import image from "./assets/img/logo-just-escape.png"
import axios from "axios"
export default {
data(){
const lang = localStorage.getItem('lang')
return {
imagel: image,
lang: lang,
languages:null,
menu:null,
submenu:null
}
},
async created(){
try {
var res =await axios.get(`lng`);
this.languages=res.data;
const valmenu="titles/value?language="+this.lang;
res=await axios.get(valmenu);
this.menu=res.data;
this.submenu=this.getSubMnu(this.menu);
console.log(this.submenu)
}catch(e){
console.error(e);
}
},
methods: {
handleChange(event){
localStorage.setItem('lang',event.target.value);
window.location.reload();
},
getSubMnu(value){
let temp='';
let sbmenu=[];
let variable=null;
for(temp in value){
if('2'==value[temp].subtitle){
variable=value[temp];
let temp1=value[temp].link+"\/"+this.menu[temp].id;
variable.link=temp1;
sbmenu.push(variable);
}
}
return sbmenu;
}
}
}
</script>
<template>
<div id="app" class="bg-dark">
<div>
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="/">
<img width="100" height="50" :src="imagel"/>
</a>
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<div v-for="menuButton in this.menu" :value="menuButton.title" :key="menuButton.id">
<li class="nav-item" v-if="menuButton.subtitle ===0">
<router-link :to="menuButton.link" ><span class="nav-link">{{menuButton.title}}</span></router-link>
</li>
<li class="nav-item dropdown" v-if="menuButton.subtitle ===1" style="color: white;">
<span class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{menuButton.title}}</span>
<div v-for="tempor in this.submenu" class="dropdown-menu dropdown-menu-right bg-dark" :value="tempor.title" :key="tempor.id">
<span class="nav-link">{{tempor.title}}</span>
<router-link :to="tempor.link" #click.name><span class="nav-link">{{tempor.title}}</span></router-link>
</div>
</li>
</div>
<li class="nav-item">
<select class="selectpicker form-control" v-model="lang" data-width="fit" #change="handleChange($event)">
<option v-for="langu in languages" :value="langu.language_short" :key="langu.id">
{{langu.language}}
</option>
</select>
</li>
</ul>
</div>
</nav>
<div class="divmargin" >
<router-view/>
</div>
</div>
</div>
</template>
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read property 'submenu' of undefined"
found in
---> at src/App.vue
If someone can give me some answer to this I will be very grateful.
Thank you,
Vlad.
Hello everyone I need help regarding linking of pages in nextjs.
actually I know how to link but what i want is following:
I have my home page having course team contact links in navbar so when I click course then course page gets open with url "localhost:3000/course" and in that course page I have courses .
I want that by clicking on any course in course page it should get open and the url should be "localhost:3000/course/course_1".
what should I do ?
This is header component:
const Header = () => (
<div>
<nav className="navbar navbar-expand-lg navbar-dark" >
<Logo />
<button className="navbar-toggler" type="button" data-target="#navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse">
<ul className="navbar-nav">
<li>
<a href="/" className="nav-link" >Home</a>
</li>
<li>
<a href="/team" className="nav-link" >Team</a>
</li>
<li>
<a href="/courses" className="nav-link" >Course</a>
</li>
<li >
<a href="/contact" className="nav-link" >Contact</a>
</li>
</ul>
<form className="form-inline my-2 my-lg-0">
<div className="d-flex justify-content-center h-100">
<div className="searchbar">
<input className="search_input text-center" type="text" name="" placeholder="Search..." />
<i className="fas fa-search"></i>
</div>
</div>
</form>
</div>
</nav>
This is the course :
const Course = () => (
<div>
<div className="col-xs-12 col-sm-4">
<div className="card">
<a className="img-card img-part-2" href="#">
<img src="/static/course1-img.jpg" />
</a>
<div className="teacher-img">
<div className="ava">
<img alt="Admin bar avatar" src="http://ivy-school.thimpress.com/demo-3/wp-content/uploads/learn-press-profile/5/2448c53ace919662a2b977d2be3a47c5.jpg" className="avatar avatar-68 photo" height="68" width="68" />
</div>
</div>
<div className="card-content">
<p className="card-para">Charlie Brown </p>
<h4 className="card-title">
<a href="/Pyhton">
Learn Python – Interactive <br/> Python
</a>
</h4>
<div className="info-course">
<span className="icon1&-txt">
<i className="fas fa-user"></i>
3549
</span>
<span className="icon2&-txt">
<i className="fas fa-tags"></i>
education
</span>
<span className="icon3&-txt">
<i className="fas fa-star"></i>
0
</span>
</div>
</div>
</div>
</div>
You can try like this:
server.js
const express = require('express')
const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.get('/course', (req, res) => {
return app.render(req, res, '/courses')
})
server.get('/course/:id', (req, res) => {
return app.render(req, res, '/course', { id: req.params.id })
})
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
course.js
import React, { Component } from 'react'
export default class extends Component {
static getInitialProps ({ query: { id } }) {
return { courseId: id }
}
render () {
return (
<div>
<h1>Course {this.props.courseId}</h1>
</div>
)
}
}
courses.js
import React, { Component } from 'react'
export default class extends Component {
render () {
return (
<div>
<a href="/course/python">
Learn Python – Interactive <br/> Python
</a>
<a href="/course/javascript">
Learn Javascript – Interactive <br/> Javascript
</a>
</div>
)
}
}
I just started on ReactJS and came across this error
Error: Invariant Violation: CarDisplay.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.
And the render function is this:
render: function() {
var cars = this.state.loadedCars.map(function(loaded) {
return (
<div class="row">
<div class="col-md-7">
<a href="#">
<img class="img-responsive" src="http://placehold.it/700x300" alt=""></img>
</a>
</div>
<div class="col-md-5">
<ul class="list-group">
<li class="list-group-item"><b>Brand: {loaded.brand}</b></li>
<li class="list-group-item"><b>Model: {loaded.model}</b></li>
<li class="list-group-item"><b>Fuel: </b></li>
<li class="list-group-item"><b>Mileage: </b></li>
<li class="list-group-item"><b>Location: </b></li>
<li class="list-group-item"><b>Price: </b></li>
</ul>
<a class="btn btn-primary" href="#">Buy it! <span class="glyphicon glyphicon-chevron-right"></span></a>
</div>
</div>
);
console.log(cars);
return (<div>
{cars};
</div>
);
});
}
So far I know that error is caused by not returning a div, even if blank, but that's not the case. Am I doing something wrong, or React just can't return anything related to Bootstrap? (This is just a small example I was writing as practice, don't mind any minor errors)
React is ok with bootstrap. You've simply made a mistake by putting return statement of the render method inside of .map() function. Your render() method returned nothing, and that's why the mentioned error was triggered. Correct code should look like:
render: function() {
var cars = this.state.loadedCars.map(function(loaded) {
return (
<div class="row">
<div class="col-md-7">
<a href="#">
<img class="img-responsive" src="http://placehold.it/700x300" alt=""></img>
</a>
</div>
<div class="col-md-5">
<ul class="list-group">
<li class="list-group-item"><b>Brand: {loaded.brand}</b></li>
<li class="list-group-item"><b>Model: {loaded.model}</b></li>
<li class="list-group-item"><b>Fuel: </b></li>
<li class="list-group-item"><b>Mileage: </b></li>
<li class="list-group-item"><b>Location: </b></li>
<li class="list-group-item"><b>Price: </b></li>
</ul>
<a class="btn btn-primary" href="#">Buy it! <span class="glyphicon glyphicon-chevron-right"></span></a>
</div>
</div>
)
});
console.log(cars);
return (
<div>
{cars};
</div>
);
}