Issue fetching data with react - reactjs

I have a rare issue fetching data on a useEffect hook....It gives me "CORS error" on chrome inspector... here is my code:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import './HomeScreen.css'
import config from '../config'
// Compomnents
import Quiz from "../components/Quiz";
const HomeScreen = () => {
const [data, setData] = useState({ quizzes: [] });
const [loading, setLoading] = useState('true');
const [error, setError] = useState(false);
console.log("TESTING...............................");
useEffect(() => {
setLoading('testing');
const url = "https://mocki.io/v1/4a0ad1a9-352a-45bb-84b9-67e6363d6b7a"; //config.prodLocalhostURLRestAPI + 'quizzes';
fetch(url)
.then(res => res.json())
.then(res => {
setLoading('result..........')
})
.catch(error => {
//console.log(error);
});
}, []);
return (
<div className="homescreen">
<h2 className="homescreen__title">Quizzes</h2>
<div className="homescreen__quizzes">
<h2>{loading}</h2>
{loading ? <h2>Loading............</h2> : error ? <h2>ERROR</h2> : data.quizzes.map(quiz => (
<Quiz />
))}
</div>
</div>
)
}
export default HomeScreen;
The server code is:
var express = require("express"),
app = express(),
http = require("http"),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
server = http.createServer(app),
mongoose = require("mongoose");
const port = process.env.OPENSHIFT_NODEJS_PORT || 3011;
app.set('port', port);
app.set('ipaddr', process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1");
app.use(bodyParser.json());
app.use(methodOverride());
//Import routes
const chatsRoutes = require('./routes/quizzes');
app.use('/quizzes/', chatsRoutes);
app.get('/', (req, res) => {
res.send("Ready!");
});
/** catch 404 and forward to error handler */
app.use('*', (req, res) => {
return res.status(404).json({
success: false,
message: 'API endpoint doesnt exist'
})
});
//app.use('/', routesRaids);
mongoose.connect('mongodb://localhost/quizes', {useNewUrlParser: true, useUnifiedTopology: true }, () =>
console.log('Connected to Mongo DB')
);
app.listen(port);
The URL is correct and works directly on the browser.
What's the issue?

First hit npm install cors , then
var express = require("express"),
app = express(),
http = require("http"),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
server = http.createServer(app),
mongoose = require("mongoose");
const cors = require('cors');
const port = process.env.OPENSHIFT_NODEJS_PORT || 3011;
app.use(cors())
app.set('port', port);
app.set('ipaddr', process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1");
app.use(bodyParser.json());
app.use(methodOverride());
//Import routes
const chatsRoutes = require('./routes/quizzes');
app.use('/quizzes/', chatsRoutes);
app.get('/', (req, res) => {
res.send("Ready!");
});
/** catch 404 and forward to error handler */
app.use('*', (req, res) => {
return res.status(404).json({
success: false,
message: 'API endpoint doesnt exist'
})
});
//app.use('/', routesRaids);
mongoose.connect('mongodb://localhost/quizes', {useNewUrlParser: true, useUnifiedTopology: true }, () =>
console.log('Connected to Mongo DB')
);
app.listen(port);

Related

React function doesn't work when placed inside another function

In the frontend I've made 2 buttons, one to create the data from a form and another the GET and display it onto the frontend, this is all being sent and received from an API and it works just fine when I use two separate buttons. What I want to do is combine the two to function only when the create button is clicked; I've tried putting the getData function into the createData function but it never works and I keep on getting errors.
How can I fix this?
Frontend.js
import React, { useState, useRef, useEffect } from 'react';
import axios from 'axios'
import './App.css';
function App() {
const cardHolderRef = useRef("");
const balanceRef = useRef("");
const [cardHolder, setCardHolder] = useState("");
const [cardNumber, setCardNumber] = useState("");
const [balance, setBalance] = useState("");
const [expDate, setExpDate] = useState("");
const [cvc, setCvc] = useState("");
async function getCardData() {
await axios.get("http://localhost:5000/", { crossdomain: true })
.then(response => {
setCardHolder(response.data.data.name_on_card);
setCardNumber(response.data.data.card_pan);
setBalance(response.data.data.amount + " " + response.data.data.currency);
setExpDate(response.data.data.expiration);
setCvc(response.data.data.cvv);
})
};
async function createCardData(e) {
e.preventDefault();
await axios.post("http://localhost:5000/", {
cardHolder: cardHolderRef.current.value,
balance: balanceRef.current.value
})
getCardData();// This isn't working at all
};
return (
<div>
<div className='vcard'>
<div className='theBalance'>
<h2>{balance}</h2>
</div>
<div className='numNcvc'>
<h2 className='theNum'>{cardNumber}</h2>
<h2 className='theCvc'>{cvc}</h2>
</div>
<div className='expNholder'>
<h2>Expiry Date<br/> {expDate}</h2>
<h2>Card Holder<br/> {cardHolder}</h2>
</div>
</div>
<div className='details-div'>
<form className='details'>
<input
placeholder='Name on Card'
type="text"
id='cardholder'
name='cardholder'
ref={cardHolderRef}></input>
<input
placeholder='Amount (in USD)'
type="text"
id="cardbalance"
name="cardbalance"
ref={balanceRef}></input>
<input placeholder='MTN MoMo Number' type="text"></input>
</form>
<button className='createCardBtn' onClick={createCardData}>
Create Card
</button>
<button className='createCardBtn' onClick={getCardData}>
Get Card Data
</button>
</div>
</div>
);
}
export default App;
Backend.js
const { response } = require('express');
const express = require('express');
const cors = require('cors');
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const jsonParser = bodyParser.json();
const Flutterwave = require('flutterwave-node-v3');
const flw = new Flutterwave("FLWPUBK_TEST-63a79c5a6fe457d75a611b0f376e3e53-X", "FLWSECK_TEST-a6281194ef4ca095e794a1681fe32d69-X");
app.use(bodyParser.json());
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();
});
app.post("/", jsonParser, async (req, res) => {
const cardHolder = req.body.cardHolder;
const balance = req.body.balance;
console.log(cardHolder);
console.log(balance);
// Payload: Flutterwave Card Details
const payload = {
"currency": "USD",
"amount": balance,
"billing_name": cardHolder,
"billing_address": "2014 Forest Hills Drive",
"billing_city": "React",
"billing_state": "NY",
"billing_postal_code": "000009",
"billing_country": "US",
}
const createCardResponse = await flw.VirtualCard.create(payload);
const newPayload = {
"id": createCardResponse.data.id
}
const fetchResponse = await flw.VirtualCard.fetch(newPayload);
console.log(fetchResponse);
app.get('/', async (req, res) => {
res.send(fetchResponse);
})
});
app.use(bodyParser.json());
app.listen(5000, () => {console.log("Server started on port 5000")})
//createVcard();
In the api response, you added the app.get method inside the app.post, and you aren't returning any data.
You need to move the app.get outside the app.post and in the app.post return your data like this:
app.get('/', async (req, res) => {
...
}
app.post("/", jsonParser, async (req, res) => {
const cardHolder = req.body.cardHolder;
....
const fetchResponse = await flw.VirtualCard.fetch(newPayload);
res.send(fetchResponse);
});

How to resolve the Socket.io error "ERR_NAME_NOT_RESOLVED

When I run my MERN Stack project on my localhost and get my app's render page, when I click on a button in my app, that button does and displays nothing. When I inspect my client-side render page, I see the following error:polling.js:311 GET http://%22http/socket.io/?EIO=4&transport=polling&t=O7Mtvxd net::ERR_NAME_NOT_RESOLVED. I don't know what it means, I searched the meaning on the internet but without success. Here is my backend index.js file:
const express = require('express')
const cors = require('cors')
const mongoose = require('mongoose')
require("dotenv").config()
const app = express()
const http = require('http')
const server = http.createServer(app)
const io = require('socket.io')(server)
const UserRoutes = require('./routes/User')
const AuthRoutes = require('./routes/Auth')
const PostRoutes = require('./routes/Post')
const PORT = process.env.PORT || 5000
const {MONGODB_URI} = require("./config")
app.use(cors())
app.use(express.json())
app.use((req, res, next) => {
io.req = req
req.io = io
next()
})
app.use('/api/auth', AuthRoutes)
app.use('/api/user', UserRoutes)
app.use('/api/post', PostRoutes)
require('./socket')(io)
mongoose
.connect(MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then(() => {
console.log('database connected')
server.listen(PORT, () => console.log(`server started on port ${PORT}`))
})
.catch((err) => console.log(err))
my backend socket.js file :
const User = require('./models/User')
const jwt = require('jsonwebtoken')
module.exports = (io) => {
io.on('connection', (socket) => {
if (io.req) {
socket.broadcast.emit('friend-login-status', { user_id: io.req.userId })
addSocketIdInDB(socket.id, io.req.userId)
socket.on('disconnect', () => {
socket.broadcast.emit('friend-logout-status', {
user_id: io.req.userId,
})
io.req.userId = null
})
}
})
}
async function addSocketIdInDB(socket_id, user_id) {
const user = await User.findById(user_id)
if (socket_id) {
user.socketId = socket_id
}
await user.save()
}
I looked on this question after this but without success. I work on Microsoft Edge .

change code from template engine to next js

How do I convert my app that is made with .pug to next app ? I have an app using .pug engine and I want to convert it into next.
This is the app.js but as I know next is different how do I do it? Because here my files are in views, and in views the files are in pages etc how do I do it? Is there any way or I have to code it all again?
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const middleware = require('./middleware')
const path = require('path')
const bodyParser = require("body-parser")
const mongoose = require("./database");
const session = require("express-session");
const http = require('http');
const server = app.listen(port, () => console.log("Server listening on port " + port));
const io = require("socket.io")(server, { pingTimeout: 60000 });
app.set("view engine", "pug");
app.set("views", "views");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "public")));
app.use(session({
secret: "#########",
resave: true,
saveUninitialized: false
}))
// Routes
const loginRoute = require('./routes/loginRoutes');
const registerRoute = require('./routes/registerRoutes');
const logoutRoute = require('./routes/logout');
const postRoute = require('./routes/postRoutes');
const profileRoute = require('./routes/profileRoutes');
const uploadRoute = require('./routes/uploadRoutes');
const searchRoute = require('./routes/searchRoutes');
const messagesRoute = require('./routes/messagesRoutes');
const notificationsRoute = require('./routes/notificationRoutes');
// Api routes
const postsApiRoute = require('./routes/api/posts');
const usersApiRoute = require('./routes/api/users');
const chatsApiRoute = require('./routes/api/chats');
const messagesApiRoute = require('./routes/api/messages');
const notificationsApiRoute = require('./routes/api/notifications');
app.use("/login", loginRoute);
app.use("/register", registerRoute);
app.use("/logout", logoutRoute);
app.use("/posts", middleware.requireLogin, postRoute);
app.use("/profile", middleware.requireLogin, profileRoute);
app.use("/uploads", uploadRoute);
app.use("/search", middleware.requireLogin, searchRoute);
app.use("/messages", middleware.requireLogin, messagesRoute);
app.use("/notifications", middleware.requireLogin, notificationsRoute);
app.use("/api/posts", postsApiRoute);
app.use("/api/users", usersApiRoute);
app.use("/api/chats", chatsApiRoute);
app.use("/api/messages", messagesApiRoute);
app.use("/api/notifications", notificationsApiRoute);
app.get("/", middleware.requireLogin, (req, res, next) => {
var payload = {
pageTitle: "Home",
userLoggedIn: req.session.user,
userLoggedInJs: JSON.stringify(req.session.user),
}
res.status(200).render("home", payload);
})
io.on("connection", socket => {
socket.on("setup", userData => {
socket.join(userData._id);
socket.emit("connected");
})
socket.on("join room", room => socket.join(room));
socket.on("typing", room => socket.in(room).emit("typing"));
socket.on("stop typing", room => socket.in(room).emit("stop typing"));
socket.on("notification received", room => socket.in(room).emit("notification received"));
socket.on("new message", newMessage => {
var chat = newMessage.chat;
if(!chat.users) return console.log("Chat.users not defined");
chat.users.forEach(user => {
if(user._id == newMessage.sender._id) return;
socket.in(user._id).emit("message received", newMessage);
})
});
})
If you don't want to refactor all your pug template engine pages to next.js pages, then you can make the pug pages coexist with the next.js. You can make the next.js the default route, and place next.js code after all pug page routes. And you also need to refactor app.get("/", middleware.requireLogin, (req, res, next) => {...} to make sure next.js is the default route.
To apply this rule, you need a custom next.js server.
sample code
const express = require('express');
const next = require('next');
const port = 3000;
const dev = process.env.NODE_ENV !== 'production'; // use default NodeJS environment variable to figure out dev mode
const app = next({dev, conf});
const handle = app.getRequestHandler();
const server = express();
// all your pug page routes should be declared before `server.get('*'`.
server.get('*', authMiddleware(false), (req, res) => {
// pass through everything to NextJS
return handle(req, res);
});
app.prepare().then(() => {
server.listen(port, (err) => {
if (err) throw err;
console.log('NextJS is ready on http://localhost:' + port);
});
}).catch(e => {
console.error(e.stack);
process.exit(1);
});

