how get data in nodejs received from frontend in reactjs? - node.js

I am begineer in reactjs and nodejs, and I think i post data successfully from front end to backend, but now i want to fetch and display received data from frontend in console, but i didnot know how to do it, anyone guide me in this situation? cause when i print something in console like console.log(data) that time it displays some logs in console but i want to display received data in console
demoLogin.js
// this is frontend in reactjs
import React, { Component } from 'react'
import axios from 'axios'
class Login extends Component {
constructor(props) {
super(props)
this.state = {
username:'',
password:''
}
}
usernameHandler=event=>{
this.setState({
username:event.target.value,
})
}
passwordHandler=event=>{
this.setState({
password:event.target.value
})
}
submitHandler=event=>{
let data = {
username: this.state.username,
password: this.state.password,
};
event.preventDefault()
console.log(this.state)
axios.post('http://localhost:8080/note', data,{
headers: {'Content-Type':'application/json'}
})
.then(res => {
console.log(res)
})
}
render() {
const {username, password}=this.state
return (
<div className="custom_wrapper">
<div className="custom_form-wrapper">
<h1>SIGN IN INTO YOUR ACCOUNT</h1>
<form onSubmit={this.submitHandler} >
<div className="custom_username" >
<label htmlFor="username">User Name</label>
<input className='custom_input'
placeholder="example#email.com"
type="text"
name="username"
value={username}
onChange={this.usernameHandler}
/><br></br>
<label htmlFor="password">Password</label>
<input className='custom_input'
placeholder="password"
type="password"
name="password"
value={password}
onChange={this.passwordHandler}
/>
<button type="submit" >Login</button>
</div>
</form>
</div>
</div>
)
}
}
export default Login
server.js
//this is backend in nodejs
var restify=require('restify')
const corsMiddleware = require('restify-cors-middleware2');
const { data } = require('jquery');
var server=restify.createServer() //server created
server.use(
function crossOrigin(req,res,next){
res.header("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Credentials', true); // If needed
res.header("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
return next();
}
);
const cors = corsMiddleware({
preflightMaxAge: 5, //Optional
origins: ['*'],
allowHeaders: ['*'],
exposeHeaders: ['*']
})
server.pre(cors.preflight)
server.use(cors.actual)
server.use(restify.plugins.bodyParser());
//get data from login form
function userCreation(req, res, next) {
console.log('data received...')
console.log(res.json(data))
return next();
}
server.post('/note', userCreation);
server.listen(8080, function(){
console.log("server started...")
})

Simply create a a GET request to that url you POST ed.
import axios from 'axios'
class App extends Component {
constructor (props) {
super(props)
this.state = {
username: ''
}
this.handleClick = this.handleClick.bind(this)
}
handleClick () {
axios.get('http://localhost:8080/note')
.then(response => this.setState({username: response.data.name}))
}
render () {
return (
<div className='show_my__username'>
<button className='button' onClick={this.handleClick}>Click Me</button>
<p>{this.state.username}</p>
</div>
)
}
}

Related

Access to fetch from api blocked by CORS policy: No Access-Control-Allow-Origin

I have a route on React where I change the user password.
const { isLoading, error, sendRequest, clearError } = useHttpClient();
const userId = useParams().userId;
const navigate = useNavigate();
const auth = useContext(AuthContext);
const [formState, inputHandler] = useForm(
{
currentPassword: {
value: "",
isValid: false,
},
newPassword: {
value: "",
isValid: false,
},
confirmNewPassword: {
value: "",
isValid: false,
},
},
false
);
const changePasswordHandler = async (event) => {
event.preventDefault();
if (
formState.inputs.newPassword.value ===
formState.inputs.confirmNewPassword.value
) {
try {
const formData = new FormData();
formData.append("password", formState.inputs.confirmNewPassword.value);
await sendRequest(
process.env.REACT_APP_BACKEND_URL +
`/users/${userId}/change-password`,
"PATCH",
formData,
{
Authorization: "Bearer " + auth.token,
"Content-Type": "application/json",
}
);
navigate(`/users/${userId}`);
} catch (err) {}
}
};
return (
<div className="changePasswordForm">
<ErrorModal error={error} onClear={clearError} />
<Card className="changePassword">
{!isLoading && inputHandler && (
<form onSubmit={changePasswordHandler}>
<Input
element="input"
id="currentPassword"
type="password"
label="Current Password"
validators={[VALIDATOR_MINLENGTH(5)]}
onInput={inputHandler}
/>
<Input
element="input"
id="newPassword"
type="password"
label="New Password"
validators={[VALIDATOR_MINLENGTH(5)]}
onInput={inputHandler}
/>
<Input
element="input"
id="confirmNewPassword"
type="password"
label="Confirm New Password"
validators={[VALIDATOR_MINLENGTH(5)]}
onInput={inputHandler}
/>
<Button type="submit" disabled={!formState.isValid}>
Save Changes
</Button>
</form>
)}
</Card>
</div>
Every other route is working nice, even another route which is similar to the one I'm facing problems. It's a route to update user info and it works great. I have tried to add the mode: 'no-cors' but it still didn't work. The headers on backend are okay as other routes work great.
It works great on postman too so it's not a backend problem.
Your issue is not in the front-end code. The solution is adding headers to your back-end for Access-Control-Allow-Headers and Access-Control-Allow-Origin. If you are using NodeJS, set the headers like this as a middleware.
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept'
)
next()
})

