Force preact-router to reload a page completely - preact

I have a page that contains a link to a secondary page that creates a record. Here is the problem I'm running into: If I fill out the fields on the secondary page, and return back to create another item, the previous data is still inside my text boxes.
I don't know if this is just how preact works. I thought that by calling route it would unmount the component, thus clearing state. I even tried adding unique keys to my routes (which I heard forces them to unmount).
I really am at wits end.
app.jsx
const App = () => (
<div>
<Header/>
<Router history={createHashHistory()}>
<Home path="/" />
<DisplayUsers key="displayUsers" path="/display-users"/>
<CreateUser key="createUser" path="/create-user"/>
</Router>
</div>
);
create-item.jsx
import { h, Component } from "preact";
import { route } from 'preact-router';
import { $post } from "app/services/ajax.jsx";
import Section from "app/components/section/section.jsx";
import UserList from "app/components/user-list/user-list.jsx";
class CreateUser extends Component {
constructor(props) {
super(props);
this.state = {
userName: "",
route: ""
};
}
handleSubmit = (event) => {
event.preventDefault();
$post("/api/users", this.state, () =>
{
route('/display-users');
}
);
}
handleChange = (event) => {
this.setState({
[event.target.name]: event.target.value
});
}
render() {
return (
<Section title="New User">
<form onSubmit={this.handleSubmit}>
<div className="mat-field">
<label
htmlFor="userName"
className="mat-field__label">
User Name:
</label>
<input
type="text"
id="userName"
name="userName"
className="mat-field__input"
autoComplete="off"
autoFocus="autoFocus"
maxlength="30"
required
onChange={this.handleChange}/>
</div>
<div className="mat-field">
<label
htmlFor="route"
className="mat-field__label">
Route To:
</label>
<UserList
name="route"
onChange={this.handleChange}/>
</div>
{/* Buttons */ }
<div>
<input
type="submit"
value="Create"
className="mat-button mat-button--secondary mat-button--raised"/>
<a
href="/display-users"
className="mat-button">Cancel</a>
</div>
</form>
</Section>
);
}
}
export default CreateUser;

Related

I am having problems with setState

I'm working on a simple login site and to navigate between Login and Sign up site I made a state called "aktivSide" meaning "activeSite" which is supposed to determine whether the login site or the sign up site will display.
Whenever I click on the "Registrer Bruker" (sign up) button, I get this error message:
Uncaught TypeError: Cannot read properties of undefined (reading 'setState')
import planB from "./plan_b.json"
import logo from './bilder/logo.png'
import './App.css';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faEyeSlash, faEye } from '#fortawesome/free-solid-svg-icons'
import React from 'react';
class App extends React.Component {
//React
constructor(props) {
super(props);
this.state = {
aktivSide: "tom"
};
}
render() {
//JavaScript
return (
//jsx (javascript og HTML)
<>
<div onLoad={() => this.setState({ aktivSide: <LoggInn /> })} className="App">
<title>SpeedType</title>
<header className="App-header">
<div id="topp">
<img id="logoen" width={300} src={logo}></img>
</div>
<button onClick={() => console.log(this.state.aktivSide)}>state</button>
{this.state.aktivSide}
</header>
</div>
</>
)
function RegistrerBruker() {
return (
<>
<h1>Registrer Bruker</h1>
<input type="text" placeholder='brukernavn' className='input_text'></input>
<div className='passord'>
<input type="password" placeholder='passord' className='input_text'></input>
<FontAwesomeIcon className='eye_icon' id='eye_icon1' />
</div>
<p id='passordTekst'>tom</p>
<div className='knapper'>
<button className='knapper_login'><p>Logg Inn</p></button>
<button className='knapper_login'><p>Registrer deg</p></button>
</div>
</>
)
}
function LoggInn() {
//JavaScript
return (
//jsx
<>
<h1>Logg inn</h1>
<input type="text" placeholder='brukernavn' className='input_text'></input>
<div className='passord'>
<input type="password" placeholder='passord' className='input_text'></input>
<FontAwesomeIcon className='eye_icon' id='eye_icon1' />
</div>
<p id='passordTekst'>tom</p>
<div className='knapper'>
<button className='knapper_login'><p>Logg Inn</p></button>
<button onClick={() => this.setState({ aktivSide: <RegistrerBruker /> })} className='knapper_login'><p>Registrer deg</p></button>
</div>
</>
)
}
}
}
export default App;
I've tried adding:
this.aktivSide.bind(this);
to the constructor, but nothing will display.

Using the useContext , it says object is not iterable (cannot read property Symbol(Symbol.iterator))?

