I`m new in react, and I get problem with registration:
http.hook.js:17 POST http://localhost:3000/api/auth/register 500 (Internal Server Error)
Error: Что-то пошло не так :(, попробуйте снова
at http.hook.js:21
at async registerHandler (Registration.js:24)
code http.hook.js :
import {useState, useCallback} from 'react';
export const useHttp = () => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const request = useCallback( async (url, method = 'GET', body = null, headers = {}) => {
setLoading(true);
try {
if (body) {
body = JSON.stringify(body);
headers['Content-Type'] = 'application/json'
}
const response = await fetch(url, {method, body, headers});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || 'Что-то пошло не так :(');
};
setLoading(false);
return data;
} catch (e) {
console.log(e)
setLoading(false);
setError(e.message);
throw e;
}
}, [])
const clearError = useCallback( () => setError(null), []);
return { loading, request, error, clearError }
}
and code Registration.js without front-end:
import React, { useState, useEffect } from 'react';
import { useHttp } from '../hooks/http.hook';
import { useMessage } from '../hooks/message.hook';
export const Registration = () => {
const message = useMessage();
const {loading, error, request, clearError} = useHttp();
const [form, setForm] = useState({
nick: '', email: '', password:''
});
useEffect(() => {
console.log(error);
message(error);
clearError();
}, [error, message, clearError]);
const changeHandler = event => {
setForm({ ...form, [event.target.name]: event.target.value });
};
const registerHandler = async () => {
try {
const data = await request('/api/auth/register', 'POST', {...form});
console.log('Data', data)
} catch (e) {
console.log(e)
}
};
I think the problem with your server-side.
HTTP response code 500 means that the server encountered an unexpected condition.
Test your endpoint by curl or XHR request.
Also maybe you send not valid data.
Related
I'm trying to create a login/logout with React and Sweet Alert, but the it keeps saying that the 2nd argument is invalid and I'm not sure where.
Below the code for the login.
Can anyone spot any error in these functions?
If yes, please let me know.
Cheers
import React, {
useState
} from 'react';
import swal from 'sweetalert';
async function loginUser(credentials) {
let BaseUrl = 'process.env.MYCREDENTIALS';
fetch(BaseUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(credentials)
})
.then(data => data.json())
}
export default function Signin() {
const classes = useStyles();
const [username, setUserName] = useState();
const [password, setPassword] = useState();
const handleSubmit = async e => {
e.preventDefault();
const response = await loginUser({
username,
password
});
if ('accessToken') {
swal("Success", {
buttons: false,
timer: 1000,
})
.then((value) => {
localStorage.setItem('accessToken', response['accessToken']);
localStorage.setItem('user', JSON.stringify(response['user']));
window.location.href = "/profile";
});
} else {
swal("Failed", response.message, "error");
}
}
i want to fetch datas from backend with axios Authorization header.
I get token code from local storage and set it to a state.
for first load every thing is ok and datas are showin correctly.but on each render I got 401 (Unauthorized) error.
here is my code. where is the problem?
const UserManage = () => {
const [tokenCode, setTokenCode] = useState("");
const api_url = "http://localhost:5000";
const accessToken = tokenCode;
const AuthAxios = axios.create({
baseURL: api_url,
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
useEffect(() => {
const loginDetail = JSON.parse(localStorage.getItem("authState"));
setTokenCode(loginDetail.token); //access token code from local storage
}, []);
const [users, setusers] = useState([])
useEffect(() => {
const fetchUsers = async() => {
const {
data
} = await AuthAxios.get(`/user/all`);
setUsers(data);
setUsers(data);
};
try {
fetchUsers();
} catch (error) {
console.log(error);
}
}, []);
}
I have a custom react hook fetching number of comments from an API that looks like this:
export async function useFetchNumberOfComments(articleId) {
const [numberOfComments, setNumbeOfComments] = useState(0);
useEffect(() => {
(async () => {
try {
const response = await axios.get(`https://example.com/${articleId}`, {
headers: {
"Content-Type": "application/json",
"X-API-KEY": "X",
Authorization: localStorage.getItem("access_token"),
},
});
const data = await response.data;
setNumbeOfComments(data);
} catch (err) {
console.log(err);
}
})();
}, []);
return numberOfComments;
}
And I want to use it in a Article component that looks like this:
import { useFetchNumberOfComments } from "../utils";
const SingleArticle = () => {
let { id } = useParams();
// Important state
const [numOfComments, setNumOfComments] = useState(0);
// Not important states
const [title, setTitle] = useState("");
const [author, setAuthor] = useState("");
const [content, setContent] = useState("");
const [comments, setComments] = useState([]);
const [commentAuthor, setCommentAuthor] = useState("");
const [commentContent, setCommentContent] = useState("");
const [imageId, setImageId] = useState("");
const [imageUrl, setImageUrl] = useState("");
const [createdAt, setCreatedAt] = useState();
const postComment = async (e) => {
e.preventDefault();
const dataToSend = {
articleId: id,
author: commentAuthor,
content: commentContent,
};
try {
await axios.post(`https://example.com/comments`, dataToSend, {
headers: {
"Content-Type": "application/json",
"X-API-KEY": "X",
Authorization: localStorage.getItem("access_token"),
},
});
// Here, fetch the number of comments from my custom hook and update numOf Comments in this component
setCommentAuthor("");
setCommentContent("");
} catch (err) {
console.log(err);
}
};
return (
<>
<form onSubmit={postComment}>
// Here are some inputs, labels and a submit button
</form>
<h4 className={styles.h1}>Comments({numOfComments})</h4>
</>
);
};
export default SingleArticle;
Now, the problem is that I have no idea how to do the mentioned activity within the Article component: Once the form data(for comment) are sent, trigger the useFetchNumberOfComments custom hook and set the numOfComments state inside article component to the newly fetched data.
I think you'd be better served refactoring the useFetchNumberOfComments hook to return a fetch function and some fetch request meta data, i.e. loading and response and error states.
Example:
export function useFetchNumberOfComments() {
const [numberOfComments, setNumbeOfComments] = useState(0);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const fetchArticleCommentCount = useCallback(async (articleId) => {
setLoading(true);
try {
const response = await axios.get(`https://example.com/${articleId}`, {
headers: {
"Content-Type": "application/json",
"X-API-KEY": "X",
Authorization: JSON.parse(localStorage.getItem("access_token")),
},
});
const data = await response.data;
setNumbeOfComments(data);
setError(null);
return data;
} catch (err) {
console.log(err);
setError(err);
} finally {
setLoading(false);
}
}, []);
return {
fetchArticleCommentCount,
numberOfComments,
loading,
error
};
};
...
import { useFetchNumberOfComments } from "../utils";
const SingleArticle = () => {
const { id } = useParams();
const {
fetchArticleCommentCount,
numberOfComments,
} = useFetchNumberOfComments();
// Important state
const [numOfComments, setNumOfComments] = useState(0);
// Not important states
...
const postComment = async (e) => {
e.preventDefault();
const dataToSend = {
articleId: id,
author: commentAuthor,
content: commentContent,
};
try {
await axios.post(`https://example.com/comments`, dataToSend, {
headers: {
"Content-Type": "application/json",
"X-API-KEY": "X",
Authorization: localStorage.getItem("access_token"),
},
});
// await returned comment count and update local state
const commentCount = await fetchArticleCommentCount(id);
setNumOfComments(commentCount);
// or use the updated numberOfComments value returned from hook
fetchArticleCommentCount(id);
// both are available, but you only need one or the other here
setCommentAuthor("");
setCommentContent("");
} catch (err) {
console.log(err);
}
};
return (
<>
<form onSubmit={postComment}>
// Here are some inputs, labels and a submit button
</form>
<h4 className={styles.h1}>Comments({numberOfComments})</h4>
</>
);
};
export default SingleArticle;
I'm using ReactJS to build a blog app. I can use axios get, put, delete but NOT POST. Every time I post a new blog, it gives me server responded with a status of 500 (Internal Server Error).
I have been struggle with this issue for a week and couldn't figure out the reason. Thank you very much for your help! Let me know if you need additional information.
Here are my codes:
API
import axios from 'axios'
const baseUrl = `/api/blogs`
let token = null
const setToken = newToken => {
token = `bearer ${newToken}`
}
const getAll = () => {
const request = axios.get(baseUrl)
return request.then(response => response.data)
}
const create = async newBlog => {
const config = {headers: { Authorization: token }}
const response = await axios.post(baseUrl, newBlog, config)
return response.data
}
const update = async (id, newObject) => {
const request = axios.put(`${baseUrl}/${id}`, newObject)
const response = await request
return response.data
}
const remove= async (id) => {
const config = {headers: { Authorization: token }}
const request = axios.delete(`${baseUrl}/${id}`, config)
const response = await request
return response.data
}
const exportedObject = { getAll, create, update, setToken, remove }
export default exportedObject
Frontend App.js
import React, { useState, useEffect, useRef } from 'react'
import blogService from './services/blogs'
import loginService from './services/login'
import Blog from './components/Blog'
import LoginForm from './components/LoginForm'
import BlogForm from './components/BlogForm'
import Togglable from './components/Togglable'
import Notification from './components/Notification'
import axios from 'axios'
const App = () => {
const [blogs, setBlogs] = useState([])
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [user, setUser] = useState(null)
const [loginVisible, setLoginVisible] = useState(false)
const [notificationText, setNotificationText] = useState("")
const [notificationStyle, setNotificationStyle] = useState("notification")
const [Toggle, setToggle] = useState(false)
const BlogFormRef = useRef()
useEffect(() => {
const Data = async () => {
const initialBlogs = await blogService.getAll()
setBlogs( initialBlogs )
}
Data()
}, [])
useEffect(() => {
const loggedUserJSON = window.localStorage.getItem('loggedBlogUser')
if (loggedUserJSON) {
const user = JSON.parse(loggedUserJSON)
setUser(user)
blogService.setToken(user.token)
}
}, [])
const addBlog = async (blogObject) => {
BlogFormRef.current.toggleVisibility()
if (blogObject.title !== '' && blogObject.author !== '' && blogObject.url !== '') {
const newBlog = await blogService.create(blogObject)
setBlogs(blogs.concat(newBlog))
setNotificationStyle('notification')
setNotificationText(`A new blog ${blogObject.title} by ${blogObject.author} is added`)
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
setBlogs('')
console.log(blogObject)
document.location.reload()
} else {
setNotificationStyle('Warning')
setNotificationText('You must fill all fields to create a blog')
setToggle(!Toggle)
setTimeout(() => {
setToggle(false)
}, 5000)
}
}
Backend
const blogsRouter = require('express').Router()
const Blog = require('../models/blog')
const User = require('../models/user')
const jwt = require('jsonwebtoken')
const middleware = require("../utils/middleware")
blogsRouter.get('/', async (request, response) => {
const blogs = await Blog.find({}).populate('user', { username: 1, name: 1 })
response.json(blogs)
})
blogsRouter.get('/:id', (request, response) => {
Blog.findById(request.params.id)
.then(blog => {
if (blog) {
response.json(blog)
} else {
response.status(404).end()
}
})
})
blogsRouter.post('/', middleware.userExtractor, async (request, response) => {
const body = request.body
const user = request.user
const decodedToken = jwt.verify(request.token, process.env.SECRET)
if (!decodedToken.id){
return response.status(401).json({error: 'token missing or invalid'})
}
if(body.title === undefined){
return response.status(400).send({
error: 'title is missing'
})
}
else if(body.author === undefined){
return response.status(400).send({
error: 'author is missing'
})
}
else if(body.url === undefined){
return response.status(400).send({
error: 'url is missing'
})
}
else{
const blog = new Blog({
title: body.title,
author: body.author,
url: body.url,
likes: body.likes,
user: user.id
})
const savedBlog = await blog.save()
//console.log(savedBlog)
//console.log(user)
user.blogs = user.blogs.concat(savedBlog.id)
await user.save()
const populatedBlog = await savedBlog.populate('user', { username: 1, name: 1 }).execPopulate()
response.status(200).json(populatedBlog.toJSON())
}
})
blogsRouter.delete('/:id', middleware.userExtractor, async (request, response) => {
const blog = await Blog.findByIdAndRemove(request.params.id)
const user = request.user
const decodedToken = jwt.verify(request.token, process.env.SECRET)
if(! request.token || !decodedToken.id){
return response.status(401).json({error:'token is missing or invalid'})
}
else if(blog.user.toString() === user.id.toString()){
await Blog.findByIdAndRemove(request.params.id)
response.status(204).end()
}
else{
return response.status(401).json({error:'cannot process deletion'})
}
})
blogsRouter.put('/:id', async (request, response) => {
const body = request.body
const blog = {
title: body.title,
author:body.author,
url: body.url,
likes: body.likes
}
await Blog.findByIdAndUpdate(request.params.id, blog, { new: true })
.then(updatedBlog => {
response.json(updatedBlog)
})
})
module.exports = blogsRouter
Mongoose
const mongoose = require('mongoose')
const blogSchema = new mongoose.Schema({
title: {type:String,
required: true},
author:{type:String,
required: true},
url: {type:String,
required: true},
likes: {type:Number,
default: 0},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'}
})
blogSchema.set('toJSON', {
transform: (document, returnedObject) => {
returnedObject.id = returnedObject._id.toString()
delete returnedObject._id
delete returnedObject.__v
}
})
const Blog = mongoose.model('Blog', blogSchema)
module.exports = Blog
Additional information: terminate output, the info is actually POST just cannot render in the front
terminal output
import axios from 'axios';
// const usersUrl = 'http://localhost:3003/users';
const usersUrl = 'http://localhost:8020/users';
export const getUsers = async (id) => {
id = id || '';
return await axios.get(`${usersUrl}/${id}`);
}
export const addUser = async (user) => {
return await axios.post(`${usersUrl}/add`, user);
}
export const deleteUser = async (id) => {
return await axios.delete(`${usersUrl}/${id}`);
}
export const editUser = async (id, user) => {
return await axios.put(`${usersUrl}/${id}`, user)
}
This my client code when I try to add user it adds the user and details in back end in mongo db but cant view it in the front end when I click on the specific user.
import React, { useState, useEffect } from "react";
import { Link, useParams } from "react-router-dom";
import axios from "axios";
const usersUrl = 'http://localhost:8020/users';
const View = () => {
const [user, setUser] = useState({
projectname: '',
projecttype: '',
numberofissuesreported: '',
retestlead: '',
progress: '',
startdate: '',
enddate: '',
});
const { id } = useParams();
useEffect(() => {
loadUser();
//getUsers();
}, []);
const loadUser = async () => {
const res = await axios.get(`http://localhost:8020/users/add`);
setUser(res.data);
};
And this is my view.jsx file.
As the error mentions clearly, if you use response.send, it sends the data to the client. You cannot modify the states once they are sent.
Corrected Code:
export const addUser = async (request, response) => {
// retreive the info of user from frontend
const user = request.body;
// Removed the line
const newUser = new User(user);
try{
await newUser.save();
response.status(201).json(newUser);
} catch (error){
return response.status(404).json({ message: error.message});
}
}
Tip: If you are debugging, just use console.log instead of response.send and see those values on the terminal.
Example:
export const addUser = async (request, response) => {
// retreive the info of user from frontend
const user = request.body;
console.log("Executing..");
console.log(user);
const newUser = new User(user);
try{
await newUser.save();
response.status(201).json(newUser);
} catch (error){
return response.status(404).json({ message: error.message});
}
}