post method from API express & angular 10

I'm trying to do a post method with angular and express.js to do that I created a file called index.js where I added different method but in my front end in Angular I would like to simply add data, how to do with reactive forms ?
I followed several tutorials but I did my best
thank you.
index.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
const parkings = require('../parkings.json');
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.use(express.json());
// Get all parkings details
app.get('/parkings', (req, res) => {
res.status(200).json(parkings)
});
// Get parkings by id
app.get('/parkings/:id', (req, res) => {
const id = parseInt(req.params.id)
const parking = parkings.find(parking => parking.id === id)
res.status(200).json(parking)
});
// post
app.post('/parkings', (req, res) => {
parkings.push(req.body)
res.status(200).json(parkings)
})
app.listen(3000, () => {
console.log("Listening to port 3000");
})
service
url: string = ('http://localhost:3000');
parkingForm = new FormGroup({
name: new FormControl(),
type: new FormControl(),
city: new FormControl()
});
array: any [];
constructor(private http: HttpClient) { }
get(): Observable<any> {
return this.http.get<any>(`${this.url}/parkings`);
}
postMethod() {
let myFormData = new FormData();
myFormData.append('name', this.parkingForm.value.name);
myFormData.append('type', this.parkingForm.value.type);
myFormData.append('city', this.parkingForm.value.city);
return this.http.post(this.url, myFormData,
{ responseType: 'text' }).subscribe(
(response) => this.array.push(response),
(error) => console.log(error)
);
}
ts.file
export class AppComponent implements OnInit {
getTab: any = [];
constructor(private parkingsService: ParkingsService) {}
ngOnInit() {
this.parkingsService.get().subscribe(data => {
this.getTab = data;
})
};
add() {
this.parkingsService.postMethod();
}
}
html
<table>
<tr>
<th>name</th>
<th>type</th>
<th>ville</th>
</tr>
<tr *ngFor="let parking of getTab">
<td>{{parking.name}}</td>
<td>{{parking.type}}</td>
<td>{{parking.city}}</td>
</tr>
</table>
<form [formGroup]="parkingForm">
<div class="form-group">
<input type="text" placeholder="enter name" name="name" formControlName="name"><br>
<input type="text" placeholder="enter type" name="type" formControlName="type"><br>
<input type="text" placeholder="enter city" name="city" formControlName="city"><br>
<button (click)="add()">Ajouter</button>
</div>
</form>
parkingForm: FormGroup;
this.parkingForm = this.formBuilder.group({
name: ['', [Validators.required]],
type: ['', [Validators.required]],
city: ['', [Validators.required]]
});
constructor(private formBuilder: FormBuilder) { }
ngOnInit(){
}
add() {
let bodyJSON={
name:this.parkingForm.get('name').value,
type:this.parkingForm.get('type').value,
city:this.parkingForm.get('city').value
}
this.parkingsService.postMethod(bodyJSON);
}
postMethod(data) {
let myFormData = new FormData();
myFormData.append('name', data.name);
myFormData.append('type', data.type);
myFormData.append('city', data.city);
return this.http.post(this.url, myFormData,
{ responseType: 'text' }).subscribe(
(response) => this.array.push(response),
(error) => console.log(error)
);
}

