Sending a String from Node Js to a component React Js - node.js

i am using Node Js and React Js to send data from node to a React component but the state never change in the console when i did response.json() i get my string sent but in my component it's empty and there is no data .
Here is my Node js code :
app.post('/try', function(req, res) {
results='hello everybody !'
res.send(JSON.stringify(results));
});
And here's my React component:
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = { results: null };
}
componentDidMount() {
const data = new FormData();
fetch('http://localhost:4000/try',{
method: 'POST',
body : data
})
.then(
(response) => {
console.log(response);
return response.json();
} // if the response is a JSON object
).then(
success =>console.log(success) // Handle the success response object
).catch(
error => null // Handle the error response object
)
.then(results => {
this.setState({ results: results });
console.log(results)
});
}
render() {
return (
<div className="Users">
<h1>results</h1>
<div>this is my result: {this.state.results}</div>
</div>
);
}
}
export default App;

First of all, results is string, you dont have to convert it to string again,
results='hello everybody !'
then, in react you are not using the proper way of thens. Please try the below code.
fetch('http://localhost:4000/try', {
method: 'POST',
body: data
})
.then((response) => {
console.log(response);
response.json().then((result)=>this.setState({ results: results }))
}
.catch(
error => null // Handle the error response object
)

You can't convert the normal string to JSON.
eg.
var result = "hello everybody !"
console.log(JSON.stringify(result)); // ""hello everybody !""
This is not a JSON
Try this way
var result = {"data" :"hello everybody !"}
console.log(JSON.stringify(result)); // "{"data":"hello everybody !"}"

Related

How to get data from the backend that needs authorization using React

I am creating a website using the MERN stack however I don't know how to get data to the frontend that needs authorization from the backend and I tried to console log the problem and it shows me the HTML of my login page even though I am logged in. Any will be appreciated thank you so much.
My backend code:
router.get("/questions", ensureAuthenticated, (req, res) => {
math = Math.floor(Math.random() * 3) + 1;
Security.findOne({
user: req.user.id
}, (err, user) => {
if (err) {
console.log(err);
}
if (math === 1) {
res.send({
question: user.firstQuestion
});
} else if (math === 2) {
res.send({
question: user.secondQuestion
});
} else {
res.send({
question: user.thirdQuestion
});
}
});
});
My Frontend code:
class QuestionForm extends Component {
constructor(props) {
super(props);
this.state = {
data: ''
}
}
componentDidMount() {
axios.get("http://localhost:5000/users/questions")
.then((res) => {
this.setState({
data: res.data
});
}).catch((err) => console.log(err));
}
render() {
return <h1 > {
this.state.data
} < /h1>
}
}
a lot of changes should be made.
you never want to use the port in your Axios request
add to you package.json an proxy attribute
"proxy": "http://localhost:5000"
then you can change your axios get to
axios.get("/users/questions")
best practice when using autorization is to add to axios interceptors
follow this thread :
How can you use axios interceptors?
and also here is an example for using authorization with JWT token
const tokenHandler = axios.create();
tokenHandler.interceptors.request.use(config => {
const token = localStorage.getItem("token");
if (token) {
config.headers["Authorization"] = token;
}
return config;
});
export default tokenHandler;
let's say you create a token on the login page and store it inside your local storage.
now you can import the token handler and your request should look something like this :
import {tokenHandler} from '<TOKEN HANDLER PATH>'
..
..
tokenHandler.get("/users/questions")
.then((res)=>{
this.setState({data:res.data});
}).catch((err)=>console.log(err));

Why I can't get the correct value from api

I have tried to post data in postman and it returns a json object , the methods are working good .
I have a problem to get the value of attribut when the api respond with a json object .
the forma of json like this :
{
"success" : "true"
}
the api method :
router.post("/sickers/user/login/", (req, res) => {
var values = JSON.parse(req.body);
var pass = values.password;
var email = values.email;
//console.log(values);
if (pass !== null || pass !== "") {
try {
con.connect();
con.query("SELECT Password FROM `sickers` WHERE Email='" + email + "'", function(err, rows, field) {
if (err) {
console.log(err);
res.send("an error detected try later");
} else {
try {
if (pass == rows[0].Password) {
//trying to send correct message from here
res.send({ success: "true" });
console.log("yes")
} else {
console.log("no")
res.send({ success: "false" });
}
} catch {
console.log("no")
res.send({ success: "false" });
}
}
});
} catch (e) {
res.send("no data found");
console.log("obj not found");
}
}
con.end();
});
the post method from a react app is :
//submit values
async submithandler(e) {
e.preventDefault();
try{
await fetch('http://localhost:8000/api/sickers/user/login/',{
method:'post',
mode:'no-cors',
headers:{
'Accept':'application/json',
'Content-type': 'application/json'
},
body:JSON.stringify({
password:this.state.password,
email:this.state.email
})
})
.then(response=>{
this.setState({data:response})
alert(data.success);
})
}catch(e){
alert(e)
}
}
the data declaration in state : data:[]
the error is that the data is undefined .
when you do an api call using fetch request, it returns a promise that contains the response and that response is resolved by the first .then(). after resolving this first promise it returns another response and you need to resolve it with another .then()
Please check the working example below:
import React, {Component} from "react";
class FetchExample extends React.Component {
state = {
isLoading: false,
questions: [],
error: null
};
fetchQuestions = () => {
fetch(`https://opentdb.com/api.php?amount=10&difficulty=hard&type=boolean`,)
.then(response => {
if (response.status !== 200) {
console.log('There was a problem. Status Code: ' + response.status);
return;
}
response.json().then(data => {
console.log(data);
this.setState({
questions: data,
isLoading: false
})
});
}
)
.catch(function (error) {
console.log('Error: ', error);
this.setState({error, isLoading: false})
});
};
render() {
const {isLoading, questions, error} = this.state;
return (
<React.Fragment>
<h1>Random Question</h1>
<button onClick={this.fetchQuestions}>Click for calling API using fetch</button>
{error ? <p>{error.message}</p> : null}
{!isLoading && questions.results ? (
questions.results.map((questions, index) => { //something right here
//is erroring
const {question, category, type, difficulty} = questions;
return (
<div key={index}>
<p>Question: {question}</p>
<p>Question Type: {type}</p>
<p>Difficulty: {difficulty}</p>
<hr/>
</div>
);
})
) : isLoading ? (
<h3>Loading...</h3>
) : null}
</React.Fragment>
);
}
}
export default FetchExample;
there is two problems here at this example with both parts api and react app ,
the first thing I did is to understand cors and how it works in express and I found that I should do the following steps to the api :
run
npm install cors
second is to add
const cors =require('cors')
and then :
app.use(cors());
and last step is inside the router post I should add cors :
router.post('path',cors(),(req,res)....
about react app code it just need to remove module="no-cors"
and then it works .

How to receive JSON Object from node and display it on client side in react?

I am sending a json object using res.json. On the client side I am trying to set the json object to a piece of state.
Ive tried to .json() the response but that still does not let me assign it.
This is the server side sending the JSON File
app.get('/api/getPlace', async (req, res) => {
const response = await client.search({
searchType: "Coffee",
location: "San Francisco, CA",
})
const foodPlace = response.jsonBody.businesses[9];
console.log(foodPlace);
res.json(foodPlace)
})
Below is the whole component file to render the json object
import React, { Component } from 'react';
import axios from 'axios';
class RandomPlace extends Component {
constructor(props) {
super(props);
this.state = {
response: {},
};
}
async componentDidMount() {
const res = axios.get('/api/getPlace');
this.setState({ response: res.data })
}
render() {
return (
<div>
{this.state.response}
</div>
);
}
}
export default RandomPlace;
The client call must be awaited:
async componentDidMount() {
const res = await axios.get('/api/getPlace');
this.setState({ response: res.data })
}
import React, { Component } from 'react';
import axios from 'axios';
class RandomPlace extends Component {
constructor(props) {
super(props);
this.state = {
response: {},
};
}
async componentDidMount() {
const res = await axios.get('/api/getPlace');
this.setState({ response: res.data })
}
render() {
return (
<div>
{this.state.response}
</div>
);
}
}
export default RandomPlace;
REST api calls are asynchronous, which means the code proceeds to the next statement without waiting for the api call to compelete. When await is adding before the call, the execution will pause till the call completes or timesout (if specified) before proceeding to the next line. async/await is a better alternative to promises.

React: Data won't be saved to this.state

So I am trying to send a get request to my node server which is responding by sending a list of objects that I wish to display on my page.
Tried many different methods, but I cant seem to find a solution. Also I am rendering via the server if that's any help.
Client Code:
class BookTools extends React.Component {
constructor(props) {
super(props);
this.state = {
books: []
};
this.handleAdd = this.handleAdd.bind(this);
this.handleEdit = this.handleEdit.bind(this);
this.handleDelete = this.handleDelete.bind(this);
this.updateList = this.updateList.bind(this);
fetch('/getbooks').then(function (res) {
return res.json();
}).then(function (json) {
console.log(json);
const data = JSON.stringify(json);
console.log(data);
this.setState({ books: data})
});
}
Can't use componentDidMount since it's SSR and can't seem to get componentWillMount to work either, so i tried doing it in the constructor as suggested by another. both console.logs prints out the correct response.
I have also tried doing both this.setState({ books: json.body }) and this.setState({ books: json.data }) with no other result. And yes i am quite new to react as well as node/express
Thanks for any help :)
It’s common issue in react. When you use regular function this context won’t be available so either you need to bind it or change it to arrow function.
Also make sure the API returns data
Change
fetch('/getbooks').then(function (res) {
return res.json();
}).then(function (json) {
console.log(json);
const data = JSON.stringify(json);
console.log(data);
this.setState({ books: data})
});
To
fetch('/getbooks')
.then(res => res.json())
.then(json => {
console.log(json);
const data = JSON.stringify(json);
console.log(data);
this.setState({ books: data})
});
Or
fetch('/getbooks')
.then(function (res) {
return res.json();
}.bind(this))
.then(function (json) {
console.log(json);
const data = JSON.stringify(json);
console.log(data);
this.setState({ books: data})
}.bind(this));

Call server-side function from ReactJS component

I'm trying to implement a payments system in my ReactJS app that requires server-side code.
I have several questions:
How do you connect a ReactJS app so it can communicate with server-side code?
How would you set up a function in the server-side code?
How would you call that function from a component in a ReactJS app?
For reference, I'm trying to integrate Stripe subscriptions. They give server-side code examples for Node, PHP, etc.
FYI: I am not trying to set up server-side rendering. When you search for server-side code in reference to ReactJS, that's just about all that comes up.
EDIT: I'm particularly interested in a NodeJS solution. I'm also using Webpack.
Just in case, it is helpful to you... I have a React UI that triggers video processing on a Django backend (I mainly use GraphQL through Apollo Client to trigger my server side functions and REST framework when file transfers are involved).
Is REST an option for you?
The middleware I use for file transfers for example:
const SERVER_URL = process.env.SERVER_URL;
const fileTransferApi = (payload) => {
const { authenticated, token, endpoint, body, contentType, method } = payload;
let config = {};
if (authenticated) {
if (token) {
config = {
method,
headers: {
'Content-Type': contentType,
Authorization: `Bearer ${token}`
},
body
};
} else {
throw new Error('No token saved!');
}
}
return fetch(`${SERVER_URL}/api/rest/v1/${endpoint}`, config)
.then((response) =>
response.text().then((text) => ({ text, response }))
).then(({ text, response }) => {
if (!response.ok) {
return Promise.reject(text);
}
return text;
}).catch((err) => console.log(err));
};
export const FILE_TRANSFER_API = Symbol('FILE_TRANSFER_API');
export default () => (next) => (action) => {
const fileTransferApiAction = action[FILE_TRANSFER_API];
if (typeof fileTransferApiAction === 'undefined') {
return next(action);
}
const { payload, types } = fileTransferApiAction;
const [, successType, errorType] = types;
return fileTransferApi(payload).then(
(response) =>
next({
type: successType,
payload: {
text: response,
message: 'ok'
}
}),
(error) => next({
type: errorType,
payload: {
error: error.message || 'There was an error.'
}
})
);
};
My store (I use Redux):
import { createStore, compose, applyMiddleware } from 'redux';
import { routerMiddleware } from 'react-router-redux';
import ReduxThunk from 'redux-thunk';
import ApolloClientSingleton from '../network/apollo-client-singleton';
import fileTransferApi from '../middlewares/fileTransferApi';
import reducer from './reducers';
export default class Store {
constructor(history, initialState = {}) {
this.data = createStore(
reducer,
initialState,
compose(
applyMiddleware(
fileTransferApi,
ReduxThunk.withExtraArgument(ApolloClientSingleton),
routerMiddleware(history),
ApolloClientSingleton.middleware()
),
typeof window === 'object' && typeof window.devToolsExtension !== 'undefined'
? window.devToolsExtension() : (f) => f
)
);
}
}
In my actions:
export const windowsDownload = (authenticated, token) => ({
[FILE_TRANSFER_API]: {
types: [WINDOW_DOWNLOAD_REQUEST, WINDOW_DOWNLOAD_SUCCESS, WINDOW_DOWNLOAD_FAILURE],
payload: {
endpoint: 'file_transfer/download/windows',
contentType: 'text/csv',
method: 'get',
body: null,
authenticated,
token
}
}
});
This REST setup enables me to send requests (POST video, GET csv...) from my React UI to my Django server. Can't you set up some REST calls between your app and your server?

Resources