login form input redirection to child component - salesforce

I am trying to create a login form that will send the username, password details to chilld component and display in its labels. But i dont see it is displaying the user details. I have recently started learnig lwc. Could someone help me to understad the mistake am making here. Thanks for the reply.
Parent.html:
`
<lightning-layout>
<lightning-layout-item>
<div>
<lightning-input type="text" name="Username" label="Username"></lightning-input>
</div>
<div>
<lightning-input type="text" name="Passowrd" label="Password"></lightning-input>
</div>
<div>
<lightning-button variant="brand" label="Submit" title="Primary action" onclick={handleClick} class="slds-m-left_x-small"></lightning-button>
</div>
<template if:true={buttonClicked}>
<c-sample-click onshowuserdetails={handleClick}></c-sample-click>
</template>
</lightning-layout-item>
</lightning-layout>
</lightning-card>
`
Parent.js
import { LightningElement ,api} from 'lwc';
export default class SampleDemo extends LightningElement {
buttonClicked = false;
#api username = '';
#api password = '';
handleUsername(event)
{
this.username = this.event.value;
}
handlePassword(event)
{
this.password= this.event.value;
}
handleClick(event){
this.buttonClicked =true;
//console.log(this.template.querySelector('lightning-input/'))
this.template.querySelector('c-sample-click').showUserDetails(this.username, this.password)
}
}
Child.html:
<template>
<div>You have entered {user} , {pass}}</div>
</template>
Child.js
import {
LightningElement,
api
} from 'lwc';
export default class SampleClick extends LightningElement {
#api user;
#api pass;
#api
showUserDetails(user, pass) {
this.user = user;
this.pass = pass
}
}
I tried changing some fuction parameters but the exception still exist

Related

React.js with Redux: Get info from state

I'm coding the app and I can't solve a problem. I have stored user info in the state (when I open Redux DevTools I can see the state -> user: {username: name, role: ...}).
Now in some components, I want to check if logged in user is admin or a user. I have it in that state but how can I load it in some class? When I export a function, I can use const userRole = useSelector(state => state.security.user.role_id); but in a class it makes a problem. Can you help me?
this is my code for User class and I want to show up DELETE button, only if user is an admin:
import React, {Component} from "react";
import PropTypes from "prop-types";
import {connect, useSelector} from "react-redux";
import { Link } from "react-router-dom";
import { deleteUser } from "../../store/actions/userActions";
class User extends Component{
constructor() {
super();}
onDeleteClick(id) {
this.props.deleteUser(id);
}
render() {
const { user } = this.props;
return (
<div className='row entry'>
<div className='col-sm-2'>
<span >{user.username}</span>
</div>
<div className='col-sm-2'>
<span >{user.name}</span>
</div>
<div className='col-sm-2'>
<span>{user.lastname}</span>
</div>
<div className='col-sm-2'>
<span>{user.tag}</span>
</div>
<div className='col-sm-1'>
<span>{user.pay}</span>
</div>
<div className='col-sm-1'>
<span>
{user.role_id}
</span>
</div>
<div className='col-sm-2'>
<Link to={`userlist/edituser:${user.id}`}>
<button><i className="fas fa-user-edit"></i></button>
</Link> | <button onClick={this.onDeleteClick.bind(this, user.id)}><i className="far fa-trash-alt"></i></button>
</div>
</div>
)
}
}
User.propTypes = {
deleteUser: PropTypes.func.isRequired
};
export default connect(
null, { deleteUser }
)(User);
With class components, you can make use of connect HOC with mapStateToProps to access state from redux
class User extends Component{
render() {
const { user, userRole } = this.props;
...
}
}
const mapStateToProps = (state) => {
return {
useRole: state.security.user.role_id,
}
}
export default connect(
mapStateToProps, { deleteUser }
)(User);

New Component is returned but the previous component stays the same in ReactJs