How do I use data from POST request for the next GET request

I'm trying to build a web app that uses Spotify API now. I want it to send a search keyword that an user submits to the server and send back its search result to the front end. The problem is I get a 404 status code for the fetch call. The POST request works fine.
Main.js
import React, { Component } from "react";
import SingerCard from "./SingerCard";
import axios from "axios";
export class Main extends Component {
constructor(props) {
super(props);
this.state = {
keyword: "",
artists: [],
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
this.setState({ keyword: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
axios
.post(
"http://localhost:4000/search_result",
{
keyword: this.state.keyword,
},
{
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
}
)
.then(function (res) {
console.log(res);
})
.catch(function (err) {
console.log(err);
});
}
componentDidMount() {
fetch("http://localhost:4000/api")
.then((res) => res.json)
.then((artists) => {
this.setState({ artists });
});
}
render() {
return (
<div className="main">
<form onSubmit={this.handleSubmit}>
<label htmlFor="search">Search an artist: </label>
<span>
<input
type="search"
value={this.state.keyword}
onChange={this.handleChange}
name="keyword"
/>
<button type="submit" value="Submit">
Search
</button>
</span>
</form>
<br />
<div className="container">
{this.state.artists.map((elem) => (
<SingerCard
images={elem.images}
name={elem.name}
artists={this.state.artists}
/>
))}
{console.log(this.state.artists)}
</div>
<br />
</div>
);
}
}
export default Main;
server.js
const express = require("express");
const SpotifyWebApi = require("spotify-web-api-node");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const port = 4000 || process.env.PORT;
require("dotenv").config();
app.use(express.json());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
// Create the api object with the credentials
var spotifyApi = new SpotifyWebApi({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
});
// Retrieve an access token.
spotifyApi.clientCredentialsGrant().then(
function (data) {
console.log("The access token expires in " + data.body["expires_in"]);
console.log("The access token is " + data.body["access_token"]);
// Save the access token so that it's used in future calls
spotifyApi.setAccessToken(data.body["access_token"]);
},
function (err) {
console.log("Something went wrong when retrieving an access token", err);
}
);
app.post("/search_result", (req, res) => {
console.log(req.body.keyword);
spotifyApi.searchArtists(req.body.keyword).then(function (data) {
var search_res = data.body.artists.items;
res.json(search_res);
app.get("http://localhost:/api", (req, res) => {
res.json(search_res);
res.end();
});
res.end();
}),
function (err) {
console.log(err);
};
});
app.listen(port, () => console.log(`It's running on port ${port}`));
I think the app.get() in the app.post() causes the error but I can't figure out another way to send the search result back.
You're getting a 404 because the get method is not correctly defined.
Update your server code to define the get method to just keep the pathname, like this:
app.get("/api", (req, res) => {
// ...
}
Currently, you are defining this route inside the app.post. The get route definition should be outside of the post route.
Use Axios.get
import React, { Component } from "react";
// import SingerCard from "./SingerCard";
import axios from "axios";
export class Main extends Component {
constructor(props) {
super(props);
this.state = {
keyword: "",
artists: []
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
this.setState({ keyword: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
const headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
};
axios.post(
"https://jsonplaceholder.typicode.com/users",
{ keyword: this.state.keyword },
{ headers: headers }
)
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err);
});
}
componentDidMount() {
axios.get("https://jsonplaceholder.typicode.com/users").then(res => {
this.setState({
artists: res.data
});
});
}
render() {
return (
<div className="main">
<form onSubmit={this.handleSubmit}>
<label htmlFor="search">Search an artist: </label>
<span>
<input
type="search"
value={this.state.keyword}
onChange={this.handleChange}
name="keyword"
/>
<button type="submit" value="Submit">
Search
</button>
</span>
</form>
<br />
<div className="container">
{this.state.artists.map(elem => (
<div key={elem.id}>
<ul>
<li>{elem.name}</li>
</ul>
</div>
))}
</div>
</div>
);
}
}
export default Main;

Create script for adding question in React.js

I'm making a script to add Q&A in react.js and mongodb. I have a problem when pressing a button creates the following errors
Failed to load resource: the server responded with a status of 404 (Not Found)
create-quest.component.js:40
Object
data: "↵↵↵↵Error↵↵↵Cannot POST /create↵↵↵"
status: 404
statusText: "Not Found"
headers: {access-control-allow-origin: "*", connection: "close", content-length: "146", content-security-policy: "default-src 'none'", content-type: "text/html; charset=utf-8", …}
config: {url: "http://localhost:3000/create", method: "post", data: "{"title":"aaa","content":"aaa"}", headers: {…}, transformRequest: Array(1), …}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
proto: Object
my code is:
import React, { Component } from 'react';
import axios from 'axios';
export default class CreateQuest extends Component {
constructor(props) {
super(props)
this.onChangeTitle = this.onChangeTitle.bind(this);
this.onChangeContent = this.onChangeContent.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
title: '',
content: ''
}
}
onChangeTitle(e) {
this.setState({ title: e.target.value })
}
onChangeContent(e) {
this.setState({ content: e.target.value })
}
onSubmit(e) {
e.preventDefault()
const questionObject = {
title: this.state.title,
content: this.state.content
};
axios.post('http://localhost:3000/create', questionObject)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error.response)
});
this.setState({ title: '', content: '' })
}
render() {
return (
<div className="wrapper">
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Add title</label>
<input type="text" value={this.state.title} onChange={this.onChangeTitle} className="form-control" />
</div>
<div className="form-group">
<label>Add content</label>
<input type="text" value={this.state.content} onChange={this.onChangeContent} className="form-control" />
</div>
<div className="form-group">
<input type="submit" value="Create Question" className="btn btn-success btn-block" />
</div>
</form>
</div>
)
}
}
I am beginner in node react and mongo and I dont understand where is error
this is my routes code
module.exports = (app) => {
const questions = require('../controllers/question.controller.js');
const answers = require('../controllers/answer.controller.js');
// Create a new Note
app.post('/questions', questions.create);
app.post('/questions/:questionId/answers', answers.create);
// Retrieve all Notes
app.get('/questions', questions.findAll);
// Retrieve a single Note with noteId
app.get('/questions/:questionId', questions.findOne);
app.get('/questions/:questionId/answers', questions.findOne); // find answers by question id
// Update a Note with noteId
app.put('/questions/:questionId', questions.update);
// Delete a Note with noteId
app.delete('/questions/:questionId', questions.delete);
}
let mongoose = require('mongoose'),
express = require('express'),
router = express.Router();
let question = require('../models/question.model');
router.route('/create').post((req, res, next) => {
questions.create(req.body, (error, data) => {
if (error) {
return next(error)
} else {
console.log(data)
res.json(data)
}
})
});
router.route('/').get((req, res) => {
questions.find((error, data) => {
if (error) {
return next(error)
} else {
res.json(data)
}
})
})
router.route('/edit/:id').get((req, res) => {
questions.findById(req.params.id, (error, data) => {
if (error) {
return next(error)
} else {
res.json(data)
}
})
})
router.route('/update/:id').put((req, res, next) => {
questions.findByIdAndUpdate(req.params.id, {
$set: req.body
}, (error, data) => {
if (error) {
return next(error);
console.log(error)
} else {
res.json(data)
console.log('Question updated successfully !')
}
})
})
router.route('/delete/:id').delete((req, res, next) => {
questions.findByIdAndRemove(req.params.id, (error, data) => {
if (error) {
return next(error);
} else {
res.status(200).json({
msg: data
})
}
})
})
module.exports = router;
my app.js
import React, { Component } from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import Navbar from './components/Navbar'
import Landing from './components/Landing'
import Login from './components/Login'
import Register from './components/Register'
import Profile from './components/Profile'
import Question from './components/Question'
import Answers from './components/Answer'
import CreateQuest from './components/create-quest.component'
class App extends Component {
render() {
return (
<Router>
<div className="App">
<Navbar />
<Route exact path="/" component={Landing} />
<div className="container">
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profile" component={Profile} />
<Route exact path="/questions" component={Question} />
<Route exact path="/create" component={CreateQuest} />
<Route exact path="/answers" component={Answers} />
</div>
</div>
</Router>
)
}
}
export default App
This is an issue with your backend code, rather than your frontend code. The line Cannot POST /create is the key information here. Look at where you defined your route handlers and, if you're using Express, make sure you have something like app.post('/create', (req, res) => { /** some code here **/ }
Edit:
As you have included some of your code, I'm guessing you either didn't tell your Express to app use the router, or you gave it a mount point that is not the root ('/'), so it's looking for your requests as /<mount point>/create rather than /create. Make sure you have a line in your backend app/server file saying app.use(router) and notice that no mount path was provided, so it will look for requests on /create.
However, in your routes file, you are trying to export both the routes function as well as your router, but you are overwriting the module.exports object, rather than exporting them both. You probably want to change those lines to:
module.exports.routes = (app) => ...
and
module.exports.router = router

