Overwrite Redis method - javascript

I try to add an option to my app to toggle using a cache. For cache I am using Redis and made simple wrapper for that. The problem is coming when I try to overwrite redis.get method, it's simply doens't work or cannot found this.
'use strict';
const redis = require('redis');
const config = require('../config');
const REDIS_EMPTY_VALUE = 'NOT_EXIST';
const MINUTE = 60;
let client = redis.createClient({
host: config.get('REDIS_HOST'),
port: config.get('REDIS_PORT')
});
client.on("error", function (err) {
logging.error('Redis Error: ' + err);
throw new Error(err);
});
/**
* Next are custom extensions for Redis module
*/
client.emptyValue = REDIS_EMPTY_VALUE;
client.minute = MINUTE;
client.setAndExprire = function(key, value, expire) {
this.set(key, value);
this.expire(key, expire);
};
// Here is the problem
client.get = function(key, cb) {
if (config.get('disable-cache') === 'true') return cb(null, null);
return client.get(key, cb);
}
module.exports = client;

Since you override client.get, the client.get become the new function that you defined. So that, you can call to the function that come along with redis package. You can use another object (custom) to call the redis function like below:
'use strict';
const redis = require('redis');
const config = require('../config');
const REDIS_EMPTY_VALUE = 'NOT_EXIST';
const MINUTE = 60;
const definedFunctions = [
'hgetall', 'hexists', 'hmset', 'hmget', 'hkeys', 'hvals', 'hget', 'hset', 'hdel',
'mget', 'mset', 'set', 'del', 'exists', 'lpush', 'lrange',
'zrange', 'zrem', 'zadd', 'zrangebyscore', 'zrevrangebyscore',
'expire', 'incrby'
];
let client = redis.createClient({
host: config.get('REDIS_HOST'),
port: config.get('REDIS_PORT')
});
client.on("error", function (err) {
console.error('Redis Error: ' + err);
throw new Error(err);
});
/**
* Next are custom extensions for Redis module
*/
const custom = {
emptyValue: REDIS_EMPTY_VALUE,
minute: MINUTE
};
definedFunctions.map((fn) => {
custom[fn] = (...args) => {
return client[fn](args);
};
});
custom.get = function(key, cb) {
if (config.get('disable-cache') === 'true') return cb(null, null);
return client.get(key, cb);
}
module.exports = custom;

Related

Nodejs TypeError: Cannot read properties of undefined (reading 'refresh')

I need your help, it turns out that I am trying to use the Hubstaff api. I am working on nodejs to make the connection, I followed the documentation (official hubstaff api documentation) and use the methods they give as implementation examples (example of implementation nodejs).
But I get the following error:
I don't know why this happens, and I can't find more examples of how I can implement this api. The openid-client lib is used to make the connection through the token and a state follow-up is carried out to refresh the token.
To be honest, I'm not understanding how to implement it. Can someone who has already used this API give me a little explanation? I attach the code
hubstaffConnect.util
const {
Issuer,
TokenSet
} = require('openid-client');
const fs = require('fs');
const jose = require('jose');
// constants
const ISSUER_EXPIRE_DURATION = 7 * 24 * 60 * 60; // 1 week
const ACCESS_TOKEN_EXPIRATION_FUZZ = 30; // 30 seconds
const ISSUER_DISCOVERY_URL = 'https://account.hubstaff.com';
// API URl with trailing slash
const API_BASE_URL = 'https://api.hubstaff.com/';
let state = {
api_base_url: API_BASE_URL,
issuer_url: ISSUER_DISCOVERY_URL,
issuer: {}, // The issuer discovered configuration
issuer_expires_at: 0,
token: {},
};
let client;
function loadState() {
return fs.readFileSync('./configState.json', 'utf8');
}
function saveState() {
fs.writeFileSync('./configState.json', JSON.stringify(state, null, 2), 'utf8');
console.log('State saved');
}
function unixTimeNow() {
return Date.now() / 1000;
}
async function checkToken() {
if (!state.token.access_token || state.token.expires_at < (unixTimeNow() + ACCESS_TOKEN_EXPIRATION_FUZZ)) {
console.log('Refresh token');
state.token = await client.refresh(state.token);
console.log('Token refreshed');
saveState();
}
}
async function initialize() {
console.log('API Hubstaff API');
let data = loadState();
data = JSON.parse(data);
if (data.issuer) {
state.issuer = new Issuer(data.issuer);
state.issuer_expires_at = data.issuer_expires_at;
}
if (data.token) {
state.token = new TokenSet(data.token);
}
if (data.issuer_url) {
state.issuer_url = data.issuer_url;
}
if (data.api_base_url) {
state.api_base_url = data.api_base_url;
}
if (!state.issuer_expires_at || state.issuer_expires_at < unixTimeNow()) {
console.log('Discovering');
state.issuer = await Issuer.discover(state.issuer_url);
state.issuer_expires_at = unixTimeNow() + ISSUER_EXPIRE_DURATION;
console.log(state.issuer);
}
client = new state.issuer.Client({
// For personal access token we can use PAT/PAT.
// This is only needed because the library requires a client_id where as the API endpoint does not require it
client_id: 'PAT',
client_secret: 'PAT',
});
saveState();
console.log('API Hubstaff initialized');
}
async function request(url, options) {
await checkToken();
let fullUrl = state.api_base_url + url;
return client.requestResource(fullUrl, state.token, options);
}
function tokenDetails() {
let ret = {};
if (state.token.access_token) {
ret.access_token = jose.JWT.decode(state.token.access_token);
}
if (state.token.refresh_token) {
ret.refresh_token = jose.JWT.decode(state.token.refresh_token);
}
return ret;
}
module.exports = {
initialize,
checkToken,
request,
tokenDetails
};
controller
const usersGet = async(req, res = response) => {
const response = await api.request('v2/organizations', {
method: 'GET',
json: true,
});
const body = JSON.parse(response.body);
res.render('organizations', {
title: 'Organization list',
organizations: body.organizations || []
});
};

