How to make simple RESTful app using node, express, and mongoose - mern

I am completely new to server-side development. almost whole month I spent for learning mongodb, nodeJs, Express. So I tried for the first time to make simple RESTful api using these. but over and over again I've been getting same error. here is code:
const http = require("http")
const express = require("express")
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const schema = mongoose.Schema;
const url = "mongodb:localhost:27017/app";
//connection to db
const con = mongoose.connect(url,{useNewUrlParser:true,useUnifiedTopology:true})
con.then((db)=>{
console.log("connection is successful");
}).catch((err)=>{
console.log(err);
});
//schema
const plan = new schema({
name:{
type: String,
required:true,
unique:true
},
gender:{
type: String,
required: true
},
date:{
type: Date,
default: Date.now
}
})
const details = mongoose.model("model", plan, "details")
const port = 3000;
const hostName = "localhost";
const app = express();
app.use(bodyParser.json());
app.get("/", (req, res)=>{
res.statusCode = 200;
res.setHeader("Content-Type","application/json")
res.end("This is working well")
});
app.post("/details", (req,res)=>{
details.create(req.body)
.then((details)=>{
console.log("new details is added to database")
res.writeHead(200,{"Content-Type":"application/json"})
res.json(details)
})
.catch((err)=>{
console.log(err)
})
})
app.get("/details", (req,res)=>{
details.find({})
.then((details)=>{
res.writeHead(200,{"Content-Type":"application/json"})
console.log("Recorded documents are: \n")
res.json(details)
})
.catch((err)=>{
console.log(err)
})
})
const server = http.createServer(app)
server.listen(port, hostName,()=>{
console.log(`connected to localhost: ${hostName}:${port}`)
And the error I'm getting is:
MongoParseError: Invalid connection string
at parseConnectionString (F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongodb\lib\core\uri_parser.js:565:21)
at connect (F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongodb\lib\operations\connect.js:282:3)
at F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongodb\lib\mongo_client.js:223:5
at maybePromise (F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongodb\lib\utils.js:662:3)
at MongoClient.connect (F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongodb\lib\mongo_client.js:219:10)
at F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongoose\lib\connection.js:788:12
at new Promise (<anonymous>)
at NativeConnection.Connection.openUri (F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongoose\lib\connection.js:785:19)
at F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongoose\lib\index.js:341:10
at F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongoose\lib\helpers\promiseOrCallback.js:31:5
at new Promise (<anonymous>)
at promiseOrCallback (F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongoose\lib\helpers\promiseOrCallback.js:30:10)
at Mongoose.connect (F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\node_modules\mongoose\lib\index.js:340:10)
at Object.<anonymous> (F:\Node.Js files\Coursera\week2\#3 REST API with Express, node and mongoose\#1 Example\index.js:7:22)
at Module._compile (internal/modules/cjs/loader.js:1176:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1196:10)
connected to localhost: localhost:3000
so my question is, Am i making any sort of mistake? if it is, then how can i solve it?

The URL should be:
mongodb://localhost:27017/app
That is why it is giving you "Connection Error".

Related

Reading Arduino data using WebSocket with HTML & nodejs

I can't quite grasp the last step in this puzzle. Everything compiles, and it is "bug-free". This is my first foray into communications/full-stack and I have been stumped despite numerous excellent tutorials.
[WORKING] Arduino reads and interprets sensor data
[WORKING] index.js acquires data with serial communication over USB
[WORKING] index.js creates a WebSocket connection using nodejs
[WORKING] index.html performs the WebSocket handshake
[WORKING] index.html uses Plotly to create a real-time line graph
[WIP] index.html passes through the Arduino data in the Plotly function
Chopped down index.html:
<script src="server/plotly.min.js"></script>
<script>
//connection to the web socket server
const ws = new WebSocket("ws://localhost:5000");
let foo = 0.0;
//working
ws.addEventListener("open", () => {
console.log("We Are Connected");
ws.send("TestData");
});
//working
ws.addEventListener("message", e => {
console.log(e);
console.log("Data Recieved! Success.");
});
</script>
Rest of the file is just the graphing function which I would like to pass through Arduino data.
index.js
const WebSocket = require("ws");
const wss = new WebSocket.Server({ port: 5000 });
//create a serial port that allows serial connection from Arduino
let SerialPort = require("serialport");
let port = new SerialPort('COM4', { baudRate: 9600 });
let Readline = require("#serialport/parser-readline");
let parser = port.pipe(new Readline({ delimiter: '\n' }));
wss.on("connection", ws => {
//working
console.log("New Client Connection");
//this is what I need to passthrough my Plotly arg
parser.on("data", data => {
//event is firing but can't get client to grab this. Console logs data correctly.
console.log(RPM: ${data});
});
//working on both ends
ws.on("message", data => {
console.log("TEST")
ws.send(data);
});
//doesn't log?
port.on("open", () => {
console.log("Serial Port Open");
});
});
//working
console.log("The server is ON");
I'm looking for a strategy or method to grab the sensor data in my HTML file. Is it something simple conceptually I am missing? Thank you.
You established a websocket server, and it is works. If you want to send message to websocket, define a socket to the websocket server, get out the Serial part from websocket server, and run is standalone, and send data from this to the websocket.
Like this:
const http = require('http');
const WebSocketServer = require('websocket').server;
const server = http.createServer();
server.listen(5000);
const wsServer = new WebSocketServer({
httpServer: server
});
let SerialPort = require("serialport");
var serialPort = new SerialPort("COM5", {
baudRate: 9600,
parser: new SerialPort.parsers.Readline("\n")
});
var connection;
wsServer.on('request', function(request) {
connection = request.accept(null, request.origin);
connection.on('message', function(message) {
console.log('Received Message:', message.utf8Data);
connection.sendUTF('Hi this is WebSocket server!');
});
connection.on('close', function(reasonCode, description) {
console.log('Client has disconnected.');
});
});
serialPort.on('open',function(){
//connection.sendUTF('Hi this is WebSocket server!');
console.log('open');
serialPort.on('data', function(data){
readData = data.toString();
console.log("N<", readData);
if( typeof connection!="undefined")
connection.sendUTF( readData);
});
});

connection in channels.js returns undefined?

I'm trying to establish a real-time socket connection to my client
side via feathers channels. It works without any sort of
authentication. But if i add the following login action scoket is
throwing a weak map key error.
app.on('login', (authResult, { connection }) => {
console.log(connection) // returns undefined
....
})
This is the error I'm receiving
Unhandled Rejection at: Promise Promise { TypeError:
Invalid value used as weak map key
at WeakMap.set ()
app.on('login', (authResult, { connection }) => {
console.log("============>>", connection)
if (authResult && connection) {
app.channel('anonymous').leave(connection);
if (authResult.user && authResult.user['chanelName']) {
let channelName = authResult.user['chanelName'].toString();
channelName = channelName.substr(0, 5)
app.channel(`channel/${channelName}`).join(connection);
} else
app.channel('authenticated').join(connection)
}
});
The connection object is undefined, i think that causes the problem.
Anu suggestions?
Please provide the client side script.
According to fethers documentation connection can be undefined if there is no real-time connection, e.g. when logging in via REST.
You should authenticate your client.
Sample script
const feathers = require('#feathersjs/feathers');
const socketio = require('#feathersjs/socketio-client');
const io = require('socket.io-client');
const auth = require('#feathersjs/authentication-client');
const socket = io('http://localhost:3031');
const app = feathers();
// Setup the transport (Rest, Socket, etc.) here
app.configure(socketio(socket));
const options = {
header: 'Authorization', // the default authorization header for REST
prefix: '', // if set will add a prefix to the header value. for example if prefix was 'JWT' then the header would be 'Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOi...'
path: '/authentication', // the server-side authentication service path
jwtStrategy: 'jwt', // the name of the JWT authentication strategy
entity: 'user', // the entity you are authenticating (ie. a users)
service: 'users', // the service to look up the entity
cookie: 'feathers-jwt', // the name of the cookie to parse the JWT from when cookies are enabled server side
storageKey: 'feathers-jwt', // the key to store the accessToken in localstorage or AsyncStorage on React Native
storage: undefined // Passing a WebStorage-compatible object to enable automatic storage on the client.
}
app.configure(auth(options))
app.authenticate({
strategy: 'jwt',
accessToken: '<JWT TOKEN>'
}).then(() => {
console.log("Auth successfull")
const deviceService = app.service('myService');
deviceService.on('created', message => console.log('Created a message', message));
}).catch(e => {
console.error('Authentication error', e);
// Show login page
});
Hope this will help you.

Error when subscribing to ERC-20 (BAT, i.e. Basic Attention Token)

I'm trying to subscribe to BAT(Basic Attention Token) ERC-20 token "Transfer" event to detect any transaction made to my ethereum address using web3 in nodejs. I'm using parity (Parity/v1.10.6-stable-bc0d134-20180605/x86_64-linux-gnu/rustc1.26.1) node running on same local machine -
parity --jsonrpc-hosts all --jsonrpc-apis all --ws-apis all --ws-hosts all --ws-origins all --ws-interface all
Here is the code that I've used to subscribe -
const Web3 = require('web3');
const abi = require('human-standard-token-abi');
var contract = '0x0D8775F648430679A709E98d2b0Cb6250d2887EF'; //BAT contract address
var web3Socket = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8546'));
function tokenEventListener = (address) => {
let token = new web3Socket.eth.Contract(abi, address);
console.log(address);
let subscription = token.events.Transfer({
fromBlock: 0
})
.on('data', (event) => {
// do something
})
.on('error', console.error);
}
tokenEventListener(contract);
I get an error when I run the code -
Error: CONNECTION ERROR: Couldn't connect to node on WS
It means that your node is not set up properly. Change:
var web3Socket = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8546'));
to
var web3Socket = new Web3(new Web3.providers.WebsocketProvider('wss://mainnet.infura.io/ws'));
This will connect to the Infura node which doesn't require you to host one.

Angular 4 with nodejs and Mysql connectivity

I am new in angular and node js. I want to know how angular connect with node js with mysql server. Which simple return query result. Can anyone help me.
Angular is a fronend framework and nodejs can be used to implement a backend for a system. And you can use mysql as your DBMS.
You have to implement your backend and frontend separately. From backend you are exposing endpoints, routes, apis to the external applications.
And you can access those apis,routes from angular using HttpClient module. You can make Http requests using that.
Hope this helps
You may need to use some libraries to make a connection between angular frontend and backend with MySQL database.
You will need the express.js to handle the backend for the data request. Because you use the MySQL database, the database language would be different from any others such as MongoDB. The express provided database integration for the different databases.
You also need a body-parser as a middleware to parse the request body. This is a very important part of your project. The req is very complicated and this middleware can help to get the information which you need.
Here is a sample of how to use express connect mysql.
var express = require('express');
var query = require('./query')
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var app = express();
//Middleware for bodyparsing using both json and urlencoding
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
//login
app.post('/login',(req,res)=>{
var opts = req.body;
query(" SELECT *FROM `v_users` WHERE userAcount = ?",opts.userName).then((result)=>{
var response = result[0];
if(opts.password !== response.u_password){
return res.send({
errorCode:'404',
errorMsg:'password error'
})
}
//loginToken
var loginToken = response.userAcount + Math.random()*Math.pow(10,16)
res.send({
loginToken:loginToken
})
})
})
var server = app.listen(3000,()=>{
console.log('success')
})
Here is the query method:
(function() {
var mysql = require('mysql');
// var session = require('cookie-session');
var query = (sql,key) => {
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root123',
database: 'm_users'
});
connection.connect()
var promise = new Promise((resolve,reject)=>{
connection.query(sql,[key], function(error, results, fields) {
if(error){
reject(error)
}else{
resolve(results);
}
});
connection.end();
});
return promise;
}
module.exports = query;
})()

node-mysql Connection Pooling "No connections available" for Node.js Application

I've got a website I've written that gets data from a Restful web service. That Restful web service is run off node.js and MySQL using node-mysql. The problem I am running into is with connections running out. For example, my default page does a bunch of lookups to get data. On the 9th refresh of that page, one of my lookups to the Restful API throws this error "No connections available."
Here is kind of how things are architected on the Restful API side:
In server.js:
var db = require('mysql');
var db_pool = db.createPool(
{
host : 'localhost',
connectionLimit: 100,
supportBigNumbers: true,
waitForConnections: false
});
setRoutes(server, db_pool, passport, LocalStrategy, jwt, tokenSecret, bcrypt);
In router.js:
setRoutes = function(server, connectionPool, passport, LocalStrategy, jwt, tokenSecret, bcrypt)
{
require('./lib/places.js');
place.connectionPool = connectionPool;
}
server.get('api/place/:id', function(request, response)
{
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Headers", "X-Requested-With");
place.get(request.params.id, function(err, data)
{
response.send(data);
next();
});
});
Finally, in places.js:
place.connectionPool = null;
place.get = function(id, callback)
{
place.connectionPool.getConnection(function(error, connection)
{
var query = "select myColumn from myTable";
connection.query
(
query,
function (queryError, rows, fields)
{
try {connection.release();} catch(e){};
if (queryError)
{
console.log(JSON.stringify(queryError));
return (callback(null, queryError));
}
return (callback(null, rows));
}
);
});
}
What is the best practice for implementing node-mysql and connection pooling for websites?
Thanks!
Solved the connection issue - I was not releasing the connection in all places where I was doing a callback.