How to parse json response using fetch API

Am trying to display json response after calling an API using fetch, I can see the response in the response tab of chrome, but I can't find it in fetch response object
Client side
import React from 'react';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
query: '',
properties: []
}
this.search = this.search.bind(this);
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
const { name, value } = event.target;
// const { query } = this.state.query;
this.setState({
[name]: value
});
}
search() {
console.log('fetching data')
try {
fetch('http://localhost:3000/property/find', {
method: 'POST',
mode: 'CORS',
body: JSON.stringify({ "query": this.state.query }),
headers: {
'Content-Type': 'application/json'
}
}).then(res => res.json())
.then((data) => {
console.log(data)
this.setState({ properties: data.result });
})
}
catch (err) {
return err;
}
}
render() {
const { properties } = this.state;
return (
<div className="App" >
<input type="text" name="query" onChange={this.handleChange}></input>
<div className="form-group">
<button className="btn btn-primary" onClick={this.search}>Search</button>
</div>
<div className="row text-center">
{properties.items &&
properties.items.map((property, index) =>
<div className="col-lg-3 col-md-6 mb-4" key={index}>
<div className="card h-100">
<img className="card-img-top" src="http://placehold.it/500x325" alt="" />
<div className="card-body">
<h4 className="card-title"> {property.details.description}</h4>
{/* <p className="card-text">{property.biography}</p> */}
</div>
<div className="card-footer">
Find Out More!
</div>
</div>
</div>
)
}
</div>
</div>
)
}
}
export default App;
Server side
var app = express();
const server = http.createServer(app);
const io = socketIo(server);
var db = require('./db');
var property = require('./endpoint/property');
// var authController = require('./auth/AuthController');
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3001');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
next();
});
//allow OPTIONS on just one resource
// app.post('*', cors())
app.use(cors())
app.use('/property', property);
End point response
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({ extended: true }));
router.use(bodyParser.json());
var Model = require('../model/propertyModel');
// GETS A SINGLE USER FROM THE DATABASE
router.post('/find',function (req, res) {
var query = req.body.query
console.log(query)
Model.find( { $text: { $search: query }} , { score: { $meta: "textScore" } }).sort( { score: { $meta: "textScore" } } ).then((data)=>{
if(data.length>0){
res.status(200).json({"result":data});
}
if (data.length==0){
Model.find({ "details.description": {$regex:query} }).sort( { score: { $meta: "textScore" } } ).then((data)=>{
if(data){
res.status(200).json({"result":data});
}
if (data.length==0) return res.status(404).send("No properties found.");
})
}
})
});
Inside your render method, if you change this:
{properties.items &&
properties.items.map((property, index) =>
...to this:
{properties &&
properties.map((property, index) =>
That should resolve this for you.
Within the render method, it looks like properties.items is expected to be an array. But in the network tab response screenshot, the result field inside the JSON response is an array.
Calling this.setState({ properties: data.result }); will lead to properties being the field you should be mapping over in the render method, instead of properties.items

Resources