fetch POST not working on heroku but work locally - javascript

So I tried to make a request using
import React, {useState} from 'react';
const CommentForm = (props) => {
const [inputHandler, setInputHandler] = useState();
const [nameHandler, setNameHandler] = useState();
const URL_COMMENT = `https://damp-sierra-44032.herokuapp.com/API/${props.postID}/comment`
const submitValue = async (e) => {
const data = {name: nameHandler, comment: inputHandler}
await postComment(data);
window.location.reload()
}
async function postComment(data) {
await fetch(URL_COMMENT, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
}
return (
<div>
<form>
<input type="text" name="name" placeholder="Name..." value={nameHandler} onChange={e => setNameHandler(e.target.value)} required></input>
<input type="text" name="comment"placeholder={"Write comment here..."} value={inputHandler} onChange={e => setInputHandler(e.target.value)} required></input>
<button type="submit" onClick={submitValue}>Submit</button>
</form>
</div>
)
}
export default CommentForm
to heroku from my React app and when i clicked submit button the heroku log shows
heroku log
but when I tried to request from my app that runs locally (localhost:8000) it works just fine and succesfully creates new comment.
I wonder what's wrong?

Related

how to update (when login put token and logout reset) global variable in react for use it on all conponents

I try to make a global variable in react. I succeeded to have global variable and update it when user is login but when I refresh page or go on an another page the variable is clear.
for example I connect with form the user if data is good I put the token in variable like this :
import React, { useEffect, useState } from "react";
import { Navigate, redirect, useNavigate } from "react-router-dom";
import { json } from "stream/consumers";
import Fetch from "../conponents/Fetch";
import globalToken from '../GlobalVariable'
const Login: React.FC = () => {
var [user, setUser] = useState<string>("");
var [pass, setPass] = useState<string>("");
var [login, setLogin] = useState<boolean>(false);
const navigate = useNavigate();
useEffect(() => {
//async function dataFetch(user: string, pass: string) {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "text/plain");
var raw =
'{\n "username": "' + user + '",\n "password": "' + pass + '"\n}';
var requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
};
fetch("https://bilemo.thomas-dasilva.fr/BileMo/login_check", requestOptions)
.then((response) => response.text())
.then((result: any) => {
if (result !== '{"code":401,"message":"Invalid credentials."}') {
let token: any = JSON.parse(result);
//process.env.REACT_APP_TOKEN = token.token;
//console.log(process.env.REACT_APP_TOKEN)
globalToken.test = token.token
setLogin(true);
return navigate("/home");
}
})
.catch((error) => console.log("error", error));
//}
});
return (
<>
<main>
<section>
<h1>Login</h1>
<form
method="POST"
onSubmit={(e) => {
e.preventDefault();
var inputUser = document.getElementById(
"username"
) as HTMLInputElement;
var inputPassword = document.getElementById(
"password"
) as HTMLInputElement;
setUser(inputUser.value);
setPass(inputPassword.value);
//<Fetch username="test" password="test" />;
}}
>
<div>
<label htmlFor="username">Username</label>
<input
type="text"
name="username"
id="username"
data-testid="username"
/>
</div>
<div>
<label htmlFor="password">Password</label>
<input
type="password"
name="password"
id="password"
data-testid="password"
/>
</div>
<button type="submit" data-testid="btnLogin">
Go login
</button>
</form>
</section>
</main>
</>
);
};
export default Login;
when the user I redirect and I console.log(globalToken.test) I have the token in but when I refresh or change page the variable is clear and return the initial value.
I setup variable like this :
var globalToken = {test: ""}
export default globalToken
I put this in a file and I import it on other conponent
I have try with window but didn't work and with global
I would like to use this variable to check if the user is connect on no, for example if var not empty is :
if (globalToken.test.length > 1) {
}
but variable not register the token when I refresh page.
It's possible with react to do this ?
You need to use either a sessionStorage or localStorage to persist data across reloads, which is available thru the window object. This elegant hook pretty much answers your question.

