Why isnt my pic getting displayed after using Active Storage? - reactjs

I am trying to implement active storage .And have been following along with this article .Its a very very short article https://dev.to/jblengino510/uploading-files-in-a-react-rails-app-using-active-storage-201c.The backend has been set correctly as instructed...The only problem is in the front end..I am not able to write my React project code in a way thats similar to this project and hence im lacking a correct code.
Here is my Project code
The add review form card
function AddReviewForm({user,handleAddReviews}){
const params = useParams();
const[img,setImg]=useState("");
const[r,setR]=useState("");
const[imgData,setimgData]=useState("");
const newReview = {
img,
r,
imgData,
restaurant_id: params.id,
user_id: user.id,
};
const configObj = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(newReview),
};
function handleReviewSubmit(event) {
event.preventDefault();
fetch(`/reviews`, configObj)
.then((r) => r.json())
.then((review)=>{
handleAddReviews(review);
setR('')
setImg('')
setimgData('')
}
);
}
return (
<>
<h1>Add review form</h1>
<form onSubmit={handleReviewSubmit}>
<div>
<input type="file"
name="picture"
accept="image/png, image/gif, image/jpeg"
id="picture"
onChange={(e)=>setimgData(e.target.files[0])} />
</div>
<div>
<label htmlFor="r" >Review</label>
<input type="text" name="r" value={r} onChange={(e) => setR(e.target.value)} placeholder="review" />
</div>
<input type="submit" />
</form>
</>
)
}
export default AddReviewForm;
And the displayed ReviewCard.js
import { useParams } from "react-router-dom";
function ReviewCard({review,user,handleDelete}){
const{id,img,r,picture,user:reviewuser}=review
function handleDeleteClick() {
fetch(`/reviews/${review.id}`, {
method: "DELETE",
})
handleDelete(review.id)
}
return(
<>
<img src={img}/>
<img src={picture} />
<p></p>
<p>{r}</p>
<h6>By {review.user.name}</h6>
{user.id===reviewuser.id&&<button onClick={handleDeleteClick} >Delete</button>}
</>
)
}
export default ReviewCard;
Pls help me out and lemme know what changed I can do so that my picture gets displayeddd

Related

Unable to make a PATCH request using radio buttons in ReactJS

