Using Mixpanel - Node Library in Express - node.js

I am currently trying integrate the Mixpanel Node library into a test application that I am building. This is a Node.js application using the express framework.
As per the express docs, I have a JS file to manage the project, a folder called "public" that contains all of my static files, and another folder with the node modules that come with express.
I have two static HTML pages in "public" that I am trying to put mixpanel tracking into. I am running the project locally by running node app.js.
app.js includes:
const express = require('express');
const app = express();
const port = 3000;
const path = require('path');
//Mixpanel Additions
var Mixpanel = require('mixpanel');
var mixpanel = Mixpanel.init('<I am putting my project token here>', {
protocol: 'https'
});
//App Configuration and Init
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/public/page.html'));
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
In my HTML files I try to use mixpanel functions by putting them into script tags:
<script>
mixpanel.track("event")
</script>
But when I run node app.js and view the page in my browser it says:
Uncaught ReferenceError: mixpanel is not defined
I have a pretty poor understanding of node.js, but I am imagining that I need to use app.use(), app.get(), or something along those lines to get the Mixpanel lib loaded into the app. What am I doing wrong? I also realize that my understanding of Express and Node is pretty rudimentary, so any additional knowledge is appreciated, especially if I am way off.

If you want to call mixpanel tracking functions in the browser, you should load the mixpanel library in a script tag on the browser side, as seen here:
https://developer.mixpanel.com/docs/javascript
The purpose of the node.js package is to send events from the server side, like if you wanted to log when page.html is rendered, you could do
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/public/page.html'));
mixpanel.track('event')
});

Related

How to manage NodeJs app code to reduce clutter

Hie,
I am developing a Nodejs (Express) web app and pretty much new to this technology. So far I see that there can only be one point of entry mine being my the server.js file. Now it seems all requests and/or processes should be initiated here which is fine for a smaller application, but my site has about 25 page routes already all of who's request should be handle here. I also have a dozen or so Ajax requests are handled here. Now even though I am processing different functions e.g CRUD operations in separate files, I still fear at some point my code will become unreadable as the server.js file get longer
const express = require("express")
const path = require("path")
const exphbs = require("express-handlebars")
let app = express()
app.set("views",path.join(__dirname,'templates'))
app.engine('handlebars',exphbs({defaultLayout:'main'}))
app.set('view engine','handlebars')
app.set('port',(process.env.PORT || 3000));
app.get('/',(req,res)=>{
res.render('home',{'title':'Home'});
});
app.get('/home',(req,res)=>{
res.render('home',{'title':'Home'});
});
app.get('/register',(req,res)=>{
res.render('register',{'title':'Register'});
});
app.use(express.static(path.join(__dirname, '/public')));
app.listen(app.get('port'),()=>{
console.log(`Server started on port : ${app.get('port')}`)
})
So far my server.js is this small, but it just hit me that I have 25 pages and multiple Ajax processes on each.
Yes, you have to structure your routes. For that, you have to look at Express Router. You have to create different route files based on a specific resource.
/routes/homeRoutes.js
const express = require("express");
const router = express.Router();
router.get('/',(req,res)=>{
res.render('home',{'title':'Home'});
});
module.exports = router;
server.js
const homeRoutes = require("./routes/homeRoutes");
app.use("/api/v1/home", homeRoutes);
Also, have a look at the following links for a better understanding of project structure and express router.
https://expressjs.com/en/guide/routing.html
project structure
I think what you are looking for is splitting the code up in local modules. You can place parts of your code in separate files, include module.exports at the end and then require(./filename.js) them in your server.js.
You can see an example here: https://www.tutorialsteacher.com/nodejs/nodejs-local-modules

React Router with Node JS

When using React-Router, you only serve up the original index.html with Node because the client handles the rest. I understand how to route between different pages once the user is at the home page. However, let's say the user types in the URL '/about'. Node will serve up the index.html, but how do you tell React-Router to then immediately take the user to the about page? Thank you.
If you have your BUILT create-react-app project sitting inside you node/public folder. you need to let express know that the index.html file will be handling the routes. see super simple server example below. this will use react routers setup properly.
const express = require('express');
const app = express();
const path = require('path');
app.use(express.static(path.join(__dirname, 'public')));
app.get('*', (req, res) => res.sendFile(path.join(__dirname, 'public/index.html')));
app.listen(3000);