How Gatsby Functions handle file upload in the contact form

I could make Contact Form by using Gatsby Functions and SendGrid. The value of Input text and Textarea can be successfully sent, but I am wondering how I can handle the file to upload and send. <input type="file" id="formFile" />
In the case of Next.js' API Router, it seems to be possible by installing "Next-connect" and "multiparty" package.
Any idea in the case of Gatsby Functions?
api/form_sent.js
export default function formHandler(req, res) {
const sgMail = require('#sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_APIKEY);
const { method, body } = req;
const mailData = {
from: process.env.AUTHORIZED_SENDER,
to: body.formEmail,
subject: 'question from web',
html: `<p>${body.formName}<p>${body.formTextarea}</p>`,
}
const results = sgMail.send(mailData)
.then(result => res.status(200).json(JSON.stringify(result)))
.catch(error => res.status(500).json(JSON.stringify(error)))
}
pages/form.js
import * as React from "react"
import Layout from "../components/layout"
export default function FormPage() {
const [serverResponse, setServerResponse] = React.useState(``)
async function onSubmit(e) {
e.preventDefault()
const response = await window
.fetch(`/api/send`, {
method: `POST`,
headers: {
"content-type": "application/json",
},
body: JSON.stringify(value),
})
.then(res => res.json())
setServerResponse(response)
}
return (
<Layout>
<form onSubmit={onSubmit} method="POST" action="/api/send">
<input type="text" id="formName" />
<input type="email" id="formEmail" />
<textarea id="formTextarea"></textarea>
<input type="file" id="formFile" />
<button type="submit">Send</button>
</form>
</Layout>

TypeError: Cannot read properties of undefined (reading 'data') console.log(data) isnt returning user information

So basically I'm making a login function in React and I've made users using api I've stored the users in my MongoDB database and I'm getting no coding errors in my terminal I now have tried to login to one of the accounts and check the console on my browser and I keep getting back the error Cannot read properties of undefined (reading 'data').
Its saying that my console.log(data) isn't reading any properties and I'd appreciate some help on how i can fix this I'll paste down the code below to show what I've done
I need the console.log(data) to show the user which I log into information once I've logged in that should appear in the console but the error which I've trying to resolve isn't allowing it
import axios from 'axios';
import React, { useState } from 'react';
import { Col, Container, Row, Form, Button } from "react-bootstrap";
import './Login.css'
export const Login = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const submitHandler = async (e) => {
e.preventDefault();
try {
const config = {
headers: {
"Content-type": "application/json"
},
};
setLoading(true)
const { data } = await axios.post(
"/api/users/login",
{
email,
password,
},
config
);
//Here is the console.log which isnt returning the users info in my console
console.log(data);
localStorage.setItem('userInfo', JSON.stringify(data));
setLoading(false);
} catch (error) {
setError(error.response.data);
}
};
return (
<Form onSubmit={submitHandler}>
<Form.Group controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control
type="email"
value={email}
placeholder="Enter email"
onChange={(e) => setEmail(e.target.value)}
/>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
value={password}
placeholder="Password"
onChange={(e) => setPassword(e.target.value)}
/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
);
};
export default Login;
Try the following, without async/ await.
axios.post("api/users/login", { email, password, },config)
.then(res=>res.data)
.then(data=> {
console.log(data);
localStorage.setItem('userInfo', JSON.stringify(data));
setLoading(false);
})
.catch(error => {
setError(error)
})
I had the same error,
in my project I was using axios in an async function with await command as below
(bmUserApi is an api library which I coded myself over axios )
onLogin = async(formValues) => {
this.setState({loading:true, error: ""});
try {
var ls_response = await bmUserApi.login(formValues);
this.setState({loading: false});
const lv_token = ls_response.headers['x-auth-token'];
Redux_Set_User(lv_token, this.props.redux_dispatch, this.props.history);
when I was checking the error position on Google Chrome in "Call Stack" part, I've seen that my api library was trying add to authentication token to the api call header, by reading from localStorage of the browser.
I was doing it by using axios interceptors as below :
axiosClient.interceptors.request.use(
async function(config) {
config.headers = {
'Content-Type': 'application/json'
}
// token :
var ls_user = JSON.parse(localStorage.getItem('user'));
const authToken = ls_user.token;
if (authToken)
config.headers['x-auth-token'] = authToken;
return config;
},
error => { Promise.reject(error) }
)
But this is login call .. so off course there is no stored data and token on the browser yet. So the "ls_user" variable in the above code was null .. this was causing the error. I just added control before that.
I hope this can be useful to your case.

React.js: Component updates only after refreshing the page [Post request]

Hi guys still new to react, working on a small react app supposed to display pictures of hamsters.
Inside of the AddHamster component, I have a Post request that seems to be working fine; " Object are passed into Database! "
My issue is that the object only get's displayed after refreshing the page. I
need the hamster object to be displayed on the page directly after pressing the Add Button, connected to the form.
Any clue on this?
import React, {useState} from "react";
import HamsterCard from './HamsterCard'
import './AddHamster.css';
const AddHamster = () => {
const [name, setname ] = useState('')
const [age, setage ] = useState('')
const [favFood, setfavFood ] = useState('')
const [imgName, setImgName ] = useState('')
const [hamsterItems, setHamsterItems] = useState([])
async function handleAddHamster(){
const newHamster = {
name: name,
age: Number(age),
favFood: favFood,
imgName: imgName
}
console.log(newHamster, 'newHamster')
const response = await fetch('/hamsters ', {method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(newHamster)
})
const data = await response.json()
console.log(data, "this is a data response");
if (response.status === 200){
setHamsterItems([...hamsterItems,name, age, favFood, imgName])
setname('')
setage('')
setfavFood('')
setImgName('')
}
}
return(
<div className="add-todo-wrapper">
<form onSubmit={(e) => e.preventDefault()}>
<label>name
<input type="text"
name="id"
value={name}
onChange={e => setname(e.target.value)} />
</label>
<label>age
<input type="text"
name="id"
value={age}
onChange={e => setage(e.target.value)} />
</label>
<label>favFood
<input type="text"
name="id"
value={favFood}
onChange={e => setfavFood(e.target.value)} />
</label>
<label>Image
<input type="text"
name="id"
value={imgName}
onChange={e => setImgName(e.target.value)} />
</label>
<div className="message">{hamsterItems ? <p>{[...hamsterItems]}</p> : null}</div>
</form>
<button onClick={() => handleAddHamster()}>ADD</button>
<HamsterCard />
</div>
)
}
export default AddHamster;
import React, {useState, useEffect} from "react";
import './HamsterCard.css';
const HamsterCard = () => {
const [hamsters, setHamsters] = useState([])
useEffect(() => {
async function get(){
const response = await fetch('/hamsters', {method: 'GET',})
const data = await response.json()
setHamsters(data)
console.log(data)
}
get()
}, [] );
return (
<div className="container">
<div className="hamster-card">
{hamsters.map((hamster) => (
<Hamster hamster={hamster}
key={hamster.id} />
))
}
</div>
</div>
)
}
export default HamsterCard;
import React, {useState} from "react";
const Hamster = ({name, age, favFood, hamster}) => {
const [hamsterDeleted, setHamsterDeleted] = useState(false)
async function deleteHamster(id) {
const response = await fetch(`/hamsters/${id}`, { method: "DELETE" });
setHamsterDeleted(true)
}
return (
hamsterDeleted ? null : (
<div>
<button onClick={() => deleteHamster(hamster.id)}>Delete</button>
<h2>{hamster.name}</h2>
<p>Ã…lder:{hamster.age}</p>
<p>Favorit mat:{hamster.favFood}</p>
<img src={'./img/' + hamster.imgName} alt="hamster"/>
</div>
))
}
export default Hamster;
After changing code
setHamsterItems([...hamsterItems,name, age, favFood, imgName])
to
setHamsterItems([...hamsterItems, newHamster])
I get this error message:
In the AddHamster component when you update hamsterItems it renders the whole component but in Hamstercard you are using useEffect to fetch the latest hamsters from the database
which runs only the first time the HamsterCard component mounts to re-render the HamsterCard you have to add some dependency in useEffect of HamsterCard so this will re-render the HamesterCard every time you click add button.
for which you can send hamsterItems as props to HamsterCard and pass that to useEffect dependency array.
<HamsterCard hamsterItems={hamsterItems}/>
function HamsterCard({ hamsterItems }) {
useEffect(() => {
async function get(){
const response = await fetch('/hamsters', {method: 'GET',})
const data = await response.json()
setHamsters(data)
console.log(data)
}
get()
}, [hamsterItems] );
It's now working.. problem that Is was this line:
<div className="message">{hamsterItems ? <p>{[...hamsterItems]}</p> : null}</div>
Was trying to render an object directly into the jsx..

How to connect login API in reactjs

I am creating login form for practice. I need to connect online API. I have no idea hot connect login API . I Just connect only fetch data API and not able to connect login API. I have design but not able to connect API .I am working in "react": "^16.12.0". using react hooks
enter code here
import React, { useState } from "react";
import { Wrapper } from "./vehiclesTableStyles";
import { PostData } from "./postData";
function VehiclesTable() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const submitForm = e => {
e.preventDefault();
PostData(username, password).then(result => {
console.log(result);
});
console.log("username", username);
console.log("password", password);
};
return (
<Wrapper>
<div className="search_box">
<form onSubmit={submitForm}>
<input
name="name"
type="text"
placeholder="username"
onChange={e => setUsername(e.target.value)}
/>
<input
name="password"
type="password"
placeholder="search"
onChange={e => setPassword(e.target.value)}
/>
<input type="submit" value="login" />
</form>
</div>
</Wrapper>
);
}
export default VehiclesTable;
export function PostData(userData) {
let BaseUrl = "https://reqres.in//api/login";
console.log("userData", userData);
return new Promise((resolve, reject) => {
fetch(BaseUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
// body: JSON.stringify(userData)
})
.then(response => response.json())
.then(responseJson => {
resolve(responseJson);
})
.catch(error => {
reject(error);
});
});
}
I also have the same problem. check the code below. You are making some mistake in code while calling api. You need to call in React life cycle hooks that is the best way.
enter code here
import React, { useState } from "react";
import { Wrapper } from "./vehiclesTableStyles";
import { PostData } from "./postData";
function VehiclesTable() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const submitForm = e => {
e.preventDefault();
PostData(username, password).then(result => {
console.log(result);
});
console.log("username", username);
console.log("password", password);
};
return (
<Wrapper>
<div className="search_box">
<form onSubmit={submitForm}>
<input
name="name"
type="text"
placeholder="username"
onChange={e => setUsername(e.target.value)}
/>
<input
name="password"
type="password"
placeholder="search"
onChange={e => setPassword(e.target.value)}
/>
<input type="submit" value="login" />
</form>
</div>
</Wrapper>
);
}
export default VehiclesTable;
export function PostData(userData) {
let BaseUrl = "https://reqres.in//api/login";
console.log("userData", userData);
return new Promise((resolve, reject) => {
fetch(BaseUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
// body: JSON.stringify(userData)
})
.then(response => response.json())
.then(responseJson => {
resolve(responseJson);
})
.catch(error => {
reject(error);
});
});
I am creating syntax error 'reqres.in//api/login' correct is 'reqres.in/api/login' and also sending email and password as array. that should I have to send as object. like this{email, password}
fetch(baseUrl,
{
method: "POST",
mode: 'cors', // no-cors, cors, *same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
referrer: 'no-referrer',
headers: {
'Content-Type': 'application/json',
...headers
}
})
use this basic fetch config

Categories