When ever i am using useContext in the js file, it gives the error "TypeError: Object is not iterable (cannot read property Symbol(Symbol.iterator))". Removing that line , it works perfectly fine . I am not able to figure out the problem with this. Any help would be appreciated.
import { useRef } from "react";
import "./login.css";
import { loginCall } from "../../apicalls";
import { useContext } from "react";
import {AuthContext} from '../../context/AuthContext.js'
export default function Login() {
const email = useRef();
const password = useRef();
const [user,dispatch] = useContext(AuthContext);
const handleClick = (e) => {
e.preventDefault();
// loginCall(
// { email: email.current.value, password: password.current.value },
// dispatch
// );
console.log('hi');
};
// console.log(user);
return (
<div className="login">
<div className="loginWrapper">
<div className="loginLeft">
<h3 className="loginLogo">SocioFolio</h3>
<span className="loginDesc">
Connect with friends and the world around you on SocioFolio.
</span>
</div>
<div className="loginRight">
<form action=""
onSubmit={handleClick}
>
<div className="loginBox">
<input placeholder="Email" type="email" required className="loginInput" />
<input placeholder="Password" type="password" required minLength="6" className="loginInput" />
<button className="loginButton">Log In</button>
<span className="loginForgot">Forgot Password?</span>
<button className="loginRegisterButton">
Create a New Account
</button>
</div>
</form>
</div>
</div>
</div>
);
}

Error occurs in the template of component EmployeeCreateComponent

I'm new to Angular and working on httpclient and httpservice project of CRUD application. While compiling with ng serve in VS code I get the following error:
error: ERROR in src/app/employee-create/employee-create.component.html:18:65 - error TS2554: Expected 1 arguments, but got 0.
employee-create.component.html
<div class="container custom-container">
<div class="col-md-12">
<h3 class="mb-3 text-center">Create Employee</h3>
<div class="form-group">
<input type="text" [(ngModel)]="employeeDetails.name" class="form-control" placeholder="Name">
</div>
<div class="form-group">
<input type="text" [(ngModel)]="employeeDetails.email" class="form-control" placeholder="Email">
</div>
<div class="form-group">
<input type="text" [(ngModel)]="employeeDetails.phone" class="form-control" placeholder="Phone">
</div>
<div class="form-group">
<button class="btn btn-success btn-lg btn-block" (click)="addEmployee()">Create Employee</button>
</div>
</div>
</div>
employee-create component.ts
import { Component, OnInit, Input } from '#angular/core';
import { Router } from '#angular/router';
import { RestApiService } from "../shared/rest-api.service";
#Component({
selector: 'app-employee-create',
templateUrl: './employee-create.component.html',
styleUrls: ['./employee-create.component.css']
})
export class EmployeeCreateComponent implements OnInit {
#Input() employeeDetails = { name: '', email: '', phone: 0 }
constructor(
public restApi: RestApiService,
public router: Router
) { }
ngOnInit() { }
addEmployee() {
this.restApi.createEmployee(this.employeeDetails).subscribe((data: {}) => {
this.router.navigate(['/employees-list'])
})
}
}
The error is obvious in your template addEmployee() method on button click doesnt have any param.
(click)="addEmployee()"
But in your component you are passing dataEmployee param in addEmployee(dataEmployee) method (which looks like not in use).
Hence you can remove dataEmployee param from addEmployee() method.
addEmployee() { // <=== no dataEmployee param
this.restApi.createEmployee(this.employeeDetails).subscribe((data: {}) => {
this.router.navigate(['/employees-list'])
})
}
addEmployee() { // <=== dataEmployee Parameter this.restApi.createEmployee(this.employeeDetails).subscribe((data: {}) => {
this.router.navigate(['/employees-list'])
})
}
you are not passing a Parameter in Html file but you are trying to get parameter in ts that's why you are getting Error.

How to display value in real time without refresh page with React and SocketIO?

