How get data from mongodb into react router to render on page - node.js

I have an existing blog and I want to move to react. My production blog uses node, express, and mongodb. I followed this guide to get up and running with react. I think I can use the pages I've setup to grab data from mongo with a request like https://domain.com/api/all-documents for the homepage. How can I add an API request to the react router in the app.get('*',(req, res) section from the guide's app-server.js file?
I want to add something like:
const db = require('monk')('localhost/myDB')
const documents= db.get('documents')
db.close()
app.get('/api/all-documents',function(req,res){
documents.find({}, {}, function(err, docs) {
res.json(docs);
});
});
Then in my react pages I can use the JSON data to add content to the page ... right?
Thanks!

Related

React fullstack architecture: When adding a react front-end to a node/express application, what aspects does react's state generally handle?

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.

Generate Express Routes Dynamically from MongoDB Data which changes every few Minutes

I want to create a web page that dynamically renders data from mongoDB.
I am crawling articles on the internet and then saving data related to that in a MongoDB.
Now I want to create dynamic routes within express (e.g. page/:word), where word is a word taken from the crawled articles. If you use that route you get some information and statistics about the word (e.g. when it's used most)
The Problem I am having now is, that once i started my NodeJS Express Server the routes aren't updatet because once the data is loaded from the MongoDB it's not updatet later, when there is for example a new word in the database.
Is there any way to update these routes dynamically when I change data in the MongoDB ?
Btw: I am Using Handlebars to render the webpage, would all of that be easier with Angular ?
Thank you so much for your help!
You could check the database for each request, to see if the word can be found in the database:
app.get('/page/:word', (req, res) => {
collection.find({ word : req.params.word }).toArray().then(results => {
if (results.length) {
...word found...
} else {
...word not found...
}
});
});

Problem integrating Angular SPA and mongodb in heroku

I am creating a simple app using angular and I am trying to use mongodb to save my data. So far I managed to create my SPA with angular and deploy it to heroku adding the server.js file. My problem starts when I tried to connect mongodb.
Currently I was serving my page using
app.get('/*', function(req,res) {
res.sendFile(path.join(__dirname,'/dist/showoff/index.html'));
});
Inside index.html I am calling <app-root> and my application has two routes: /display and /control
I then realized I have to add some more routes to save and read from my database through a service, so I had to add things like:
router.route('/players').get((req, res) => {
Player.find((err, player) => {
if (err)
console.log(err);
else
res.json(player);
});
});
Problem is that I cant reach those routes since I have already one with /*. I tried writing this other routes on top as I figured it might take the first it finds but its not working and I am always redirected to my index.html
My question is:
Is there a way to deploy my SPA like this and still use mongo? or do I need to somehow restructure everything since my approach isn't right?
You can find my whole code here if needed GitHub code
In case it helps anyone I did the following. Not sure if its the best way to go but it worked.
I divided my /* route as follows
app.get('/display', function(req,res) {
res.sendFile(path.join(__dirname,'/dist/showoff/index.html'));
});
app.get('/control', function(req,res) {
res.sendFile(path.join(__dirname,'/dist/showoff/index.html'));
});
And continue to add handlers for other routes there, which manage the requests to write and read from the database.

SailsJS - How to render views in server

Can please someone let me know how to render all the views in the server and send it to the web browser ? Just like any other PHP framework would do ?
Is this feasible at all ?
Read through the Sails.js documentation.
In the controllers section you can learn about the Response Object. On the response object you have a function called view().
So you can use res.view() to render a view and send it to the client. Typical example:
functionNameHere: function(req, res, next) {
res.view({
data: {first: "one", second: "two"}
});
}
Sails.js is built on top of Express.js. There are already plenty of tutorials on how to use Express on the internet.
Here is the documentation for Express.
Just put:
YourFunctionName : function (req,res) {
res.view('yourview', option, data);
}
The parameters are optional depending on the way you need and you put your route.js file.
Read the controllers section on: http://sailsjs.org/#!documentation/controllers

How to dynamically render/load pages in express?

I need to dynamically load/render part of a page in nodejs (v1.8.15) with express (>3.0) framework. Generally, I want to create a single-page app.
I have a menu at the top of the page with links. Clicking on the links will change the content below, as in AJAX page loading.
For example:
>home|login|signup|chat
..content for home..
If I press the 'signup' link:
home|login|>signup|chat
..content for signup..
In express I have routes on the server:
var express = require('express');
var app = express();
app.get('/signup', function(req, res) {
// render signup.jade
res.render('signup');
}
app.post('/signup', function(req, res) {
// .. work with information
if (ok) res.send('ok', 200); else res.send(error, 200);
}
After reading this, I figured out that I should use socket.io. I know sockets well, so it will be easy to send data about 'clicking on link' from the client to the server.
Q1: How do I render/load pages dynamically like I wrote in express?
Yes, I could use AJAX for page loading, but will it work for .post methods in express?
How should I organize my thoughts to create such a site?
By the way, I've read about Derby and SocketStream, but I didn't understand.
Q2: Can I use Derby or SocketStream in my aims (site functions: login, signup, chat)? How?
If SocketStream is what I need, that would be very bad, because Heroku doesn't work with it.
Q1) This is in fact very simple, no need for Socket.io, Derby or whatever. You can call any expess route with any method through ajax, using jQuery makes ajax very easy. In your example, let's suppose your container HTML file has a div with id 'container', which is where you want the ajax-loaded content to go:
$.ajax({ url: 'http://yoursite.com/signup'
, type: 'GET'
, dataType: 'html'
})
.done(function(data) {
$('#container').html(data);
})
.fail(function() {
console.log("Something went wrong!");
});
Express supports all HTTP verbs (GET, POST, PUT etc.). For loading pages dynamically, use GET, then when a user enters some login information you can POST it to an Express route that will tell you if it is valid or not, and you use jQuery to modify the DOM accordingly.
Q2) As said in Q1, no need to use Derby or SocketStream. Plain old jQuery + basic Express will get you where you want!

Resources