I'm working on a web application built with react js in the front-end and express js in the back-end, i'm also using MongoDB as a database.
I was following this tutorial in which the YouTuber is using Axios in order to connect between the react js application and the express js API.
Right now i have two questions :
is Next JS used for these kind of things ? if not, what is Next js ?
Should i use Axios like the tutorial ? or there is a better solution for this situation ?
Thank you in advance.
Next Js is basically lets you build server-side rendering and static web applications using React.
You can use following way to connect to your Nodejs backed from react using axios
axios.post(url,data, {
headers: {
'authorization': your_token,
'Accept' : 'application/json',
'Content-Type': 'application/json'
}
})
.then(response => {
// return response;
})
.catch((error) => {
//return error;
});
Where your_token is authenticate token if you have any, url is the nodejs url you want to access and data is the body you supply to post data to your node server.
To fetch data you can use the awesome built in fetch or axios library:
fetch(/* url to your backend, eg. http://localhost:3000/mydata */
, /* notice comma */
/* other options, eg. method: โpostโ */)
.then(response => res.json() /* convert server response from string to JSON */)
.then(data => /* your data array or object like */)
for details: MDN: fetch API
check your browser's console for cors issues ๐
Using create react app you are building a single page app (SPA) which is the standard, that whole app served as a JS bundle to your client browser and after that you fetch data only from server.
On the other hand Nextjs is a server side rendering which is the best of two worlds, it helps with higher page ranking on search engines, lift the heavy load from clients especially (low powered mobile devices) and more
Check this if interesting nextjs
Related
I have a fully built node/express application that I want to add react to in order to practice that relationship in full stack applications. I've built apps in react before, and in node, but never together and I am confused about how react fits into the MVC architecture.
In a react-node full stack application does react state then handle all of the data I was previously passing into my ejs views?
I have been looking through tutorials on full stack applications with node and react, but they only seem to go into issues like how does react fetch data from the back end, or how to set up the configuration,
but I get that part, I just don't understand what react does in a full stack application, what part of the model-controller-view architecture of a node/express backend app does react take over? How are the responsibilities split between the backend and front end?
So for example, I'm working with a reddit-clone type app so when you click on a post title to see the post my controller queries the database for that post and then passes it to the view as {post}:
show(req, res, next){
postQueries.getPost(req.params.id, (error, post) => {
if(error || post == null){
res.redirect(404, "/");
} else {
res.render("posts/show", {post});
}
});
},
So when I add a front-end with react, would that {post} object then be something handled by react? So react would fetch that data and use it in a post component to create what is currently my view show.ejs file?
So when I add a front-end with react, would that {post} object then be something handled by react? So react would fetch that data and use it in a post component to create what is currently my view show.ejs file?
Yes. The show.ejs would be a React view or a page that contains a component to handle how to show it.
To simplify:
React -- is a virtual DOM, so it'll swap views/containers/components in and out based upon events (like clicking a button), which in turn, will: retrieve, display, manipulate and/or send data to the API. In development, it is completely separate from your back-end. All the routing will be handled by a front-end router package. In production, all of the front-end src code is compiled into a dist or build folder that contains your assets (images, fonts, css) and most importantly bundle.js file(s) that are then served by express.
Express + some database -- will act as your API where it'll CRUD data based upon the front-end request(s). If your app is a MPA (multiple page application), then a common practice is to delineate your back-end routes from your front-end routes with a /api/ prefix. In production, if express doesn't recognize the route (it's not a /api/ request), then it'll fall back into the front-end bundle.js file where it'll be handled by the front-end router.
See a working example here: https://github.com/mattcarlotta/fullstack-mern-kit (client is the frontend, everything else is the backend)
Or
See a working codesandbox (where I'm making a GET request to an API that returns json):
For your example above, your show controller will just be sending JSON (or a string message) back to the frontend (redirects will happen on the frontend via a router -- like react-router-dom):
show(req, res, next){
postQueries.getPost(req.params.id, (error, post) => {
if(error || post == null){
// res.status(404).send("Unable to locate posts.");
res.status(404).json({ err: Unable to locate posts });
} else {
res.status(200).json({ post });
}
});
},
You can even simplify the above using async/await:
const show = async (req, res, done) => {
try {
const post = await postQueries.getPost(req.params.id);
res.status(200).json({ post });
} catch(err) {
// res.status(404).send("Unable to locate posts.");
res.status(404).json({ err: Unable to locate posts });
}
};
And then the React front-end handles the response.
I am building a library management system using MERN Stack, where the ISBN number is fetched from free Google Book API. But I am confused about how to fetch an API to my application.
You can use fetch API implemented by browsers or AJAX for using with ReactJS (or any frontend code for that matter)
With nodejs you can use pacakages like request, request-promise, node-fetch, axios in similar fashion.
An example using request library available for nodejs
request
.get('http://google.com/img.png' // api url)
.on('response', function(response) {
console.log(response.statusCode) // 200
console.log(response.headers['content-type']) // 'image/png'
// save the image somewhere, or render to webpage
})
.pipe(request.put('http://yoursite.com/img.png'))
I am building a node.js app with express, I am hosting an Angular SPA in the public folder.
The app runs and the hosting works fine when I use the angular router for navigation around the website, but when I directly try to access the link, for example: http://192.168.1.4:3000/posts, the entire body of the website is just the JSON response object, without the app
this is the Node.js code handling the get request
postRouter.route('/')
.options(cors.corsWithOptions, (req, res) => {
res.sendStatus(200);
})
.get(cors.cors, (req, res, next) => {
posts.find({})
.then((post) => {
res.status(200);
res.setHeader('Content-Type', 'application/json')
res.send(post);
}, (err) => next(err))
.catch((err) => next(err));
})
this is my angular service sending out the get request
getPosts(): Observable<Post[]> {
return this.http.get(baseURL + 'posts')
.catch(error => { return this.processHttpService.handleError(error); });
}
Post Component .ts file
ngOnInit() {
this.postService.getPosts()
.subscribe(posts => { this.posts = posts, console.log(this.posts); },
errmess => this.errMess = <any>errmess);
}
Again, when i use my Angular 5 client app hosted in the public folder, built with ng build --prod, the JSON object is retrieved from the mongodb database and is displayed correctly on my website, along with the rest of the app, the header, the body, and the footer.
it might also be worth noting that the console.log on the ngOnInit() is not displayed on the browser when using the direct link.
Any advice/fix is greatly appreciated
You have a clash of routes between angular and your express application. Angular is served up on one route (I'm guessing the / route) and then it sort of "hijacks" the users navigation. It does this by not actually changing web pages, instead it just changes the URL in the navigation bar, but never actually makes a web request to get to that resource.
You've then got endpoints on a web server listening on those endpoints. This means the moment you visit the /posts page, you're not asking angular to do anything. In fact, angular isn't even loaded because that only gets loaded on the / route. Instead you're going straight to your API.
There are ways around this, to start with many people put their API fairly separately, either on a subdomain or mounted on /api (such as /api/posts). Then your angular app can be served up on the / route. There are other techniques you can use to then allow a user to go to /posts and still get your angular app loaded.
You can use a few approaches for this such as the hash location strategy, or you can serve up your angular application from any route on the application (* in express) and load the angular app which will then take over. This second approach is most comment, it usually results in hosting your api on a sub domain and then serving your angular app on the * route of the normal domain name. For example: api.myapp.com will serve only JSON responses, but any route on myapp.com will serve the angular app, such as myapp.com/posts.
I'm using express as backend. I implemented facebook authentication at the backend.
router.get('/login/facebook',
passport.authenticate('facebook',{scope:['email']}));
router.get('/login/facebook/callback',
passport.authenticate('facebook',{
successRedirect : '/home',
failureRedirect:'/'
})
);
Now I want to call this through my react app, so that when the user lands up at home page, first he should be authenticated by facebook then only he can see homepage. How can I do this ?
I tried using react-router, but I can't understand how to call backend using react-router.
I also fetched /login/facebook using fetch command :
componentDidMount(){
fetch("127.0.0.1:3001/login/facebook");
But it gave me CORS error.
My react app is at 127.0.0.1:3000 and express server at 127.0.0.1:3001.
If this issue is only in dev mode, then Daniel's answer is correct.
In any case, I recommend to avoid calling the :3001 api directly from the :3000 app. Here's what I would do.
I will edit the fetch call as follows,
componentDidMount(){
fetch("/login/facebook");
}
This call will be received by the backend which serves the react application.
Now there are three cases,
Case 1: Your file serving app will have a proxy method which can forward requests to an API. For example read it here
Case 2 This is my Recommended approach. I would simply write the authentication logic in the :3000 server and only use the :3001 API for handling business logic of the app.
Case 3: If you have a backend app (:3000), say written using expressJs, you can forward the request to the :3001 API. Here is a sample code for that,
client.send({
method: req.method,
path: req.url,
data: req.body,
params: req.params
}).then( (response) => {
// Something
}).catch( (err) => {
// Handle error
});
Here the client is a module which uses the request module to make HTTP calls.
You can implement the above call as an express middleware to use it for all HTTP calls.
There are several options:
If you are using webpack dev server, you can set up a proxy to your api. See here
You can temporary disable cors validation during development. See here
I have an application which need to interact with UI and perform various CURD operation to database in the backend,
At present I we have a angular 1.2 application which have the UI and another node application and for every and the angular application sends http request to node application for every interaction needed, so here I have two different services.
I wanted to combine these operations into a one single service means UI(React) and node in one single service, like react inside node, when I start node server I should be able to access by UI also ,I am using express in node, what is the best way to do to use ReactJS with Node in a single service.
Hope you are using express along with nodejs. You could place the react application folder inside your node application folder in some folder named client. Then from node app you could do the following to server react files:
var app = express();
app.use(express.static(path.join(__dirname, 'client')));
After all the application specific routes to serve your apis, provide the following to serve index.html for all other get requests.
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname+'/client/index.html'));
});
In order to execute http requests from a react application (it doesn't matter if you backend is node), I recommend using fetch api:
fetch(url)
.then(response => response.json())
.then(response => /* Do what you need with it */)
Axios also works quite good and provides the same result:
axios.get(url)
.then(response => response => /* Do what you need with it */)
.catch(error => console.log(error))