Generating a random string in browser - javascript

I need to generate a random, two-word identifier field for each Mongo doc I'm inserting via Node.
I found random-words, an NPM module. It's great, except that I can only generate the random string server-side. When I try to use it in the client code, the function randomWords() comes back as undefined.
Here's my relevant server code (I took out the error handlers for the sake of brevity):
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
// random words
var randomWords = require('random-words');
// Database
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/test');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// Make the db accessible to our router
app.use(function(req,res,next){
req.db = db;
next();
});
app.use('/', routes);
app.use('/users', users);
module.exports = app;
And here's my server stuff (my global js file, not the route - though it doesn't work in either):
// DOM Ready =============================================================
$(document).ready(function() {
var ident = randomWords(2);
// Add User button click
$('#button').on('click', addUser); //addUser is a function in this doc
});
Any idea what I'm doing wrong here? I'm exporting the module and I'm able to access other stuff from the server-side code (like the database), I just don't know where I'm messing it up.

I solved this using vmkcom's suggestion above. I'm posting for others who might benefit from it because I had a really hard time diagnosing this problem and figuring out how to solve it. NOTE: This is a hacky fix that I suspect isn't recommended (but it works in this instance because, as vmkcom pointed out, the index.js file is pretty simple), so if you have a more elegant solution, please feel free to respond below.
Node modules, as helpfully pointed out above, are not automatically accessible to your browser. However you can make them so with Browserify, which is, in theory, great. But, when I ran Browserify, it didn't work and when I got it to run it only caused more errors.
What I did instead was take the index.js file from the random-words github (located here), renamed it random.js, and included it in my public /javascripts folder. I then linked to it in my layout.jade template file like this:
body
block content
script(src='http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js')
script(src='/javascripts/global.js')
script(src='/javascripts/random.js')
It isn't ideal, but it does work. As I said this is quick and dirty at its quickest and dirtiest, so if you have a better way, please share.

if you are using it in server side for env file you can do it like:
export const randomString = (length: number) => {
if (process.env.SECRET_KEY === undefined)
process.env.SECRET_KEY = [...Array(length)]
.map(() => (~~(Math.random() * 36)).toString(36))
.join("");
return process.env.SECRET_KEY;
};

Just copy code of random-words module index.js into your client code and rewrite module.exports = words as window._words = words
Or use some module system at client code as require.js

Related

React | React is not rendering anything in my project [duplicate]