A new component is returned after login, but both the login component and the Home Component are seen on the page. I need to return the Home Componenet without Login Component. I am new to React and still trying to understand return and routes in React.
This is my pages component which returns either Login or Home based on this.state.redirect1.
import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import '../../App.css';
import Login from '../Login';
import Home from '../Home';
import Header from './Header';
import Footer from './Footer';
class Pages extends Component {
constructor(props) {
super(props)
this.state = {
redirect: false,
}
}
handleClick() {
this.state.redirect = true;
console.log(this.state.redirect);
}
changeRedirect =() =>{
this.state.redirect = true;
console.log(this.state.redirect);
this.forceUpdate()
}
renderRedirect = () => {
if(this.props.redirect1){
return <Home/>
}
else{
return <Login/>
}
}
render() {
return (
<div className="mh-100 PgWidth">
{this.renderRedirect()}
</div>
)
}
}
export default Pages
Below is my Login, Home and App Components
Login.js
import React, { Component } from 'react'
import Axios from 'axios';
import Pages from './common/Pages'
import { Redirect } from 'react-router-dom';
class Login extends Component {
constructor(props) {
super(props)
this.state = {
username: '',
password: '',
redirect: false
}
}
handleUsername = (event) => {
this.setState({
username: event.target.value
})
}
handlePassword = (event) => {
this.setState({
password: event.target.value
})
}
renderRedirect = () => {
if (this.state.redirect) {
console.log("from render redirect");
return <Pages redirect1={this.state.redirect} />
}
}
formSubmitHandler = event => {
let formdata = new FormData();
formdata.append("username", this.state.username);
formdata.append("password", this.state.password);
Axios.post("/auth/local",{
"name":this.state.username,
"password": this.state.password
})
.then(res => {
if (res) {
console.log(res);
this.setState({ redirect: true });
}
})
event.preventDefault() // used to keep the form data as entered even after the submit
}
render() {
const { username, password } = this.state
return (
<div className="p-5">
{ this.renderRedirect() }
<h3>Sign-In</h3>
<form onSubmit={this.formSubmitHandler}>
<div className="form-group row">
<label htmlFor="inputEmail3" className="col-sm-2 col-form-label">Username</label>
<div className="col-sm-10">
<input type="text" value={username} onChange={this.handleUsername}
className="form-control" id="inputEmail3" placeholder="Username" />
</div>
</div>
<div className="form-group row">
<label htmlFor="inputPassword3" className="col-sm-2 col-form-label">Password</label>
<div className="col-sm-10">
<input type="password" value={password} onChange={this.handlePassword}
className="form-control" id="inputPassword3" placeholder="Password" />
</div>
</div>
<div className="form-group row">
<div className="col-sm-2">Checkbox</div>
<div className="col-sm-10">
<div className="form-check">
<input className="form-check-input" type="checkbox" id="gridCheck1" />
<label className="form-check-label" htmlFor="gridCheck1">
Example checkbox
</label>
</div>
</div>
</div>
<div className="form-group row">
<div className="col-sm-10">
<button type="submit" onClick={this.formSubmitHandler} className="btn btn-primary">Sign in</button>
</div>
</div>
</form>
</div>
)
}
}
export default Login
Home.js
import React, { Component } from 'react'
import '../App.css';
export class Home extends Component {
componentDidMount(){
console.log("home component mount");
}
render() {
return (
<div>
<h1>The page has been routed</h1>
</div>
);
}
}
export default Home
App.js
import React, { Component } from 'react';
import './App.css';
import Header from './components/common/Header';
import Footer from './components/common/Footer';
import Pages from './components/common/Pages';
class App extends Component {
render() {
return (
<div className="App container-fluid bg-light w-75">
<div className="row justify-content-md-center">
<div className="col m-0 p-0">
<Header/>
<div className="">
<Pages/>
</div>
<Footer/>
</div>
</div>
</div>
);
}
}
export default App;
Issue is in this line:
{ this.renderRedirect() }
Once redirect will be true, it will render the Home page first then the Login component.
Solution to you problem is: Manage the redirect bool in Page component only, and pass a function to update to Login component to update its value and decide the component based on that.
Changes:
1- defined redirect: false in Pages component.
2- A function to change its value in Pages component:
updateValue = (value) => {
this.setState({ redirect: true })
}
3- Pass function to Login component:
renderRedirect = () => {
if(this.props.redirect1) {
return <Home/>
}
else{
// =====> here
return <Login updateValue={this.updateValue} />
}
}
4- After successful Login call this function and render Home Component:
formSubmitHandler = event => {
event.preventDefault();
let formdata = new FormData();
formdata.append("username", this.state.username);
formdata.append("password", this.state.password);
Axios.post("/auth/local",{
"name":this.state.username,
"password": this.state.password
})
.then(res => {
if (res) {
// =======> here
this.props.updateValue(true)
}
})
}
5- Remove this line from Login Component:
{ this.renderRedirect() }
Problem with current code:
You are managing the login session using state variable, so after refreshing the page it will again show the login page not home page. So better to store the value in localStorage and read its value in page component to decide the initial value of redirect.
Suggestion:
Instead of deciding the route/component using boolean, better to use react-router for better structuring/managing the app.
Try return it in render:
import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import '../../App.css';
import Login from '../Login';
import Home from '../Home';
import Header from './Header';
import Footer from './Footer';
class Pages extends Component {
constructor(props) {
super(props)
this.state = {
redirect: false,
}
}
handleClick() {
this.state.redirect = true;
console.log(this.state.redirect);
}
changeRedirect =() =>{
this.state.redirect = true;
console.log(this.state.redirect);
this.forceUpdate()
}
render() {
if(this.props.redirect){
return (
<div className="mh-100 PgWidth">
<Home/>
</div>
)
} else {
return (
<div className="mh-100 PgWidth">
<Login/>
</div>
)
}
}
export default Pages;
You can do it like this
<div className="mh-100 PgWidth">
{this.props.redirect1&&<Home/>}
{!this.props.redirect1&&<Login />}
</div>
But, the best way to do this is using react router and managing the global react state

Not able to add email field in react web app

I am developing a small React App that is integrating with Mobx. I have setup a members store which is the following:
import {observable, action, computed} from 'mobx';
class MemberStore {
#observable members = [];
#action addMember(data) {
const existing = this.members;
this.members = existing.concat(data);
}
#computed get memberCount() {
return this.members.length;
}
}
const store = new MemberStore();
export default store;
Now I have a contact page which has a form of Name and email. Now I am able to add a name but not the email. So basically when I click the submit button I only get the name and a 0 next to the name.
import React, { Component } from 'react';
import Navbar from '../components/Navbar';
import Footer from '../components/Footer';
import Jumbotron from '../components/Jumbotron';
import {inject, observer} from 'mobx-react';
#inject('MemberStore')
#observer
class Contact extends Component {
handleSubmit = (e) => {
e.preventDefault();
const member = this.member.value;
const email = this.email.value;
// const email = this.email.value;
this.props.MemberStore.addMember(member, email);
this.member.value = '';
this.email.value = '';
}
render() {
const {MemberStore} = this.props;
return (
<div>
<Navbar />
<Jumbotron title="Contact Page" subtitle="You want to get in touch"/>
<div className="container">
<h2>You have {MemberStore.memberCount} members.</h2>
<form onSubmit={e => this.handleSubmit(e)}>
<input type="text" placeholder="Enter Your Name" ref={input => this.member = input }/>
<div>
<input type="text" placeholder= "Enter Your Email" ref={input => this.email = input }/>
</div>
<button>Submit</button>
</form>
<ul>
{MemberStore.members.map((member,email) => (
<li key={member}>
{member}
{email}
</li>
))}
</ul>
</div>
<Footer />
</div>
)
}
}
export default Contact;
Any help would be appreciated.
Your problem is probably that addMember takes one parameter data, and you’re passing two parameters to it when you call it: addMember(name, email).
You should pass the name and email in as an object instead:
addMember({name, email})
Your code that maps the MemberStore.members array to JSX is also taking two parameters, when it should only take one object as a param:
{MemberStore.members.map({member,email}) => (
Note that I’m using the ES6 Object Literal Property Value Shorthand syntax above.

Pass data between independent component using flux react

I am trying to pass data from one component to another. but it has no parent child relation and it is independent from each other. I want to do it using flux not redux. Can anyone help me to do this? below are my code.
export class EmpSearch extends React.Component {
constructor(props) {
super(props);
this.state = {
Empnumber: ''
};
}
updateEmpNumber(e) {
this.setState({Empnumber: e.target.value});
}
render() {
return (
<div className="row">
<form>
<div className="form-group">
<label htmlFor="Empnumber">Emp Number</label>
<input type="text" className="form-control" id="Empnumber" placeholder="Emp Number" value={this.state.Empnumber} onChange={this.updateEmpNumber.bind(this)}/>
</div>
</form>
</div>
);
}
}
export default EmpSearch
The other file is where i want to send the EmpNumber is below,
class EmpDetail extends React.Component {
render() {
return (
<div className="container">
<input type="text"/>
</div>
);
}
}
export default EmpDetail;
Assuming you have already implemented the flux architecture in your app.
your 1st component will be like this.
import React from 'react';
import UserAction from '../../Actions/UserActions';
export class EmpSearch extends React.Component {
constructor(props) {
super(props);
this.state = {
Empnumber: ''
};
}
updateEmpNumber(e) {
this.setState({Empnumber: e.target.value});
UserAction.employeeNumb(this.state.Empnumber);
}
render() {
return (
<div className="row">
<form>
<div className="form-group">
<label htmlFor="Empnumber">Emp Number</label>
<input type="text" className="form-control" id="Empnumber" placeholder="Emp Number" value={this.state.Empnumber} onChange={this.updateEmpNumber.bind(this)}/>
</div>
</form>
</div>
);
}
}
export default EmpSearch
The Actions file will look like
import {dispatch,register} from '../Dispatcher/Dispatcher';
export default {
employeeNumb(Data){
dispatch({ actionType:'EMPNO',data:Data});
}
}
The Store will look like
import {dispatch,register} from '../Dispatcher/Dispatcher';
import AppConstants from '../Constants/AppConstants';
import {EventEmitter} from 'events';
const CHANGE_EVENT = 'change';
var a=0;
const UserStore = Object.assign(EventEmitter.prototype,{
emitChange(){
this.emit(CHANGE_EVENT)
},
addChangeListener(callback){
this.on(CHANGE_EVENT,callback);
},
removeChangeListener(callback){
this.removeListener(CHANGE_EVENT,callback)
},
setEmpData(data){
a=data;
},
getEmpData(){
return a;
}
});
dispatcherIndex:register((action)=>{
switch (action.actionType) {
case AppConstants.EMPNO:
UserStore.setEmpData(action.data);
UserStore.emitChange();
break;
}
UserStore.emitChange();
});
export default UserStore;
The dispatcher file
import {Dispatcher} from 'flux';
const flux = new Dispatcher();
export function register(callback){
return flux.register(callback);
}
export function dispatch(actionType,action){
flux.dispatch(actionType,action);
}
and the 2nd Component file looks like
import React from 'react';
import Store from '../../Store/UserStore';
class EmpDetail extends React.Component {
constructor(props){
super(props);
this.state={
empno:''
};
}
componentDidMount(){
Store.addChangeListener(this._onChange);
}
componentWillUnmount = () =>{
Store.removeChangeListener(this._onChange);
}
_onChange = () =>{
this.setState({empno:Store.getEmpData()});
}
render() {
return (
<div className="container">
<input type="text"/>
<input type="button" onClick={()=>{console.log(this.state.empno);}}/>
</div>
);
}
}
export default EmpDetail;
What you have tried might be slightly different but this is the normal flow for what you are looking for.

How to change the form fields by clicking the button in REACT.js?

I have signup.jsx
import React from "react"
import { render } from "react-dom"
import SignupContainer from "./containers/SignupContainer"
class Signup extends React.Component {
user(){
this.props.type='user';
}
hotel(){
this.props.type='hotel';
}
render() {
return (
<div>
Registration Type :
<br></br>
<button onClick={this.user}>user</button>
<button onClick={this.hotel}>hotel</button>
<SignupContainer type={this.props.type}/>
<h1>Signup</h1>
</div>
);
}
}
render(<Signup type='user'/>, document.getElementById('Signup'))
My SignupContainer.jsx
import React from "react"
import Headline from "../components/Headline"
export default class SignupContainer extends React.Component {
render() {
if(this.props.type=='user'){
return (
<div className="container">
<div className="row">
<div className="col-sm-12">
<form action="/loginapp/" method="POST">
First Name:
<input type="text" name="first_name">
</input>
<br></br>
Last Name:
<input type="text" name="last_name"/>
<br></br>
Gender:
<input type="radio" name="gender" value="male" />Male
<input type="radio" name="gender" value="female" /> Female
<br></br>
<input type="submit" value="Submit"/>
</form>
</div>
</div>
</div>
);
} else if(this.props.type=='hotel'){
return(<h1>{this.props.type}</h1>);
}
}
}
What i want is that when i click on user button then it should show me the registration form and when i click on hotel button it should print hotel without reloading the page.
In React, props are passed down from parent to child, and should be considered immutable. On the other hand, state is used by components internally and can be updated with this.setState(), which triggers a re-render. Also, when using native JavaScript classes, you need to bind the class methods to the class if you want this to refer to class. So in your case, something like this should work:
class Signup extends React.Component {
constructor(props) {
super(props);
this.state = { // this is your default state
type: 'user'
}
}
user() {
this.setState({
type: 'user'
})
}
hotel() {
this.setState({
type: 'hotel'
})
}
render() {
return ( < div >
Registration Type:
< br > < /br>
<button onClick={this.user.bind(this)}>user</button >
<button onClick = {this.hotel.bind(this)}>hotel</button>
<SignupContainer type={this.state.type} />
<h1> Signup </h1>
</div>
);
}
}
render( < Signup type = 'user' / > , document.getElementById('Signup'))
Try not to change props of own component after component has mounted. Instead use states.
import React from "react"
import {render} from "react-dom"
import SignupContainer from "./containers/SignupContainer"
class Signup extends React.Component {
constructor(props){
super(props);
this.state = {type : this.props.type};
}
user() {
this.setState({type: 'user'});
}
hotel() {
this.setState({type: 'hotel'});
}
render() {
return ( <div >
Registration Type:
<br />
<button onClick={this.user}>user</button >
<button onClick = {
this.hotel
} > hotel </button>
<SignupContainer type={this.state.type}/ >
<h1> Signup </h1>
</div>
);
}
}
render( < Signup type = 'user' / > , document.getElementById('Signup'))

Resources