Error wooCommerce REST API : woocommerce_rest_cannot_view

I have some difficulties accessing my wooCommerce API with react and nextjs.
I always have this message : woocommerce_rest_cannot_view
I tried the response I've seen on other thread on stackoverflow, but nothing worked for me.
Here my server.js
const next = require('next');
const express = require('express');
const wooConfig = require( './wooConfig' );
const WooCommerceAPI = require('woocommerce-api');
// import WooCommerceRestApi from "#woocommerce/woocommerce-rest-api"; // Supports ESM
const WooCommerce = new WooCommerceAPI({
url: wooConfig.siteUrl,
consumerKey: wooConfig.consumerKey,
consumerSecret: wooConfig.consumerSecret,
wpAPI: true,
version: 'wc/v1',
query_string_auth: true
});
const port = 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare()
.then(() => {
const server = express();
server.get('/getProducts', (req, response) => {
WooCommerce.get('products', function (err, data, res) {
response.json(JSON.parse(res));
});
})
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(port, err => {
if (err) {
throw err;
}
console.log(`Ready on port ${port}`)
})
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
});;
I found the solution :
This is
queryStringAuth: true
instead of
query_string_auth: true

ReactJs, Express and Axios, send request to server then respond to client

I have a question how to send "params" value to express server. The respond from server to client will not be a big problem because I done the respond. I have problem with sending data to server.
this is my server.js file
const express = require('express');
const axios = require('axios');
const app = express();
const port = process.env.PORT || 5000;
const cors = require('cors');
var bodyParser = require('body-parser')
var urlencodedParser = bodyParser.urlencoded({ extended: false })
app.get('/category', (req, res) => {
axios.get(`https://newsapi.org/v2/${params}&language=pl&sortBy=publishedAt&apiKey=API`)
.then(response =>{
let articles = [];
response.data.articles.map((article) =>{
articles.push(article);
})
res.send({ articles});
});
})
app.listen(port, () => console.log(`Listening on port ${port}`));
and here is my app.js
//make api request
setApiKey = params => {
this.setState(
{
apiKey: api,
},
this.makeApiRequest,
);
return api;
}
//set state after request
makeApiRequest = () =>{
axios.get('/category')
.then(response => {
this.setState({articles: response.data.articles});
})
}
//set new api on input chnage
switchOnInputChange=(event)=>{
if(event.target.value.length >3) {
let params = `everything?q=${event.target.value}`
this.setApiKey(params);
this.setState({headerText: "Popularne"},
this.makeApiRequest,
)
}
if (event.target.value.length < 3){
this.setState({
apiKey: apiTop,
headerText: "Popularne"
},
this.makeApiRequest,);
}
}
scrollOnBtnClick = () =>{
this.smoothScrollTo(0, window.outerHeight, 1500);
this.toggleNav();
}
//change api on click
switchCatOnClick = (event) =>{
let text = event.target.innerText;
let params = `top-headlines?country=us&category=${event.target.getAttribute("switch")}`
this.setApiKey(params);
this.smoothScrollTo(0, window.outerHeight, 1500);
this.setText(text);
}
as You can see I want to pass params which are created on click or input change.
Working solution:
server.js
app.get('/category', (req, res) => {
axios.get(`https://newsapi.org/v2/${req.query.path}?country=${req.query.country}&category=${req.query.category}&apiKey=API_KEY`)
.then(response =>{
let articles = [];
response.data.articles.map((article) =>{
articles.push(article);
})
res.send({ articles});
});
})
app.js
switchCatOnClick = (event) =>{
let text = event.target.innerText;
let params = `path=top-headlines&country=pl&category=${event.target.getAttribute("switch")}`
this.callApi(`/category?${params}`)
.then(response => {
this.setState({
articles: response.articles
});
});
this.smoothScrollTo(0, window.outerHeight, 1500);
this.setText(text);
this.scrollOnBtnClick();
this.toggleNav
}

Resources