Connection resets after 60 seconds in node.js upload application

I've written an application in node.js consisting of a server and a client for storing/uploading files.
For reproduction purposes, here's a proof of concept using a null write stream in the server and a random read stream in the client.
Using node.js 12.19.0 on Ubuntu 18.04. The client depends on node-fetch v2.6.1.
The issue I have is after 60 seconds the connection is reset and haven't found a way to make this work.
Any ideas are appreciated.
Thank you.
testServer.js
// -- DevNull Start --
var util = require('util')
, stream = require('stream')
, Writable = stream.Writable
, setImmediate = setImmediate || function (fn) { setTimeout(fn, 0) }
;
util.inherits(DevNull, Writable);
function DevNull (opts) {
if (!(this instanceof DevNull)) return new DevNull(opts);
opts = opts || {};
Writable.call(this, opts);
}
DevNull.prototype._write = function (chunk, encoding, cb) {
setImmediate(cb);
}
// -- DevNull End --
const http = require('http');
const server = http.createServer();
server.on('request', async (req, res) => {
try {
req.socket.on('end', function() {
console.log('SOCKET END: other end of the socket sends a FIN packet');
});
req.socket.on('timeout', function() {
console.log('SOCKET TIMEOUT');
});
req.socket.on('error', function(error) {
console.log('SOCKET ERROR: ' + JSON.stringify(error));
});
req.socket.on('close', function(had_error) {
console.log('SOCKET CLOSED. IT WAS ERROR: ' + had_error);
});
const writeStream = DevNull();
const promise = new Promise((resolve, reject) => {
req.on('end', resolve);
req.on('error', reject);
});
req.pipe(writeStream);
await promise;
res.writeHead(200);
res.end('OK');
} catch (err) {
res.writeHead(500);
res.end(err.message);
}
});
server.listen(8081)
.on('listening', () => { console.log('Listening on port', server.address().port); });
testClient.js
// -- RandomStream Start --
var crypto = require('crypto');
var stream = require('stream');
var util = require('util');
var Readable = stream.Readable;
function RandomStream(length, options) {
// allow calling with or without new
if (!(this instanceof RandomStream)) {
return new RandomStream(length, options);
}
// init Readable
Readable.call(this, options);
// save the length to generate
this.lenToGenerate = length;
}
util.inherits(RandomStream, Readable);
RandomStream.prototype._read = function (size) {
if (!size) size = 1024; // default size
var ready = true;
while (ready) { // only cont while push returns true
if (size > this.lenToGenerate) { // only this left
size = this.lenToGenerate;
}
if (size) {
ready = this.push(crypto.randomBytes(size));
this.lenToGenerate -= size;
}
// when done, push null and exit loop
if (!this.lenToGenerate) {
this.push(null);
ready = false;
}
}
};
// -- RandomStream End --
const fetch = require('node-fetch');
const runSuccess = async () => { // Runs in ~35 seconds
const t = Date.now();
try {
const resp = await fetch('http://localhost:8081/test', {
method: 'PUT',
body: new RandomStream(256e6) // new RandomStream(1024e6)
});
const data = await resp.text();
console.log(Date.now() - t, data);
} catch (err) {
console.warn(Date.now() - t, err);
}
};
const runFail = async () => { // Fails after 60 seconds
const t = Date.now();
try {
const resp = await fetch('http://localhost:8081/test', {
method: 'PUT',
body: new RandomStream(1024e6)
});
const data = await resp.text();
console.log(Date.now() - t, data);
} catch (err) {
console.warn(Date.now() - t, err);
}
};
// runSuccess().then(() => process.exit(0));
runFail().then(() => process.exit(0));
I tried (unsuccessfully) to reproduce what you are seeing based on your code example. Neither the success call is completing in ~35 seconds nor is the error being thrown in 60 seconds.
However, that being said, I think what is happening here is that your client is terminating the request.
You can increase the timeout by adding a httpAgent to the fetch PUT call. You can then set a timeout in the httpAgent.
const http = require('http');
...
const runFail = async () => { // Fails after 60 seconds
const t = Date.now();
try {
const resp = await fetch('http://localhost:8081/test', {
method: 'PUT',
body: new RandomStream(1024e6),
agent: new http.Agent({ keepAlive: true, timeout: 300000 })
});
const data = await resp.text();
console.log(Date.now() - t, data);
} catch (err) {
console.warn(Date.now() - t, err);
}
};
See the fetch docs for adding a custom http(s) agent here
See options for creating http(s) agent here
This turned out to be a bug in node.js
Discussion here: https://github.com/nodejs/node/issues/35661

