fetch JSON array from node to Reactjs - json

I'm trying to fetch an array on my node server on localhost:3000/users to my react app on localhost:3000.
The problem is I don't getting an array on react and cannot fetch anything to my list.
var express = require('express');
var router = express.Router();
var arr = [{
id: 1,
username: "samsepi0l"
}, {
id: 2,
username: "D0loresH4ze"
}];
/* GET users listing. */
router.get('/', function(req, res, next) {
// Comment out this line:
//res.send('respond with a resource');
// And insert something like this instead:
res.json(arr);
});
module.exports = router;
And the react App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
state = {users: []}
componentDidMount() {
fetch("/users")
.then( (res) => res.json())
.then( (json) => {this.setState({users: json});});
}
render() {
return (
<div className="App">
<h1>Users</h1>
{this.state.users.map(user =>
<div key={user.id}>{user.username}</div>
)}
</div>
);
}
}
export default App;
How can I fetch the array to react page?
and here is the error that I got when I run the npm server:
Unhandled Rejection (SyntaxError): Unexpected token < in JSON at position 0

You should implement the endpoint for the fetch("/users") call
router.get('/users', function(req, res, next) {
console.log('got the response');
res.json(arr);
});
Also, you need to separate your front end react app from your server express which handles the request.
You cannot have the same port which your apps are listening. Set up different port. I.E 8000 for the front end and 8080 for the express server
UPDATE
I've managed to reproduced the tutorial which i think is the same you have found based from here : https://medium.com/front-end-hacking/calling-express-api-in-react-using-react-script-e19084a76a8a
There is nothing wrong with the tutorial. You have to set up the proxy part in the client/package-json
"proxy" : "http://localhost:3005"
and in the bin/www you have to set the line from
var port = normalizePort(process.env.PORT || '3000');
to
var port = normalizePort(process.env.PORT || '3005');
finally you may need to install the concurrently dependency in the server package.json
finally i have attached the tree structure of the tutorial

Related

How can I retrieve data from mysql upon clicking on a button by react-native