How to create a node based server to serve REST API and also deploy the application.

I am new to nodeJS server area, need help in understanding how to work with REST API (using express) and deploy the angular application over a singe node server and same ports.
By deploying i want to understand if user hit below url http://localhost:8000/<page_name> then the specified page should open.
And is user hit below url using get or post request
http://localhost:8000/api/<api_name> then a json or a text will be returned.
How to run both the thing over a single node server.
Lets assume, you have all your static files in the /public folder of you app. Generally spoken, if you are using express.static, you should also get your index.html because this is handled by default for each directory.
In your case, as you are using Angular, the routing is handled from the client side (SPA). You should only have one single index.html after building your Angular app. All files from your dist folder should then be placed into your /public folder. Then you need to make sure, that initial file serving provides your index.html like so:
In this example static files are served first, then your API and if nothing is found, you are getting back you index file.
const express = require('express');
const app = express();
// serve static files
app.static(__dirname + '/public'));
// serve your API
app.get('/api/welcome', function (req, res) {
res.send('Welcome');
});
// fallback routing (server side handling)
app.get(/.*/, function (req, res) {
res.sendFile(__dirname + ‘/public/index.html‘
});
app.listen(3000);
Next time please make sure, to give all necessary information in your question ;-)
With the help from Sebastian, so far I can find a solution but its not working when i am hitting URL for different pages.
const express = require('express');
const app = express();
app.use(express.static('public'))
Please provide your suggestions.

Router.use() requires middleware functions

I use express to serve angular html file. I want to test if angular can get data from express backend.
app.component.html
<h1>
{{title}}
</h1>
<a class="button" href="/Books/getall">Get all books</a>
server.js
const express = require('express');
var app = express();
var staticRoot = __dirname;
app.set('port', (process.env.PORT || 3000));
var bookRouter = require('./bookController');
app.use(express.static(staticRoot));
app.get('/', function(req, res) {
res.sendFile('index.html');
});
app.use('/Books', bookRouter);
app.listen(app.get('port'), function() {
console.log('app running on port', app.get('port'));
});
bookController.js
var express = require('express');
var mongoose = require('mongoose');
var Books = require('./books.model');
var bookRouter = express.Router();
var router = function(){
bookRouter.use('/getall')
.get(function(req, res){
var url = 'mongodb://admin:password#ds019076.mlab.com:19076/booksdbtest';
mongoose.connect(url, function(err){
Books.find()
.exec(function(err, results){
res.send(results);
mongoose.disconnect();
});
});
});
};
module.exports = router;
But I got some error like I mentioned on the title. I have read some articles and discussions that says i need some proxy when using express and angular 2 together but I really don't know how to implement that. Can someone help me here on what is wrong with the code? That would be so much appreciated.
EDIT:
I have found what caused the error. I have changed bookRouter.use -> bookRouter.route and the error is gone. Now another problem appears. If I click the link it will load continously and nothing happens. Anyone know why?
If you are using Angular2 with Express you need to hand off the front end routes to Angular2 and then use Express for the back end points.
In most cases you will receive problems not using some sort of template engine. I like to use Express-Handlebars.
npm install hbs
Once you have this installed you can set it up in your app.js file. The file you set Express up in.
// view engine setup
app.set('views', path.join(__dirname, 'public'));
app.set('view engine', 'hbs');
Also make sure you have a public directory. If not create one.
/public
Then in the app.js
app.use(express.static(path.join(__dirname, '/public')));
Now you can put css, js, or images in this directory and call them inside your app.
Also inside the public directory you can put your index.hbs file.
Express-Handlebars uses hbs files. In our case you are only going to need one.
This is the file you would need to put the head of your html file in. As well as the
<my-app>Loading...</my-app>
We will pass this off to Angular2.
Now that we have that setup lets make a route to pass it off.
/routes/index.js
var express = require('express');
var router = express.Router();
// pass front end off to Angular2
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
So now when the app loads it will load that index page. So that is the only route we need for now to pass the front end off. At this point we will configure angular2.
Webpack
What is Webpack?
Webpack is a powerful module bundler. A bundle is a JavaScript file
that incorporate assets that belong together and should be served to
the client in a response to a single file request. A bundle can
include JavaScript, CSS styles, HTML, and almost any other kind of
file.
I do not know how you have included Angular2 into your project. But if you have not set it up yet and do not know how I suggest using Webpack
Follow this tutorial to get it setup. Sometimes it is easier to start over.
Angular2
If you go into your Angular2 application now which for me is at
/assets/app/
You will set up your components and their own routing. Any links created for the front views will be done here now. So in the /assets/app directory you will need a app.routing.ts file.
Routing in Angular2
There are many ways to build this file. I like to use templates then child templates which would be to much to explain in this answer. For you though a basic routing file will look like this.
import { Routes, RouterModule } from "#angular/router";
import { AboutComponent } from './about.component';
import { HomeComponent } from './home.component';
const APP_ROUTES: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
];
export const routing = RouterModule.forRoot(APP_ROUTES);
Links
Now that you have routes setup in Angular2 you can create links in your html files or home.component.html like this,
<li class="nav-item p-x-1">
<a class="nav-link" routerLinkActive="active" [routerLink]="['/home']"> Home</a>
</li>
I realize this has not basically given you code that will compile which in a perfect world we would all share like that. But I really understand the struggle and want to help. There is just to much to explain to be able to hand you over that much and it make sense. Please use the tutorial I gave you above. If you have any questions ask. Try and use my answer as a baseline to understand the different components of putting together an application like this.
Disclaimer
You do not have to use Express-Handlebars. If you find in that tutorial they are doing something different just follow along so you can get a working app you understand. I like hbs because I only use it for one file then handle everything on the front end with Angular2. The reason I use it instead of just an html file is because it is a huge pain to configure Express to work right with Angular2. For example if you just use an html file then add it to the public directory then run your app and refresh the page you will get a 404 error. Unless you add something like,
HashLocationStrategy
Which adds ugly hash tags to your url and is annoying in a whole different way. Using a template engine for that small task makes everything work so much easier and better. The configuration is minimal as you can see above.
For a seed project I use,
git clone https://github.com/wuno/md-recruit.git
in the terminal navigate to the new directory you just cloned.
type,
webpack
Then
npm start
Then navigate to localhost:3000
Make sure you have webpack installed globally
npm install webpack -g
It is very important that what ever version of webpack is installed locally in your project has to match the global install.