How to pull out handler using module exports?

I am building a node application, and trying to neatly organize my code. I wrote a serial module that imports the serial libs and handles the connection. My intention was to write a basic module and then reuse it over and over again in different projects as needed. The only part that changes per use is how the incoming serial data is handled. For this reason I would like to pull out following handler and redefine it as per the project needs. How can I use module exports to redefine only this section of the file?
I have tried added myParser to exports, but that gives me a null and I would be out of scope.
Handler to redefine/change/overload for each new project
myParser.on('data', (data) => {
console.log(data)
//DO SOMETHING WITH DATA
});
Example usage: main.js
const serial = require('./serial');
const dataParser = require('./dataParser');
const serial = require('./serial');
//call connect with CL args
serial.connect(process.argv[2], Number(process.argv[3]))
serial.myParser.on('data',(data) => {
//Do something unique with data
if (dataParser.parse(data) == 0)
serial.send('Error');
});
Full JS Module below serial.js
const SerialPort = require('serialport');
const ReadLine = require('#serialport/parser-readline');
const _d = String.fromCharCode(13); //char EOL
let myPort = null;
let myParser = null;
function connect(port, baud) {
let portName = port || `COM1`;
let baudRate = baud || 115200;
myPort = new SerialPort(portName, {baudRate: baudRate})
myParser = myPort.pipe(new ReadLine({ delimiter: '\n'}))
//Handlers
myPort.on('open', () => {
console.log(`port ${portName} open`)
});
myParser.on('data', (data) => {
console.log(data)
});
myPort.on('close', () => {
console.log(`port ${portName} closed`)
});
myPort.on('error', (err) => {
console.error('port error: ' + err)
});
}
function getPorts() {
let portlist = [];
SerialPort.list((err, ports) => {
ports.forEach(port => {
portlist.push(port.comName)
});
})
return portlist;
}
function send(data) {
myPort.write(JSON.stringify(data) + _d, function (err) {
if (err) {
return console.log('Error on write: ', err.message);
}
console.log(`${data} sent`);
});
}
function close() {
myPort.close();
}
module.exports = {
connect, getPorts, send, close
}
The problem is that a module is used where a class or a factory would be appropriate. myParser cannot exist without connect being called, so it doesn't make sense to make it available as module property, it would be unavailable by default, and multiple connect calls would override it.
It can be a factory:
module.exports = function connect(port, baud) {
let portName = port || `COM1`;
let baudRate = baud || 115200;
let myPort = new SerialPort(portName, {baudRate: baudRate})
let myParser = myPort.pipe(new ReadLine({ delimiter: '\n'}))
//Handlers
myPort.on('open', () => {
console.log(`port ${portName} open`)
});
myParser.on('data', (data) => {
console.log(data)
});
myPort.on('close', () => {
console.log(`port ${portName} closed`)
});
myPort.on('error', (err) => {
console.error('port error: ' + err)
});
function getPorts() {
let portlist = [];
SerialPort.list((err, ports) => {
ports.forEach(port => {
portlist.push(port.comName)
});
})
return portlist;
}
function send(data) {
myPort.write(JSON.stringify(data) + _d, function (err) {
if (err) {
return console.log('Error on write: ', err.message);
}
console.log(`${data} sent`);
});
}
function close() {
myPort.close();
}
return {
myParser, getPorts, send, close
};
}
So it could be used like:
const serial = require('./serial');
const connection = serial(...);
connection.myParser.on('data',(data) => {
//Do something unique with data
if (dataParser.parse(data) == 0)
connection.send('Error');
});