I'm currently having an error on my code on retrieving MySQL data upon clicking a button.
Here is my 'route.js'.
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const connection = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password!',
database: 'mydb'
});
// Starting our app.
const app = express();
// Creating a GET route that returns data from the 'users' table.
app.get('/user', function (req, res) {
// Connecting to the database.
connection.getConnection(function (err, connection) {
// Executing the MySQL query (select all data from the 'users' table).
connection.query('SELECT * FROM user', function (error, results, fields) {
// If some error occurs, we throw an error.
if (error) throw error;
// Getting the 'response' from the database and sending it to our route. This is were the data is.
res.send(results)
});
});
});
// Starting our server.
app.listen(3000, () => {
console.log('Go to http://localhost:3000/user so you can see the data.');
});
async function test(){
await fetch('http://mylocalpcIP:3000/user',{
method: 'POST', // Here you're saying that you want to make a POST request. Could be any method, like a GET, for example.
headers: '', // You can specify your requisition headers here. That line is optional.
body: { // Here's the fun part. Put your data here.
"name": this.state.name,
"age": this.state.age,
"phone_number": this.state.phone_number
}
})
.then(response => response.json())
.then(user => console.warn(user))
};
export {test};
Then, I've called test function as such:
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import {test} from "./db/routes.js";
const MyScreen = ( {navigation} ) => {
return (
<View style={styles.container2}>
<TouchableOpacity
style = {[styles.mid_box, styles.pbox]}
onPress={() =>{
test();
navigation.navigate("Dating_to_Profiles")
}}>
<View>
<Text style = {styles.textstyle}>1st Introduced Profile</Text>
</View>
</TouchableOpacity>
And I'm getting this scary message when I reload the emulated Android.
Well.. It's very likely that I've messed up somewhere since I don't know much about anything yet.
I'd appreciate a lot if someone can teach me how to retrieve data via POST method.
Thanks a lot in advance!
Express is a NodeJS framework and thus obviously not compatible with react-native.
If you wanted to create an API where your data that was queried from MYSQL is served as JSON so it can be fetched by your app, I recommend this tutorial for you.

How do 'no code' websites publish webpages for each user? [duplicate]

I am used to working on httpd ( Apache ) which provides a way to configure subdomains which is mapped to a directory.
How can I do the same thing in Connect.js/Express.js ? I see that the only thing that I have is routes which I am not sure how I can use to configure sub domains. I have subdomains like m.mysite.com, sync.mysite.com
Can someone help ?
Or alternatively you could use vhost.
Then, create several sites in their own directory and export the express app, eg. /path/to/m/index.js:
var app = express()
/* whatever configuration code */
exports.app = app
// There is no need for .listen()
And then handle all requests with the following app:
var vhost = require('vhost');
express()
.use(vhost('m.mysite.com', require('/path/to/m').app))
.use(vhost('sync.mysite.com', require('/path/to/sync').app))
.listen(80)
Note that /path/to/m and /path/to/sync can be absolute paths (as written above) or relative paths.
You could append a subdomain to a request and then check for it in subsequent next() calls.
I got the following code from > http://groups.google.com/group/express-js/browse_thread/thread/b04bbaea7f0e8eed (so full credit to the original author)
app.get('*', function(req, res, next){
if(req.headers.host == 'some.sub.domain.com') //if it's a sub-domain
req.url = '/mysubdomain' + req.url; //append some text yourself
next();
});
// This will mean that all get requests that come from the subdomain will get
// /subdomain appended to them, so then you can have routes like this
app.get('/blogposts', function(){
// for non-subdomain
});
app.get('/mysubdomain/blogposts', function(){
// for subdomain
});
I have recently came across this problem, and wrote a module to help with it using express 4. https://www.npmjs.org/package/express-subdomain.
Example - api subdomain.
var express = require('express');
var app = express();
var router = express.Router();
//api specific routes
router.get('/', function(req, res) {
res.send('Welcome to our API!');
});
router.get('/users', function(req, res) {
res.json([
{ name: "Brian" }
]);
});
app.use(subdomain('api', router));
app.listen(3000);
Check out the module on npm to see more examples.
I created a module to help with subdomains in Express: https://github.com/WilsonPage/express-subdomain-handler
Do as I say, create two express app in different folder.
For example:
one app in /blogsite directory
const express = require("express");
const blog = express();
blog.get("/", (req, res) => {
res.send("BLOG SECTION");
});
blog.get("/allblogs", (req, res) => {
res.json([
{ title: "csgo major boston", description: "Best CSGO major ever" },
{ title: "Blast pro series", description: "Coolest series of CSGO" },
]);
});
module.exports = { blog };
and another one in /portfolio directory
const express = require("express");
const portfolio = express();
portfolio.get("/", (req, res) => {
res.send("PORTFOLIO SECTION");
});
portfolio.get("/resume", (req, res) => {
res.send("HERE'S MY RESUME");
});
module.exports = { portfolio };
Now create a main app in the outer folder and import the other two express apps that you just made in /blogsite directory and /portfolio directory.
And in the main app do this,
const express = require("express");
const vhost = require("vhost");
const { blog } = require("./blogsite");
const { portfolio } = require("./portfolio");
const app = express();
// BLOG AND PORTFOLIO
// url: http://blog.localhost:3002/
// url: http://blog.localhost:3002/allblogs
// url: http://portfolio.localhost:3002/
// url: http://portfolio.localhost:3002/resume
app
.use(vhost("portfolio.localhost", portfolio))
.use(vhost("blog.localhost", blog));
// MAIN APP ROUTES OR ENDPOINTS
// url: http://localhost:3002
// url: http://localhost:3002/myhobbies
app.get("/", (req, res) => {
res.send("MAIN APP SECTION");
});
app.get("/myhobbies", (req, res) => {
res.send("MAIN APP -> myhobbies section");
});
app.listen(3002, () => {
console.log("started listening");
});
fileStructure at the end should be looking like this
main(folder)
index.js (main express app which you need to run using node or nodemon)
blogsite(folder that I talked about for blog.localhost)
index.js (blog express app)
portfolio(folder)
index.js (portfolio express app)
I've had this exact same requirement for a project I was working on and ended up throwing together a middleware-based solution. It allows you to define routers and view folders per subdomains.
Check it out on NPM https://www.npmjs.com/package/express-multiview
or GitHub https://github.com/daryl-cecile/express-multi-view#readme

How to integrate React Native with mySQL

I'm new in React Native and I'm trying to integrate my app with mySQL database located inside my hosting provider (digitalocean.com).
I've managed to get the data through nodejs and express but it's actually getting the data where my problem is.
Here how it goes:
I created a routes.js and inserted the following:
Note: the following credentials are real but is for pure testing and i don't mind sharing.
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const connection = mysql.createConnection({
host: '134.122.22.176',
user: 'yannb_9',
password: 'yannb_9',
database: 'tiomanGrow'
});
// Starting our app.
const app = express();
connection.connect((err) => {
if (err) {
console.log('Connection error message: ' + err.message);
return;
}
console.log('Connected!')
// Creating a GET route that returns data from the 'users' table.
app.get('/', function (req, res) {
// Connecting to the database.
// Executing the MySQL query (select all data from the 'users' table).
connection.query('SELECT * FROM farmers', function (error, results, fields) {
// If some error occurs, we throw an error.
if (error) throw error;
// Getting the 'response' from the database and sending it to our route. This is were the data is.
res.send(results)
});
});
});
// Starting our server.
app.listen(3000, () => {
console.log('Go to http://localhost:3000/farmers so you can see the data.');
});
Up until now everything's great! you can click on the http://localhost:3000/farmers and you'll see the data when you run the file.
Here's where I get stuck:
I was to display the data on my app and i have no idea how to possibly do that.
I did a few researches and saw a possible solution which didn't work. it actually gave me a "Network request failed"
import React from "react";
import { View, Text, StyleSheet, TextInput, TouchableOpacity } from "react-native";
import { HeaderImg } from '../components/HeaderImg';
import { Button } from '../components/Button';
export default class DB extends React.Component {
state = {
email: "",
password: "",
errorMessage: null
};
fetchData = async() => {
fetch('http://134.122.22.176:3000/farmers')
.then(response => response.json())
.then(users => console.dir(users))
.catch(error=> console.log(error))
}
render() {
return (
<View style={styles.container}>
<HeaderImg />
<View style={styles.errorMessage}>
{this.state.errorMessage && (
<Text style={styles.error}>{this.state.errorMessage}</Text>
)}
</View>
<Button
onPress={this.fetchData}
/>
</View>
);
}
}
const styles = StyleSheet.create({
});
Any suggestions?
The hostname for your MySQL database in your routes.js file is shown as 134.122.22.176. That's the database ip address. You cannot fetch from this IP address. MySQL databases do not respond to standard HTTP requests; they are not web servers.
Your Express app is running on localhost: http://localhost:3000/farmers - I am guessing you can surf to that URL in a web browser and see data, for example. If that Express app is running on your development computer, then you just need to find out the IP address (xx.xx.xx.xx) for that computer on your LAN, and use that in your fetch.
Starting from Android 9, google has decided to remove http client library from bootclasspath.
With Android 6.0, we removed support for the Apache HTTP client. Beginning with Android 9, that library is removed from the bootclasspath and is not available to apps by default.
For brief overview of the changes, visit.
In order to connect with http client, you have to add this line in your AndroidManifest.xml file:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
After that you should be able to connect with HTTP clients with your android Pie device.

Error handler ignored when NODE_ENV=production

I am building a simple REST API with Node/Express, and I'm having a hard time when I deploy it to production. When NODE_ENV=development, everything works as expected. I get back the JSON error and the correct status code. When NODE_ENV=production, I only get back an HTML page with the default error message and nothing else. I can read the status code, but I need to have access to the full JSON payload to identify the errors better. This is my code:
import Promise from 'bluebird'; // eslint-disable-line no-unused-vars
import express from 'express';
import config from './config';
import routes from './routes';
import { errorMiddleware, notFoundMiddleware } from './middlewares/error.middleware';
import mongoose from './config/mongoose.config';
// create app
const app = express();
(async () => {
// connect to mongoose
await mongoose.connect();
// pretty print on dev
if (process.env.NODE_ENV !== 'production') {
app.set('json spaces', 2);
}
// apply express middlewares
app.use(express.json());
// register v1 routes
app.use('/v1', routes);
// catch errors
app.use(notFoundMiddleware);
app.use(errorMiddleware);
// start server
app.listen(config.port, () => console.info(`server started on port ${config.port}`));
})();
export default app;
This is the notFoundMiddleware:
export default (req, res, next) => next(new Error('Not Found'));
This is the errorMiddleware:
const errorMiddleware = (err, req, res, next) => {
console.log('test'); // this works in development, but not in production
const error = {
status: err.status,
message: err.message
};
if (err.errors) {
error.errors = err.errors;
}
if (process.env.NODE_ENV !== 'production' && err.stack) {
error.stack = err.stack;
}
return res.status(error.status || 500).send({ error });
};
If you are runing on production server, try to use some logging provider like "papertrailapp" to see the error occurs in your app.
I've just stumbled upon the same problem. It turned out it's caused by a transpiler optimization applied when building production bundle - this one: https://babeljs.io/docs/en/babel-plugin-minify-dead-code-elimination
Express' error handlers should have the signature (err, req, res, next) => { ... } (be of arity 4). In your example next is not used anywhere in errorMiddleware function body and thus it gets eliminated (optimized-out) from function signature in production code.
Solution:
use keepFnArgs: true plugin option - possibly through https://webpack.js.org/plugins/babel-minify-webpack-plugin/ webpack configuration:
var MinifyPlugin = require("babel-minify-webpack-plugin")
module.exports = {
// ...
optimization: {
minimizer: [
new MinifyPlugin({
deadcode: {
keepFnArgs: true,
},
}, {}),
],
}
// ...
}
or alternatively pretend in your code that this argument is used:
const errMiddleware = (err, req, res, _next) => {
// ... your code ...
// ...
// cheat here:
_next
}

Send JSX data as JSON from Express backend and then display it as component in React Frontend

I am creating a simple react front-end with Express backend. Can I get express to send me JSX data as JSON so I can fetch it in react and display it as a component? Currently I am sending JSON data and displaying it in react as a component and it works fine, How can I send JSX data as JSON?
Here is the code till now,
React front-end:-
import React, { Component } from "react";
import "./App.css";
class App extends Component {
state = { users: [] };
componentDidMount() {
fetch("http://localhost:3001/users")
.then(res => res.json())
.then(users => this.setState({ users }))
.catch(error => { });
}
render() {
return <div className="App">
<h1>Users</h1>
{this.state.users.map(user => <div key={user.id}>
{user.username}
</div>)}
</div>;
}
}
export default App;
Express Backend:-
var express = require("express");
var router = express.Router();
/* GET users listing. */
router.get("/", function(req, res, next) {
// Comment out this line:
//res.send('respond with a resource');
// And insert something like this instead:
res.json([
{
id: 1,
username: "samsepi0l"
},
{
id: 2,
username: "D0loresH4ze"
}
]);
});
module.exports = router;
Your implementation seems correct but there is an error in the request.
Your React component should be requesting http://localhost:3001/ or you should change your Express endpoint to router.get('/users', ....
As you are trying to retrieve data from express you are making a call to /users but there is no code present in express to recieve or respond to this call.
You need to add an additional router.get("/users", function(req, res, next) { } to make this call work. I don't think there could be any reason to send JSX component (I guess you meant components when you stated data) via a request back to react.
Please describe the actual problem that you want to solve.