Why combine http module with express module

Hello guys i'm new to node js and started researching and working on some tutorials. I just want a better understanding or clarification on a doubt i had. So i came across the in built module http. This helps in creating a a basic web server. Now express module is a web framework that is built on top the http module that makes it easy using a fully wedged web server without reinventing the wheel. Now I came across this code:
var express = require( 'express' )
, http = require("http")
http.createServer( options, function(req,res)
{
app.handle( req, res );
} ).listen(8080);
But in express one could simply just do this
var express = require('express');
var app = express();
app.listen(8080, function() {
console.log('Listening on ' + 8080);});
What's the difference between both? Don't they both accomplish the same thing. If not what's the difference and advantage of using the first approach. Should one adhere to the first approach as it's a good programming practice. That's my doubt as i just want a clear understanding if there's any difference.
Why combine http module with express module
There's really no reason to create your own http server using the http module. Express will just do that for you with app.listen() just fine and save you little bit of typing.
If you were creating an https server, then you would need to use the https module and pass security credentials to https.createServer(...) in order to create a properly configured server. Express does not have the ability to create a properly configured https server for you automatically.
If you look at the Express code in GitHub for app.listen(), it shows this:
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
So, there's really no difference (other than a little less typing) when you use app.listen() or create your own http server and then use app as the listener to that server.
So, these two code snippets are identical in function:
var app = require('express')();
app.listen(8080);
app.get('/', function(req, res) {
res.send("hello");
});
The above code is functionally identical to:
var http = require('http');
var app = require('express')();
http.createServer(app).listen(8080);
app.get('/', function(req, res) {
res.send("hello");
});
Of course, if you're trying to set up https servers or add custom options to the .createServer() method, then you will set up your own server first and then pass app to it as the listener. app.listen(...) is just a shortcut when the default http.createServer() works fine.

Resources