Nodejs Require Class returning {}

So I'm creating a singleton class and when I require it from my server.js file it works fine, but when I require it from another file it returns as undefined. I'll try to post relevant code but some will have to be cut out due to work.
server.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
const config = require('config');
const FBConfigsListener = require('./server/amq_listeners/fb_configs.listener');
const FBConfigs = require('./server/models/FBConfigs');
//Api file for interacting with mongodb
const api = require('./server/routes/api.routes');
//Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
//Angular Dist output folder
app.use(express.static(path.join(__dirname, 'dist')));
//Api location
app.use('/api', api);
//Send all other requests to angular
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
//set port
var port = config.get('webserver.port');
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`Running on localhost:${port}`));
models/FBConfigs.js
var ConfigModel = require('./config');
var config = require('config');
var _ = require('lodash');
var FBConfigsListener = require('../amq_listeners/fb_configs.listener');
var AMQAdapter = require('../adapters/amq.adapter');
var uniqid = require('uniqid');
const connectionOptions = config.get('activemq.connectionOptions');
class FBConfigs {
constructor() {
console.log(config.get('environments'));
this.listener = FBConfigsListener;
this.configs = {};
this.unique_keys = ['id'];
this.update_topic = '/topic/fusebuilder.update.config.';
console.log(FBConfigsListener);
//AMQ Client
this.amq_client = AMQAdapter.getInstance(connectionOptions.host, connectionOptions.port);
}
add(key, config) {
if (!(key in this.configs)) {
this.configs[key] = new ConfigModel(this.unique_keys);
}
this.configs[key].add(config);
}
get(key) {
let configs_json = {};
if (key) {
configs_json[key] = JSON.parse(this.configs[key].toString());
} else {
for (let key in this.configs) {
configs_json[key] = JSON.parse(this.configs[key].toString());
}
}
return configs_json;
}
updateByID(key, id, input_config) {
let configs = this.configs[key].get();
for (let config of configs) {
if (input_config.id === config.id) {
this.update(key, _.merge(config, input_config));
}
}
}
//Send update to config topic
update(key, config) {
let topic = this.update_topic + key;
var update_object = {};
if (Array.isArray(config)) {
update_object[key] = [...config];
} else {
update_object[key] = [config];
}
console.log(`Sending ${key} update:${JSON.stringify(update_object)}`);
this.amq_client.sendMessage(topic, update_object);
}
copyTo(key, id, env) {
let selected_env = config.get('environments.' + env);
// let tmp_amq_client = new AMQAdapter(selected_env.host, selected_env.port);
let selected_config = this.configs[key].getByID(id);
console.log(this);
if (key === 'fuses') {
console.log('In FBConfig Copy to for fuses');
const get_fuse_topic = '/topic/fusebuilder.get_fuse';
const tran_id = uniqid();
const sendObj = { fuseName: id, tran_id };
this.amq_client.sendMessage(get_fuse_topic, sendObj);
var startTime = process.hrtime()[0];
var timeout = false;
while (!this.listener.get_copy_fuse_data(tran_id)) {
console.log('Waiting for config');
sleep(100);
if (process.hrtime()[0] - startTime > 3) {
console.log('Timed out');
timeout = true;
break;
}
}
console.log(JSON.stringify(FBConfigsListener.get_copy_fuse_data(tran_id)));
} else {
tmp_amq_client.sendMessage(this.update_topic, selected_config);
}
console.log(`Copy ${key} id:${id} to ${env}`);
}
}
module.exports = new FBConfigs();
amq_listener/fb_configs.listener.js
const config = require('config');
var AMQAdapter = require('../adapters/amq.adapter');
var FBConfigs = require('../models/FBConfigs');
**removed for work**
class FBConfigsListener {
constructor() {
this.instance;
this.copy_fuse_data = {};
//AMQ Client
this.amq_client = AMQAdapter.getInstance(connectionOptions.host, connectionOptions.port);
//Subscribe to configs
this.amq_client.subscribe(config_subscribe_topic, this.config_topic_callback.bind(this));
//Request Tables
this.amq_client.sendMessage(config_request_topic, { tables: config_tables });
//Subscribe to Copy Fuse topic
this.amq_client.subscribe(subscribe_fuse_copy_topic, this.copy_fuse_callback.bind(this));
}
config_topic_callback(err, message) {
let dest = this.amq_client.getDestination(message);
let key = this.get_key_from_topic(dest);
this.amq_client.readMessage(message, body => {
let configs = JSON.parse(body);
if (key in configs) {
for (let config of configs[key]) {
FBConfigs.add(key, config);
}
}
});
}
copy_fuse_callback(err, message) {
this.amq_client.readMessage(message, body => {
const config = JSON.parse(body);
this.copy_fuse_data[config.tran_id] = config;
});
}
//Get Key from the topic and convert using key map if needed
get_key_from_topic(topic) {
let key = topic.split('.')[topic.split('.').length - 1];
key = key in key_map ? key_map[key] : key;
return key;
}
get_copy_fuse_data(id) {
if (id in this.copy_fuse_data) {
return this.copy_fuse_data[id];
} else {
return false;
}
}
}
module.exports = new FBConfigsListener();
Error happens in FBConfigs. FBConfigsListener returns {} so all functions in there are undefined. Even if I do console.log(require('../amq_listeners/fb_configs.listener')) it prints {} But doing the same thing in server.js (with updated path) it prints the module.
Also tips on how to improve my coding style would be appreciated too.
Edit
So I found out that I have a circular dependency between these classes. How can this be fixed while allowing me to call one from the other.
I would suggest you to instantiate your dependencies firstly and store them in some object which you can pass then to your dependent classes. The structure can be
factories/services.js
/*
* Instantiates passed services and passes injector object to them
*/
module.exports = function createServices(injector, services) {
return Object.entries(services)
.reduce((aggregator, [name, serv]) => {
const name_ = camelCase(name);
aggregator.set(name_, new serv(injector));
return aggregator;
}, new Map());
};
lib/service.js
/**
* Base class for classes need any injections
*/
module.exports = class Service {
constructor(injector) {
this.injector = injector;
}
get dependencies() {
return this.injector.dependencies;
}
/*
* Background jobs can be ran here
*/
async startService() {}
/*
* Background jobs can be stopped here
*/
async stopService() {}
};
lib/injector.js
const Service = require('./service');
/*
* Contains all dependencies
*/
module.exports = class Injector {
constructor() {
this.services = new Map();
this._dependencies = {};
}
has(name) {
return this.services.has(name);
}
register(name, service) {
if (this.has(name)) {
throw new Error(`Service ${name} already exists`);
}
if (service instanceof Service === false) {
throw new Error('Argument #2 should be an instance of Service');
}
this.services.set(name, service);
this._dependencies[name] = service;
}
unregister(name) {
if (! this.has(name)) {
throw new Error(`Service ${name} not found`);
}
this.services.delete(name);
delete this._dependencies[name];
}
get dependencies() {
return { ...this._dependencies };
}
/*
* Starts all registered services
*/
async start() {
for (let service of this.services.values()) {
await service.startService();
}
}
/*
* Stops all registered services
*/
async stop() {
for (let service of this.services.values()) {
await service.stopService();
}
}
};
Then import, initialize and bind your services in the main file (don't forget to export just a class, not an object like you do it now).
server.js
const createServices = require('./factories/services.js');
const injector = require('./lib/injector');
const Injector = new injector();
const services = createServices(Injector, [require('./server/amq_listeners/fb_configs.listener'), require('./server/models/FBConfigs')]);
services.forEach((service, name) => {
Injector.register(name, service);
});
// Start services
Injector.start();
Inherit required classes to Service class and you will get an access to all dependencies there (don't forget to call super() from constructor). Like
models/FBConfigs.js
const Service = require('../lib/service');
class FBConfigs extends Service {
constructor(injector) {
super(injector);
const { FBConfigsListener } = this.dependencies;
...your code here
}
async startService() {
...run bg job or init some connection
}
async stopService() {
...stop bg job or close some connection
}
}
module.exports = FBConfigs;
Also you can pass some config object to createServices (I didn't include it here) with keys equal to service names and values containing config object and pass config to appropriate service.
It is caused by that circular dependency. You should avoid it or used very carefully.
In your case the fix is probably pretty simple, move the line var FBConfigs = require('../models/FBConfigs'); from listener at the end of the file as the last line (yes, even after the module.exports).
Edit: Actually it maybe is not enough as I checked the code more in detail. As you are not using Listener in FBConfig constructor, you can create method assignListener, remove this.listener from that constructor and call it later in server.js which will do the this.listener
Or the last solution, which is also "best practice". Do not export the instances. Export the classes only. Then in server.js create these instances after both are required.

Node Js web services with visual studio 2017

Hi I'm used to work with c#, I'm new with node js. I'm trying to create some kind of web service using Node Js. I'm using VS 2017 community with node js version 8. I have next code:
Express App1
apps.js
app.param('phone', function (request, response, next, phone) {
// ... Perform database query and
// ... Store the user object from the database in the req object
req.phone = phone;
return next();});
index.js
'use strict';
var express = require('express');
var router = express.Router();
var Utils = require("./JavaScript1");
/* GET home page. */
router.get('/', function (req, res) {
res.render('index', { title: 'Express' });});
router.get('/byPhone/:phone', function (req, res) {
var t = Utils.Phone(req.params.phone).then(value => { return value });
//At this point if i try to use await or consume by using web
//http://localhost:1337/byPhone/777777 i only get a promise ...
res.send(t);
});
module.exports = router;
JavaScript1.js
function sAdd(sPhone) {
return new Promise((resolve, reject) => { // (A)
setTimeout(() => resolve("01800" + sPhone), 5000); // (B)
});}
var utils = {
//at this point in the temp and temp2 variables only have promises
Phone:
async function (sPhone) {
var temp = await sAdd(sPhone).then(value => { return value });
var temp2 = await temp;
return temp2;
}
};
module.exports = utils;
I'm trying to consume it with the next Node Js Console App:
'use strict';
async function main()
{
console.log('Hello world');
var url = "http://localhost:1337/byPhone/777777";
request(url, function (err, response, body) {
if (err) { console.log(err); callback(true); return; }
var tt = body;
console.log(tt);
});
}
main();
i get the below answer:
(node:19492) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 1): ReferenceError: request is not defined
I forgot to answer myself in this question, but I resolved what I wanted to do at that time this way:
I created a solution with 2 projects:
c# controllers webapp
on the c# side:
[Produces("application/json")]
[Route("test/Mondb")]
public class MondbController : Controller
{
// GET: api/Mondb
[HttpGet]
public string Get()
{
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("upixTest");
var collection = database.GetCollection<BsonDocument>("contacts");
var document = collection.Find(new BsonDocument()).ToList();
return document.ToJson(new JsonWriterSettings { OutputMode = JsonOutputMode.Strict });
}
// GET: api/Mondb/5
[HttpGet("{id}", Name = "Getmdb")]
public string Get(int id)
{
var filter = Builders<BsonDocument>.Filter.Eq("phone", id.ToString());
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("upixTest");
var collection = database.GetCollection<BsonDocument>("contacts");
var document = collection.Find(filter).FirstOrDefault();
return (document==null) ? "nothing":document.ToJson(new JsonWriterSettings { OutputMode = JsonOutputMode.Strict });
}
on the other side the node js project
functions.js
thefunctions = {
add: function (a, b) { return a + b; }, // test function
mongo: function () {
var axios = require('axios');
var tresult;
return axios.get('http://localhost:55384/test/Mondb/');
}
};
module.exports = thefunctions;
then in the server.js
'use strict';
var http = require('http');
var fs = require('fs');
var url = require('url');
var port = process.env.PORT || 1337;
var thefunctions = require("./thefunctions");
var dataToShow = "";
var JSON = require('JSON');
http.createServer(function (req, res) {
var hostname = req.headers.host;
var pathname = url.parse(req.url).pathname;
var fullurl = 'http://' + hostname + pathname;
var search = url.parse(req.url).search ? url.parse(req.url).search : "";
if (pathname === "/index.html") {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('hi my friend\n');
var tout = thefunctions.mongo();
tout.then(function (response) {
res.write(JSON.stringify(response.data).toString());
res.write('\n');
res.end('\n\nThe End\n');
})
.catch(function (error) {
console.log(error);
res.write("error");
res.end('\n\nThe End\n');
});
}
else {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.write('error my friend\n');
res.end('404 isnt available');
return;
}
}
).listen(port);
this way you will consume c# wb services from node js app

Categories