I develop a basic application with NodeJS, React and SocketIO.
My NodeJS server sends socket to the React clients with a table of players (string value). I want display this table of players in the react view, and refresh it dynamically when it changes.
I tried some solutions but nothing works great. Have you ideas to do that or to improve my code ?
Thanks
Constructor : this.players[]
constructor(props){
super(props);
this.state = {
endpoint: "http://127.0.0.1:8080",
}
this.gameId = this.props.match.params.id;
this.players = [];
}
showPlayer : display list of players with cards
showPlayers = () => {
const classes = this.props;
let playersCards = [];
console.log(this.players);
this.players.foreach(function(p){
playersCards.push(
<Card className={classes.card}>
<CardHeader
avatar={
<Avatar style={{backgroundColor: "#00FF00"}} aria-label="Recipe">
R
</Avatar>
}
action={
<IconButton>
<MoreVertIcon />
</IconButton>
}
title={p}
subheader=""
/>
</Card>
)
}
return playersCards;
}
Socket.io : get the table of players updated
socket.on('ack-join-game', function(res){
this.players = res.dataGame.players;
});
Render :
const classes = this.props;
return(
<div className="GameConfig">
<h1>Salon de jeu</h1>
<div className="well" style={this.wellStyles}>
<h2>Informations</h2>
Id : {this.gameId}
<br></br>
<h2>Players (0/2)</h2>
<div id="cards">
</div>
{this.showPlayers()}
<form onSubmit={this.handleFormSubmit}>
<br></br>
<Button bsStyle="primary" type="submit" bsSize="large" block>
Lancer la partie
</Button>
</form>
</div>
<ToastContainer store={ToastStore}/>
</div>
)
}
You should store your players in the state of your component as changing them affects what is going to be rendered. Also, you can remove the endpoint if it is never going to change at runtime :
constructor(props){
super(props);
this.state = {
players = [],
}
this.gameId = this.props.match.params.id;
this.endpoint = "http://127.0.0.1:8080";
}
Then call setState to update players and refresh the component in your socket event :
socket.on('ack-join-game', res => {
this.setState({ players: res.dataGame.players })
});
Now, your players will need to be accessed via this.state.players instead of this.players.
You could also completely remove your showPlayers function using map:
const { players } = this.state
const { card } = this.props.classes
return (
<div className="GameConfig">
<h1>Salon de jeu</h1>
<div className="well" style={this.wellStyles}>
<h2>Informations</h2>
Id : {this.gameId}
<br></br>
<h2>Players (0/2)</h2>
<div id="cards">
</div>
{players.map(player =>
<Card className={card} key={player}>
<CardHeader
avatar={
<Avatar style={{ backgroundColor: "#00FF00" }} aria-label="Recipe">
R
</Avatar>
}
action={
<IconButton>
<MoreVertIcon />
</IconButton>
}
title={player}
subheader=""
/>
</Card>
)}
<form onSubmit={this.handleFormSubmit}>
<br></br>
<Button bsStyle="primary" type="submit" bsSize="large" block>
Lancer la partie
</Button>
</form>
</div>
<ToastContainer store={ToastStore} />
</div>
)

ReduxForm handleSubmit refreshes page with fields assigned

Environment
ReduxForm: v6.5.0
Node: v8.1.2
Browser: Google Chrome
I've gone through all the existing issues on handleSubmit page refreshing, but none of them seems to solve my problem.
LoginForm
import React, { Component } from 'react'
import { reduxForm, Field, propTypes } from 'redux-form'
import classNames from 'classnames'
import loginValidation from './validation'
#reduxForm({
form: 'loginForm',
validate: loginValidation
})
export default class LoginForm extends Component {
static propTypes = {
...propTypes
}
inputField = ({ input, label, type, meta: { touched, error } }) => (
<fieldset className="form__fieldset login-form__fieldset">
<div className="form__field">
<input {...input}
type={type}
placeholder={touched && error ? error : label}
className={classNames('form__input login-form__input',
touched && error ? 'ng-invalid' : ''
)}
/> {/* .ng-invalid */}
</div>
{type === 'password' &&
<div className="form__helper login-form__helper">
<div className="small">
<a>I've forgotten my password</a>
</div>
</div>
}
</fieldset>
)
render() {
const { inputField, props } = this
const { handleSubmit, submitting } = props
return (
<div className="habbo-login-form">
<form className="login-form__form" onSubmit={handleSubmit}>
<Field name="username" type="text" component={inputField} label="Username" />
<Field name="password" type="password" component={inputField} label="Password" />
<button className="login-form__button" type="submit" disabled={submitting}>Let's go!</button>
</form>
<div className="login-form__social">
<div className="habbo-facebook-connect" type="large">
<button className="facebook-connect">Login with Facebook</button>
</div>
<div className="habbo-facebook-connect" type="small">
<button className="facebook-connect"></button>
</div>
</div>
</div>
)
}
}
And the HOC LoginHeader:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import classNames from 'classnames'
import LoginForm from './LoginForm'
import { authActions } from '../redux/modules/auth'
#connect(
state => ({
user: state.auth.user,
...state.form.loginForm
}),
{ ...authActions }
)
export default class LoginHeader extends Component {
static propTypes = {
user: PropTypes.object,
login: PropTypes.func.isRequired,
logout: PropTypes.func.isRequired
}
static contextTypes = {
router: PropTypes.object
}
onSubmit = (data) => this.props.login(data).then(console.log)
render() {
const { submitFailed } = this.props
const headerLoginForm = classNames(
'header__login-form',
submitFailed ? 'animated shake' : ''
)
return (
<div className="header__top sticky-header sticky-header--top">
<div className="wrapper">
<div className="header__top__content">
<div className={headerLoginForm}>
<LoginForm onSubmit={this.onSubmit} />
</div>
</div>
</div>
</div>
)
}
}
Even when I try to replace <form onSubmit={handleSubmit}> with <form onSubmit={(e) => e.preventDefault()}> my page still refreshes.
I'm unsure whether or not this is a problem with my coding, browser, version, or whatever else because practically yesterday it worked without any problem.

Resources