Rendering AngularJS HTML page on server side NodeJS - angularjs

I have NodeJS server + AnglarJS page.
All works.
Do working examples or frameworks that allow the download page on the server NodeJS and fill it and return to the client a static page. It is necessary for Browsers IE 5-8 (90% clients).

Yes, take a look at Express for Node.js - you can easily serve up a single static page and then use a link to redirect users to your Angular app (using a 'login' page, for example).
Here is an example of a very basic Express app.
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Hello World!')
})
var server = app.listen(3000, function () {
var host = server.address().address
var port = server.address().port
console.log('Example app listening at http://%s:%s', host, port)
})
The req (request) and res (response) are the exact same objects that Node provides, so you can invoke req.pipe(), req.on('data', callback) and anything else you would do without Express involved.
The app starts a server and listens on port 3000 for connection. It will respond with "Hello World!" for requests to the homepage. For every other path, it will respond with a 404 Not Found.
Save the code in a file named app.js and run it with the following command.
$ node app.js
Then, load http://localhost:3000/ in a browser to see the output.

Related

React-router urls don't work when refreshing or writing manually, gives 404 page not found

My production webiste opens normally, but for a user visiting/accessing that link the first time, he gets a 404 Page Not Found. For users that has already visited the website it loads just fine.
This is the url - https://literacycloud.org/readaloudsdetail/546-jennifer-phillips-reads-the-invitation.
Ideally it should redirect to the login page, but there is no api being hit at all.
The issue doesn't get reproduced locally only when deployed to development or to live, getting this issue.
Is it something back-end has to handle from their end?
Any help appreciated.
Set historyApiFallback in your webpack.config.js. Checkout this.
Also, it is a good idea to serve your index.html from a server. The idea is that no matter what url you visit on your domain, the server should always return the index.html as it contains your react code.
Here is a sample code:
const path = require('path');
const express = require('express');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
app.set('port', process.env.PORT || 8080);
app.get("*", (req, res, next) => {
const filePath = path.join(__dirname, 'build', 'index.html');
res.sendFile(filePath);
});
const server = app.listen(app.get('port'), function () {
console.log('listening on port ', server.address().port);
});

Prerender.io with reactjs/express application not recognizing Prerender token

I'm trying to get prerender set up with my application. I'm using react on the client side, and express on the server side. I set up an account on prerender IO, and have installed the prerender-node middleware as recommended by the site. Here is what my server looks like:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
const SocketManager = require('./sockets/SocketManager')
const path = require('path');
const users = require("./routes/api/users");
const queries = require('./routes/api/queries');
const forumActions = require('./routes/api/forumActions');
// Routes
app.use("/api/users", users);
app.use("/api/queries", queries);
app.use("/api/forumActions", forumActions);
// Serve static assets if in production
if (process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('client/build'));
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
app.use(require('prerender-node').set('prerenderToken', 'xxxTOKEN_CODExxx'));
const port = process.env.PORT || 80;
const server = app.listen(port, () => console.log(`Server running on port ${port} !`));
const io = require('socket.io')(server);
io.on('connection', SocketManager);
On the client side I'm using react-helmet to dynamically render the meta tags (title, description, etc.) based on the route. Ideally I would like to be able to share posts on social media and have the meta data display (which to my understanding prerender can do by prerendering pages specifically for web crawlers).
I've set up a prerender.io account and added my URL to the cached pages, but for some reason I am getting a message saying "We haven't seen a request with your Prerender token yet.". I am hosting on heroku, and have tried adding the token using the heroku CLI, which still hasn't fixed the issue.
Is there a step I'm missing, or did I not set this up correctly? Thanks!
It looks like you might need to move the prerender-node middleware higher up in your file so that it executes just after your routes but before the index file is served back.
Then you can change your user agent in your browser to Googlebot and visit your URL. If the middleware is set up properly, you would see a prerendered response and a request in your Prerender.io Crawl Stats.

Post SQL data to Angular View with NodeJS