I want to serve index.html and /media subdirectory as static files. The index file should be served both at /index.html and / URLs.
I have
web_server.use("/media", express.static(__dirname + '/media'));
web_server.use("/", express.static(__dirname));
but the second line apparently serves the entire __dirname, including all files in it (not just index.html and media), which I don't want.
I also tried
web_server.use("/", express.static(__dirname + '/index.html'));
but accessing the base URL / then leads to a request to web_server/index.html/index.html (double index.html component), which of course fails.
Any ideas?
By the way, I could find absolutely no documentation in Express on this topic (static() + its params)... frustrating. A doc link is also welcome.
If you have this setup
/app
/public/index.html
/media
Then this should get what you wanted
var express = require('express');
//var server = express.createServer();
// express.createServer() is deprecated.
var server = express(); // better instead
server.configure(function(){
server.use('/media', express.static(__dirname + '/media'));
server.use(express.static(__dirname + '/public'));
});
server.listen(3000);
The trick is leaving this line as last fallback
server.use(express.static(__dirname + '/public'));
As for documentation, since Express uses connect middleware, I found it easier to just look at the connect source code directly.
For example this line shows that index.html is supported
https://github.com/senchalabs/connect/blob/2.3.3/lib/middleware/static.js#L140
In the newest version of express the "createServer" is deprecated. This example works for me:
var express = require('express');
var app = express();
var path = require('path');
//app.use(express.static(__dirname)); // Current directory is root
app.use(express.static(path.join(__dirname, 'public'))); // "public" off of current is root
app.listen(80);
console.log('Listening on port 80');
express.static() expects the first parameter to be a path of a directory, not a filename. I would suggest creating another subdirectory to contain your index.html and use that.
Serving static files in Express documentation, or more detailed serve-static documentation, including the default behavior of serving index.html:
By default this module will send “index.html” files in response to a request on a directory. To disable this set false or to supply a new index pass a string or an array in preferred order.
res.sendFile & express.static both will work for this
var express = require('express');
var app = express();
var path = require('path');
var public = path.join(__dirname, 'public');
// viewed at http://localhost:8080
app.get('/', function(req, res) {
res.sendFile(path.join(public, 'index.html'));
});
app.use('/', express.static(public));
app.listen(8080);
Where public is the folder in which the client side code is
As suggested by #ATOzTOA and clarified by #Vozzie, path.join takes the paths to join as arguments, the + passes a single argument to path.
const path = require('path');
const express = require('express');
const app = new express();
app.use(express.static('/media'));
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, 'media/page/', 'index.html'));
});
app.listen(4000, () => {
console.log('App listening on port 4000')
})
If you have a complicated folder structure, such as
- application
- assets
- images
- profile.jpg
- web
- server
- index.js
If you want to serve assets/images from index.js
app.use('/images', express.static(path.join(__dirname, '..', 'assets', 'images')))
To view from your browser
http://localhost:4000/images/profile.jpg
If you need more clarification comment, I'll elaborate.
use below inside your app.js
app.use(express.static('folderName'));
(folderName is folder which has files) - remember these assets are accessed direct through server path (i.e. http://localhost:3000/abc.png (where as abc.png is inside folderName folder)
npm install serve-index
var express = require('express')
var serveIndex = require('serve-index')
var path = require('path')
var serveStatic = require('serve-static')
var app = express()
var port = process.env.PORT || 3000;
/**for files */
app.use(serveStatic(path.join(__dirname, 'public')));
/**for directory */
app.use('/', express.static('public'), serveIndex('public', {'icons': true}))
// Listen
app.listen(port, function () {
console.log('listening on port:',+ port );
})
I would add something that is on the express docs, and it's sometimes misread in tutorials or others.
app.use(mountpoint, middleware)
mountpoint is a virtual path, it is not in the filesystem (even if it actually exists). The mountpoint for the middleware is the app.js folder.
Now
app.use('/static', express.static('public')`
will send files with path /static/hell/meow/a.js to /public/hell/meow/a.js
This is the error in my case when I provide links to HTML files.
before:
<link rel="stylesheet" href="/public/style.css">
After:
<link rel="stylesheet" href="/style.css">
I just removed the static directory path from the link and the error is gone. This solves my error one thing more don't forget to put this line where you are creating the server.
var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public')));
You can achieve this by just passing the second parameter express.static() method to specify index files in the folder
const express = require('express');
const app = new express();
app.use(express.static('/media'), { index: 'whatever.html' })

Can I create a locally accessible only server in lambda?

I upload a zip file, and I have the following two files:
// server.js
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const addRequestId = require('express-request-id')();
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(addRequestId);
app.listen(8000);
exports.app = 'app';
and
// main entry point for the handler
'use strict';
const server = require('./server').app;
exports.handler = function(event, context, callback) {
// Do stuff
}
As you can see, I'd like to create an internal server that I can use inside my lambda. This times out, and I get an error message:
{"errorMessage":"2017-03-09T07:52:01.439Z 45210dff-049d-11e7-84cc-8367ae894495 Task timed out after 3.00 seconds"}
The problem happens right at app.listen(8000) (i.e. if I comment this line out, then the function runs.
Can I now create a server inside my lambda?
EDIT
Please do not comment on how a lambda is intended for a short/one time operation. The question is not about a correct implementation and usage of lambda; I know you are suppose to use API Gateway for routing. Of course this is not the full example. For the sake of this equestion, I need a server to run for the 5s that I need to execute this lambda. Is this not allowed within AWS Lambda?

Serving static files in Express with mustache templating

I'm trying to serve a folder of static mustache files from Express, but can't seem to figure out how to get it working. Say I just have an object of data like
{
a: 'Hello :)'
b: 'Goodbye :('
}
And two files,
public/a.html
<div>{{a}}</div>
public/b.html
<div>{{b}}</div>
How could I get express setup to where it serves any arbitrary number of static html files and replaces the templated parts with just my one big object? Thanks!
Static files are usually only called static when they are not processed in any way before sending to user.
What you're trying to achieve is a typical templating system. You can just follow instructions in the plugin:
var mustacheExpress = require('mustache-express');
// Register '.html' extension with The Mustache Express
app.engine('html', mustacheExpress());
app.set('view engine', 'mustache');
app.set('views', __dirname + '/views'); // you can change '/views' to '/public',
// but I recommend moving your templates to a directory
// with no outside access for security reasons
app.get('/', function (req, res) {
res.render('a');
});
Also consider using Handlebars, it's often more convenient to use than Mustache. You can find a list of differences in this question.
You can use mustachejs just like pug in express by setting mustache as view engine and defining its working like below code:
//required files
const fs = require("fs")
const mustache = require("mustache")
// To set functioning of mustachejs view engine
app.engine('html', function (filePath, options, callback) {
fs.readFile(filePath, function (err, content) {
if(err)
return callback(err)
var rendered = mustache.to_html(content.toString(),options);
return callback(null, rendered)
});
});
// Setting mustachejs as view engine
app.set('views',path.join(__dirname,'views'));
app.set('view engine','html');
//rendering example for response
app.get('/',(req,res)=>{
res.render('index',{data:'Sample Data'});
});
I modify zlumer's answer a little bit and the following code works fine for me.
const express = require('express');
const app = express();
const mustacheExpress = require('mustache-express');
app.engine('html', mustacheExpress());
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
app.get('/', function(req, res) {
const data = {
hello: 'world',
foo: 'bar'
};
res.render('test', data);
});
app.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
Please check https://github.com/HemingwayLee/sample-mustache-express
and feel free to clone and modify it.
You should not include your html files in the public directory. Public Directory should contain only images, javascript and css files.
Though there are many ways to structure the node/express application, but you can find one good way using Express Generator.
http://expressjs.com/en/starter/generator.html
If you use this, it will create the app structure for you which clearly explains how you should keep you static files.

node how can My app find index.js

Folder structure
bin - www.js
lib - jsFiles...
models - jsFiles...
node_modules -Folders and Files
public - index.html
route - jsFiles...
index.js
package.json
I use Express, angular.js. Server starts at www.js and It calls
index.js. After that, When I type merely "localhost:3000" It shows me
public/index.html. I don't have route for '/' but It shows me
'public/index.html'. I can not understand this. Please let me know
about the process.
www.js
var debug = require('debug')('example-server');
var app = require(process.cwd()+'/index');
//listen at 3000 port
app.set('port',process.env.PORT || 3000);
var server = app.listen(app.get('port'),function()
{
debug('Express server listening on port ' + server.address().port);
});
index.js
var favicon = require('serve-favicon');
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//Connection for DB
require('./lib/connection');
var employees = require('./routes/employees');
var teams = require('./routes/teams');
var app = express();
// Writing at routing table
app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended:true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname,'public')));
app.use(employees);
app.use(teams);
// send 404 to errorhandler
app.use(function(err,req,res,next)
{
var err = new Error('Not Found');
err.status = 404;
console.log(error);
next(error);
});
...
...
module.exports = app;
In express.js the sequence in which you register your middleware makes a huge difference.
When express.js receives a request, it starts from top and executes registered middleware.
Middlewares are registered in express app using app.use(middleware_goes_here) this type of middleware gets executed no matter what the request url is on the other hand you can also register a middleware like app.use('/url/path',middleware_goes_here) in this case we are registering this middleware to '/url/path' so this middleware will only get executed when you visit '/url/path' (and non of the previous matching middleware serves the request without calling next() )
This app.use(express.static(path.join(__dirname,'public'))); line of code does the magic.
You can go here (express.static ref) to know more about static content serving and routing.
Basically what happens is, we are configuring express.static middleware to serve static content "as is" from "public" folder. So when you make any request and it matches a static content in public folder, then it will serve it otherwise express.static will call next middleware in sequence.
So in your case, the first middleware that actually server input request is express.static without any route filters, so it servers index.html even without a specifically defined route. If your public folder had file at public/javascript/jquery.js then following url will map to it http://localhost:3000/javascript/jquery.js
NOTE: You do not have to specify "public" in the url, the way in which express.static is registered, it will server contents FROM "public" folder.
................
UPDATE: How does default work in express.static?
By default, app.use(express.static(path.join(__dirname,'public'))); this will take index.html as default document. If you want to set index2.html as your default document, you can do that by doing something like this app.use(express.static(path.join(__dirname,'public'),{index: 'index2.html'}));
Hope it helps.
Put a relative path to folder(one up in hierarchy).
var app = require('../index');

Issue with mongodb's collection.find() when used in an express app.js file

Just a little background: I'm quite new to backend code (node js, express js) so bear with me... I'm working on building a website and a Shopify app using express js and mongodb. The website and Shopify app both need to talk to the same database (in this case I've called it tbapp). Since I've never built a Shopify app before I decided to try to follow the express js code written in this git hub repo. I noticed that this example app wasn't using a routes directory, so without thinking much of it, I decided not to use one as well, and put all of my "get" and "post" requests in my app.js file. However unlike my app, the example app isn't storing any information in a database...
Now for the actual question: I'm trying to find out if a store owner entered a matching key into their store admin– so I'm using "collection.find". This works fine when the store owner enters the correct key, however whenever they enter a key that's not in my database, the function returns an error– even though I've specified that when "collection.find" cannot find a document it should render a page with a local variable passed to it. Below is the relevant code in my app.js file. Do you think that not using an index.js file in routes is causing this problem? This is the only explanation I can think of, since I'm literally doing the same thing in my website, but the only difference is that my website code is using routes.
This is the initial code in my app.js file:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var crypto= require("crypto");
var querystring= require("querystring");
var request= require("request");
var session= require("express-session");
var mongo= require("mongodb");
var monk= require("monk");
var db= monk("localhost:27017/tbapp");
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine("html", require("ejs").__express);
//changed renderFile
app.set('view engine', 'html');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({secret: 'somethingsecret', saveUninitialized: true, resave: true}));
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req, res, next){
req.db= db;
next();
});
This is the problem code:
app.post("/enter-store-key", function(req, res) {
var db= req.db;
var key= req.body.storeKey;
var collection= db.get("businessOwners");
console.log(key);
collection.find({_id: key}, {}, function(err, doc) {
if(err) {
res.send("There was an error");
} else {
if(doc.length>0) {
res.render("widg-index", {
api_key: config.shopify_api_key,
shop: config.shop,
title: "Home",
valid_key: "yes"
});
} else {
res.render("widg-index", {
api_key: config.shopify_api_key,
shop: config.shop,
title: "Home",
valid_key: "no"
});
}
}
});
//WHEN STORE OWNER DOESN'T INPUT A CORRECT KEY I GET AN ERROR PAGE??? IF FUNCTION "FIND" CANNOT FIND A DOCUMENT WITH SPECIFIED QUERY IT RETURNS AN ERROR?? WHYYYYYY????!!
});
Thank you to anyone who helps me with this. I've been struggling for awhile now, so any and all advice would be much appreciated!
Try this :
collection.find({_id: key}).toArray(function (err, doc) {
if (err) {
console.log(err);
} else if (doc.length) {
console.log('Found:', docs);
} else {
console.log('No docs found');
}
db.close();
});
So I finally figured out what I was doing wrong... When I was testing if the key was correct or not I was using a random string of letters/numbers that wasn't 24 characters long. The thing is, with ids for mongodb they have to be 24 characters long or else the function throws an error.

Categories

Resources