I am trying to add in a list of tasks and want to change them to either "Complete" or "Not Complete" using radio buttons and then updating it to send a PATCH request to the data to update. When I press update nothing changes on the data.
This is the code I have for this page:
`
function ProjectDetails() {
const [WaxProcedure, setWaxProcedure] = useState("");
const { id } = useParams();
const {
data: project,
error,
isPending,
} = useFetch(`http://localhost:8000/ProjectsData/${id}`);
const history = useNavigate();
const handleClickDelete = () => {
fetch(`http://localhost:8000/ProjectsData/${id}`, {
method: "DELETE",
}).then(() => {
history("/");
});
};
const handleUpdate = () => {
fetch(`http://localhost:8000/ProjectsData/${id}`, {
method: "PATCH",
headers: {
"Content-type": "application/json",
body: JSON.stringify(project),
},
}).then((response) => {
response.json();
});
};
return (
<div className="project-details">
{isPending && <div>Loading...</div>}
{error && <div>{error}</div>}
{project && (
<article>
<h1>{project.Customer}</h1>
<h2>
{project.Part} {project.Description}
</h2>
<h2>{project.Tool}</h2>
<div>Project Status: {project.Stage}</div>
<p>Lead engineer: {project.Engineer}</p>
<div className="procedure-list">
<form onSubmit={handleUpdate}>
Wax: <p>{WaxProcedure}</p>
<input
type="radio"
name="waxprocedure"
value="Not Complete"
required
onChange={(e) => setWaxProcedure(e.target.value)}
/>
Not Complete
<input
type="radio"
name="waxprocedure"
value="Complete"
required
onChange={(e) => setWaxProcedure(e.target.value)}
/>
Complete
<button type="submit" onClick={handleUpdate}>
Update
</button>
</form>
</div>
<button type="submit" onClick={handleClickDelete}>
Delete
</button>
</article>
)}
</div>
);
}
`
Any ideas why the data won't update? I am new to this and spent a long time trying to find an answer.
I have tried the patch request on Postman and this worked too, so nothing wrong with the request.
remove "onsubmit" from form tag and remove type="submit" from both buttons and pass "project" parameter to handleupdate method

React form POST to Express server not working - REST

I am trying to POST a HTML form to an Express server.
When I use a REST client, the POST request works fine and data is correctly sent and registered in DB. So server-side looks good. But my React code won't POST anything. There is no error in the console and input values are correctly targetted. I've tried native fetch method and also Axios, but both are not working. I hope someone will help me on that as I'm not very familiar with REST api's yet.
Here is my Form component :
import React, { useState } from "react";
import Header from "./Header";
import Footer from "./Footer";
const Form = () => {
{/* POST REQUEST */}
const handleFormSubmit = (event) => {
const name = event.target.elements.name.value;
const description = event.target.elements.description.value;
const email = event.target.elements.email.value;
const number = event.target.elements.number.value;
const website = event.target.elements.website.value;
const social_media1 = event.target.elements.social_media1.value;
fetch("http://192.168.1.101:7777/form", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: name,
description: description,
email: email,
number: number,
website: website,
social_media1: social_media1,
}),
})
.then((response) => {
console.log(response);
return response.json();
})
.catch((error) => console.log(error));
};
return (
<>
{/* SOME PAGE STUFF */}
<Header />
<div className="formTitle">
<h3>Create your artist page</h3>
<p>Some fields are required</p>
</div>
{/* HTML FORM */}
<form onSubmit={handleFormSubmit} className="form">
<div>
<legend>About you</legend>
{/* NAME */}
<label htmlFor="name">
Artist name <span className="required">required</span>
</label>
<input
type="text"
id="name"
name="name"
required
placeholder="Oasis"
/>
</div>
<div>
{/* DESCRIPTION */}
<label htmlFor="description">
Description <span className="required">required</span>
</label>
<textarea
rows="5"
type="text"
id="description"
name="description"
required
placeholder="Insert a short description here"
></textarea>
</div>
<div>
<legend>Contact</legend>
{/* EMAIL */}
<label htmlFor="email">
Email address <span className="required">required</span>
</label>
<input
type="email"
id="email"
name="email"
required
placeholder="contact#oasis.uk"
/>
{/* NUMBER */}
<label htmlFor="number">Phone number </label>
<input
type="text"
id="number"
name="number"
required
placeholder="+34 6 12 34 56 78"
/>
{/* WEBSITE */}
<label htmlFor="website">Website </label>
<input
type="text"
id="website"
name="website"
required
placeholder="https://oasis.com"
/>
</div>
<div>
<legend>Social media</legend>
{/* SOCIAL LINK 1 */}
<label htmlFor="social_media1">
Social media link 1 <span className="required">required</span>
</label>
<input
type="text"
id="social_media1"
name="social_media1"
required
placeholder="https://instagram.com/oasis"
/>
</div>
<button className="submit" type="submit">
Submit
</button>
</form>
<div className="temp"></div>
<Footer />
</>
);
};
export default Form;
You can try this method:
const form_Data = new FormData(event.target);
const finalData = {};
for (let [key, value] of form_Data.entries()) {
finalData[key] = value;
}
console.log(finaldata);
fetch("http://192.168.1.101:7777/form", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: finaldata
})
.then((response) => {
console.log(response);
return response.json({response);
})
.catch((error) => console.log(error));
};
First, you should convert all form data into new FormData and you can pass this object to you fetch's POST method
I think it should be work.

React form submit triggers two times

I have React login form. The problem is form submit is called two times. I dont understand it. Can somebody tell me please why? Thanks a lot.
import React from "react"
import LoginErrors from "./LoginErrors"
import LoginSuccess from "./LoginSuccess"
import axios from 'axios'
import { withRouter } from "react-router-dom";
class Login extends React.Component
{
constructor(props)
{
super(props)
this.state = {
name: '',
password: '',
errors: [],
success: []
}
}
changeName = e =>
{
this.setState({name: e.target.value});
}
changePassword = e =>
{
this.setState({password: e.target.value});
}
sendData(e)
{
e.preventDefault();
this.setState({'errors': [], 'success': []});
let formData = new FormData();
formData.set('name', this.state.name);
formData.set('password', this.state.password);
axios({
method: 'POST',
url: 'http://localhost:8000/login',
data: formData,
headers: {
'Content-Type': 'text/html',
'X-Requested-With': 'XMLHttpRequest',
}
})
.then(response => {
// ? returns undefined if variable is undefined
if( response.data?.errors?.length )
{
this.setState({errors: response.data.errors})
}
if( response.data?.success?.length )
{
let data = response.data
this.props.setAccessToken(data.token)
this.props.setUserName(data.user.name)
this.props.history.push('/')
}
})
.catch(response => {
this.setState({errors: ['Login fails. Try it again later please.']})
});
}
render() {
return (
<div className="row justify-content-md-center">
<div className="col-sm-12 col-md-6">
<div id="loginForm">
<h2 className="">Login</h2>
<LoginSuccess success={this.state.success} />
<LoginErrors errors={this.state.errors} sendParentMessage={this.handleErrorsChildMessage} />
<form onSubmit={e => {this.sendData(e)}}>
<div className="form-group">
<label htmlFor="name">Name</label>
<input ref={this.email} name="name" className="form-control" type="text" onChange={this.changeName} />
</div>
<div className="form-group">
<label htmlFor="password">Heslo</label>
<input ref={this.password} name="password" className="form-control" type="password" onChange={this.changePassword} />
</div>
<div className="form-group">
<button name="sbmt" className="btn btn-primary" type="submit">OdoslaƄ</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
So the problem is in axios preflyght request which is related to the CORS policy. But How to stop it?

How do I redirect to another page on form submit?

I'm trying to redirect to a certain page once I post my form but it doesn't redirect, it only posts the form data and does not redirect to the stated page
I've tried appending the && operator in order for onSubmit to do both functions but to no avail. I also tried having both "onSubmit" and "onClick" but it's only "onSubmit" that works
//./userspost.js
import React, { Component } from "react";
import { Redirect, Link } from "react-router-dom";
import Form1 from "./form1";
import { createUsers } from "./actions/appactions";
class userspost extends Component {
state = {
redirect: false
};
setRedirect = () => {
this.setState({
redirect: true
});
};
renderRedirect = () => {
if (this.state.redirect) {
return <Redirect to="/users" />;
}
};
handleSubmit(data) {
console.log("form submission data", data);
createUsers(data);
}
render() {
return (
<div>
{this.renderRedirect()}
<Form1 onSubmit={this.handleSubmit && this.setRedirect} />
</div>
);
}
}
export default userspost;
for the posting the form data
//./form1.js
import React from "react";
import { Link } from "react-router-dom";
var createReactClass = require("create-react-class");
const Form1 = createReactClass({
//setting initial state
getInitialState() {
return {
firstName: this.props.firstName,
lastName: this.props.lastName,
userName: this.props.userName,
role: this.props.role
};
},
handleFirstChange(e) {
this.setState({
firstName: e.target.value
});
},
handleLastChange(e) {
this.setState({
lastName: e.target.value
});
},
handleUserChange(e) {
this.setState({
userName: e.target.value
});
},
handleRoleChange(e) {
this.setState({
role: e.target.value
});
},
handleSubmit(e) {
e.preventDefault();
this.props.onSubmit(this.state);
},
render() {
return (
<form
name="categories_post"
className="form-horizontal"
onSubmit={this.handleSubmit}
>
<div id="categories_post">
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="firstName"
>
First Name
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.firstName}
onChange={this.handleFirstChange}
id="firstName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="lastName"
>
Last Name
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.lastName}
onChange={this.handleLastChange}
id="lastName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label
className="col-sm-2 control-label required"
htmlFor="userName"
>
UserName
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.userName}
onChange={this.handleUserChange}
id="userName"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<label className="col-sm-2 control-label required" htmlFor="role">
Role
</label>
<div className="col-sm-10">
<input
type="text"
value={this.state.role}
onChange={this.handleRoleChange}
id="role"
required="required"
className="form-control"
/>
</div>
</div>
<div className="form-group">
<div className="col-sm-2" />
<div className="col-sm-10">
<button
type="submit"
id="categoriesSubmit"
className="btn-default btn"
>
submit
</button>
</div>
</div>
<div className="form-group">
<div className="col-sm-2" />
<div className="col-sm-10">
<button className="btn btn-danger">
<Link to="/users">Home</Link>
</button>
</div>
</div>
</div>
</form>
);
}
});
export default Form1;
for posting using the fetch API
//./actions/appactions.js
import fetch from "isomorphic-fetch";
export function createCategories(data) {
return fetch("https://localhost:44341/api/categories", {
method: "POST",
mode: "cors",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
.then(res => {
return res;
})
.catch(err => err);
}
export function createUsers(data) {
return fetch("https://localhost:44341/api/users/create", {
method: "POST",
mode: "cors",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
.then(res => {
return res;
})
.catch(err => err);
}
export function createBusiness(data) {
return fetch("https://localhost:44341/api/businesslistings/create", {
method: "POST",
mode: "cors",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
.then(res => {
return res;
})
.catch(err => console.log(err));
}
The issue is that you are rendering the Redirect component along with the rest of your JSX everytime. Rendering only <Redirect to="" /> should solve your problem.
class userspost extends Component {
state = {
redirect: false
};
setRedirect = () => {
this.setState({
redirect: true
});
};
handleSubmit(data) {
console.log("form submission data", data);
createUsers(data);
}
render() {
if( this.state.redirect ){
return <Redirect to="users/" />
}
return (
<div>
{this.renderRedirect()}
<Form1 onSubmit={this.handleSubmit} />
</div>
);
}
}
Also, use only the handleSubmit function in your form onSubmit event. Since adding two functions with && could cause unexpected results. And when everything is ready to redirect, just call your function setRedirect.
There is someone that already answered something similar, so I took a bit of help from there. Check it out:
https://stackoverflow.com/a/43230829/5568741

'Uncaught SyntaxError: Unexpected token <' on Login Form

In my NextJS app.I'm developing a login page and now I'm getting the following error.
Uncaught SyntaxError: Unexpected token <
This was not appearing before and it started appearing yesterday.I googled the error message and browsed through many SO answers but none of them were helpful.I removed all form related onSubmit and onChange code but the error is still there.Since which code causes this error,I will post entire Login component here.
import React, { Component } from 'react';
import Heading from '../components/Heading';
class Login extends Component{
constructor(props) {
super(props);
this.onChangeInput = this.onChangeInput.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
date: new Date().toJSON().slice(0,10),
username: '',
password: ''
}
}
onChangeInput(e) {
this.setState({
[e.target.name]: e.target.value
});
}
onSubmit(e) {
e.preventDefault();
const t = {
date: new Date().toJSON().slice(0,10),
username: this.state.username,
password: this.state.password
}
fetch('/server', {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify(this.state)
})
this.setState({
username: '',
password: ''
});
}
render(){
return(
<div>
<div style={{textAlign: "center"}}>
<h1>PackMasters Ceylon (Pvt) Ltd</h1>
<h2>Inventory Management System</h2>
<h3>Login</h3>
</div>
<form onSubmit={this.onSubmit} onChange={this.onChangeInput} className={"col-md-4 col-md-offset-4"}>
<Heading title="Login | PackMasters Ceylon (Pvt) Ltd" />
<div className={"form-group"}>
<label htmlFor="username">Username</label>
<input type="text" name="username" value={this.state.username} className={"form-control"} id="username"/>
</div>
<div className={"form-group"}>
<label htmlFor="passsword">Password</label>
<input type="password" name="password" value={this.state.password} className={"form-control"} id="password" />
</div>
<div className={"form-group"}>
<input type="submit" className={"form-control"} value="Log In"/>
</div>
</form>
</div>
);
}
}
export default Login;
After struggling a lot, I found out that it is caused by the browser cache.The problem was solved after clearing browser cache on Chrome.Still I'm not able to explain the exact reason for that.However I will mention here how to clear cache on Google Chrome.
On your computer, open Chrome.
At the top right, click More.
Click More tools > Clear browsing data.
At the top, choose a time range. To delete everything, select All time.
Next to "Cookies and other site data" and "Cached images and files," check the boxes.
Click Clear data
A few issues:
The change handler should go on each input, not on the form
A bad idea to set the timestamp in the constructor... Seems you were already going in the right direction...
If you convert the handlers into arrow functions (no this context) no need to bind in the constructor (that's just a side note...)
Try this:
import React, { Component } from 'react';
import Heading from '../components/Heading';
class Login extends Component {
state = { username: '', password: '' };
handleChange = e => {
this.setState({ [e.target.name]: e.target.value });
};
handleSubmit = e => {
e.preventDefault();
const user = {
date: new Date().toJSON().slice(0, 10),
username: this.state.username,
password: this.state.password,
};
fetch('/server', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(user),
});
this.setState({ username: '', password: '' });
};
render() {
return (
<div>
<div style={{ textAlign: 'center' }}>
<h1>PackMasters Ceylon (Pvt) Ltd</h1>
<h2>Inventory Management System</h2>
<h3>Login</h3>
</div>
<form
onSubmit={this.handleSubmit}
className={'col-md-4 col-md-offset-4'}
>
<Heading title="Login | PackMasters Ceylon (Pvt) Ltd" />
<div className={'form-group'}>
<label htmlFor="username">Username</label>
<input
type="text"
name="username"
value={this.state.username}
className={'form-control'}
id="username"
onChange={this.handleChange}
/>
</div>
<div className={'form-group'}>
<label htmlFor="passsword">Password</label>
<input
type="password"
name="password"
value={this.state.password}
className={'form-control'}
id="password"
onChange={this.handleChange}
/>
</div>
<div className={'form-group'}>
<input type="submit" className={'form-control'} value="Log In" />
</div>
</form>
</div>
);
}
}
export default Login;
Edit: Add a then and a catch block to fetch:
fetch('/server', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(user),
}).then(res => res.json())
.then(response => console.log('Success:', JSON.stringify(response)))
.catch(error => console.error('Error:', error));
Also, I noticed you are using Next.js... You need to install Isomorphic Unfetch https://github.com/developit/unfetch/tree/master/packages/isomorphic-unfetch
In my case, static files were not being served due to global authentication enabled. which was also authenticating static files. So I had to apply #Public() metadata to that route to allow into JwtAuthGuard.
#Public()
#Get('/_next/static/*')
async getStaticContent(
#Req() req: IncomingMessage,
#Res() res: ServerResponse,
) {
await this.appService.handler(req, res);
}
More details on public metadata below.
https://docs.nestjs.com/security/authentication#enable-authentication-globally
And make sure your "esversion":6 is 6 for that follow below flow
For Mac VSCode : Code(Left top corner) => Prefrences => Settings => USER SETTINGS. and check at right side and write below Code
{
"workbench.colorTheme": "Visual Studio Dark",
"git.ignoreMissingGitWarning": true,
"window.zoomLevel": 0,
// you want to write below code for that
"jshint.options": {
"esversion":6
},
}

Resources