I'm having a difficult time posting data retrieved from a server using mysql with node. I have connected to my db successfully, and I can return the data I want by console logging it to the CLI when running "node server.js". However, I'm not sure how to post this data to my Angular view. No problem console logging, but this doesn't help me get data to the application.
For the moment, I'm just trying to get the data to index.html, which is my primary view and holds my ng-view portion for Angular routing. I'm probably missing something obvious bc I'm new to NodeJS.
// MODULES
var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
var mysql = require('mysql');
var serveStatic = require('serve-static');
var bodyParser = require('body-parser');
var source = __dirname + '/public/views/index.html';
app.use(serveStatic(__dirname, {'index': ['index.html']}));
app.route('/*')
.get(function(req, res) {
res.sendFile(source);
});
var data;
var connection = mysql.createConnection({
host : 'thehostdb',
user : 'username', // credentials correct, connection works
password : 'pw',
database : 'db',
port: '3306'
});
connection.query('SELECT * from poemTable', function(err, rows, fields) {
if (!err) {
data = JSON.stringify(rows);
setDataValue(data);
}
else {
console.log('Error while performing Query:', err);
}
});
function setDataValue(value) {
data = value;
console.log(data); //Where the data logs
}
app.listen(port, function () {
console.log('Example app listening on port' + port + '!')
})
You have to understand what this code does, and how nodejs and angular are supposed to work together. Angular is served to the client and then rendered by the clients browser. So if you want to inject data you have to fetch it. So in your angular app when the controller starts make an api call, and in your server create a new route:
app.get('/data', function(req, res, next) {
connection.query(..., function(err, rows, fields) {
res.json(rows);
});
});
Make sure you understand node and it's async nature, what is event loop and how it works and what is callback hell, also I would check out promises and other tutorials on nodeschool.io, it's a great place to start with node :)

Routing between Express and Angular in MEAN.JS

I ran into issues on calling a Express route from my Angular template route and Express -> Angular. This code shows my attempt into tackling this issue.
// Server.js file, the main Node.js code
var Outlook = require('Outlook');
// Bootstrap db connection
var db = mongoose.connect(config.db, function(err) {
etc..
});
// Init the express application
var app = require('./config/express')(db);
app.listen('8443'); // Main server.
// App.js - The Outlook module Express route example code
var app = require('express');
var app = express();
// Configure express
// Set up rendering of static files
app.use(express.static('static'));
// Need JSON body parser for most API responses
app.use(bodyParser.json());
// Set up cookies and sessions to save tokens
app.use(cookieParser());
// Home page
app.get('/', function(req, res) {
res.send(pages.loginPage(authHelper.getAuthUrl()));
});
app.get('/express', function(req, res) {
console.log(req.params.msg);
return 'Your EXPRESS DATA IS HERE!';
});
app.listen(3000); // Is this really necessary?
// outlook.cliet.routes.js
'use strict';
//Setting up route
angular.module('outlook').config(['$stateProvider', '$http',
function($http) {
$http.get('http://localhost:3000/express',{"msg":"hi"}).success(function(data){
console.log(data);
});
]);
Issue 1: I don't want to make express run two different servers in different ports in the same instance. That lead me to next issue.
I am using oauth-sign and simple-oauth2 when I bounce back from the outlook module to the main express server, I am logged off the main server.
I don't think it is required a separate express server. Is it possible to make app.js express routing work without listening to a second express server? Notice that express is initialized in a different way. Perhaps module.exports could help?
Thanks

AngularJS to remote node js(express js) REST api connection time out error

The issue should be pretty clear in the title line. I have a node js REST api server being called by a client AngularJS app.
Ports
The server side is running on port 3000: the code is nice and simple:
app.get('/', function ( req, res ) {
res.sendStatus( string );
})
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log( 'Example app listening at http://%s:%s', host, port );
});
The client side is running on port 8080: the http call looks like this:
var serverURL = "http://localhost:3000";
$http({
url: serverURL,
method:"GET",
dataType: 'json'
}).then( function ( data ) {
$scope.message = data.data;
}, function ( error ) {
console.error( error );
});
Real Issue
When I run this locally it works just fine with the code above. However, when I try to put the server side code on a cloud server with the ip address x.x.x.x I cannot seem to connect. The changes I make to my code are the obvious ones.
Client Side:
var serverURL = "http://x.x.x.x:3000";
Server Side:
var server = app.listen(3000, 'x.x.x.x', function () { ... }
The error looks like what you would assume:
GET: http://x.x.x.x:3000/ net::ERR_CONNECTION_TIMED_OUT
I have no idea what is going on. I don't think its a timeout window being too small issue because it fails after 20 seconds. I could guess that I may need permissions in the server side code to be called from random clients, but I'm shooting in the dark here. Any help would be greatly appreciated

Resources