how to use require function in js - javascript

I get properly credit card info upon input done I called a function to validate credit card with luhn module ( npm install luhn) as I use :
var luhn = require("luhn");
is_valid = luhn.validate(card); // should respond true.
if (!is_valid) {
console.log("Not a valid credit card");
}
return;`
Uncaught ReferenceError: require is not defined
I am sorry If this is simple question but since I could not find a logic short solution for npm packed usage. onsubmit I call this time kkTahsil() function.
function kkTahsil() {
datalariAl();
var Iyzipay = require('iyzipay');
var iyzipay = new window.Iyzipay({
apiKey: 'sandbox-PZ8jicWrEeE1rt1O75FTOegr5lsW3xxx',
secretKey: 'sandbox-2Q6aaP1FK3HFrXkTsHfftxfiudFMfxxx',
uri: 'https://sandbox-api.iyzipay.com'
});
var nameOnCard = document.getElementById('name-on-card').value;
var expireMonth = document.getElementById('card-exp-month').value;
var expireYear = document.getElementById('card-exp-year').value;
var cvc= document.getElementById('card-cvv').value;
again same error.
so in js, there must be easy way to use npm modules. But I could not found yet.
Please I need a help.

require is not available in the browser. It is used in Node.js.
If you want to use require on the client side then use Browserify:
Browserify lets you require('modules') in the browser by bundling up all of your dependencies.
In fact, require couldn't be available in the browser in the form as it is implemented in Node. The problem with require is that it is synchronous. It works on the server side on the first tick of the event loop when you can block on I/O because no event listeners are bound yet, but it will not work in the browser without problems because it would have to block the UI for the entire time that the modules are downloaded, compiled and run.
In fact synchronous vs asynchronous module loading has been a matter of controversy. See those answers for more details:
Exporting Node module from promise result
javascript - Why is there a spec for sync and async modules?

Related

Running Raygun.io with Angular Universal

I'm adding Raygun.io APM to our Angular 8 app with Angular Universal.
It is known that raygun.io has a client side javascript library and to add this to a Angular with Universal, DOM window API must be created. This can be done using domino npm using this code below:
There is also an installation guide for Angular via npm called raygun4js however the problem still exists.
// Domino for defining Windows API in SSR
(found # https://www.npmjs.com/package/domino )
const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(index.html).toString();
const win = domino.createWindow(template);
global['window'] = win; // will be used for NodeJS to read Window API
global['document'] = win.document;
*domino creates a window api and sets it to a global called win.
After adding this line to an NPM project server.ts, build and run command - an exception is found:
Raygun.Utilities = raygunUtilityFactory(window, Raygun);
^
ReferenceError: raygunUtilityFactory is not defined
This roots that a raygunUtilityFactory function is not defined within window API. Looking inside raygun.js in Github
window.raygunUtilityFactory = function(window, Raygun) {
var rg = {
getUuid: function() {
function _p8(s) {
var p = (Math.random().toString(16) + '000000000').substr(2, 8);
return s ? '-' + p.substr(0, 4) + '-' + p.substr(4, 4) : p;
}
// more code.....
Question is, how can NodeJS read raygunUtilityFactory function during build if it can't find it in window API?
UPDATE: I tried to do this on a smaller project but it seems that even its document for installing raygun.io doesn't include procedures for Angular Universal. It basically can't detect window API using domino
Raygun.Utilities = raygunUtilityFactory(window, Raygun);
^
ReferenceError: raygunUtilityFactory is not defined
Answer: Setting Raygun js as a global object and referencing it to a declared variable inside a service.
Reference: https://hackernoon.com/how-to-use-javascript-libraries-in-angular-2-apps-ff274ba601af
declare var rg4js: any;
*place this inside your service or your main component ts.
<script type="text/javascript">
!function(a,b,c,d,e,f,g,h){a.RaygunObject=e,a[e]=a[e]||function(){
(a[e].o=a[e].o||[]).push(arguments)},f=b.createElement(c),g=b.getElementsByTagName(c)[0],
f.async=1,f.src=d,g.parentNode.insertBefore(f,g),h=a.onerror,a.onerror=function(b,c,d,f,g){
h&&h(b,c,d,f,g),g||(g=new Error(b)),a[e].q=a[e].q||[],a[e].q.push({
e:g})}}(window,document,"script","//cdn.raygun.io/raygun4js/raygun.min.js","rg4js");
</script>
*add this to your index.html or download and add it to your project.
Do take note that the raygun script should be referenced as rg4js.
Angular will automatically know that the rg4js inside your TS file is reference to your raygun script tag.
-- I'm now able to see the crash reporting and the pulse monitoring inside our client dashboard. However, I noticed that all client side errors logs are not caught. I'm still researching way to send these unhandled errors - starting with windows.onerror.
Good to hear you have figured out part of the solution!
AngularJS captures a lot of errors under the hood automatically and to properly capture errors you will need to register your own angular error handler and when the callback is fired you can use the Raygun4JS send method to send the message to Raygun.
export class RaygunErrorHandler implements ErrorHandler {
handleError(e: any) {
rg4js('send', {
error: e,
});
}
}
Raygun has a little bit of angular documentation but can't import raygun4js via npm for Angular Universal (as per your discovery) so you will need to modify the examples shown. That said they should provide a good starting point.

Attempting to Import Module in Child Process (Javascript) and Failing

I'm currently running a heavy computation (i.e. generating a Monte Carlo tree), which is an expensive operation. I only have a few seconds to build as big of a tree as I can, so I am using subprocesses in Node.js in order to build multiple trees, and then aggregate their data together to make a more informed decision.
I understand that subprocesses do not share information/memory, and I need to use modules within these subprocesses that are located in a file, called "Epilog.js" on my machine.
When I run functions that are in epilog.js from the main file, it works just fine. But all of my functions that are in my worker threads return absolutely nothing.
I have tested to make sure that the parameters of the functions I am trying to use in "epilog.js" aren't empty, and they're not. The problem isn't in the parameter.
I have also tested to see what happens if I simply don't import, and instead of just outputting an undefined array, I get an error saying that there is no function called "findroles".
//My main thread.
var fs = require('fs');
eval(fs.readFileSync('epilog.js') + '');
var process = fork('./buildGraph.js');
process.send({library});
//My worker thread.
//buildGraph.js
var fs = require('fs');
eval(fs.readFileSync('epilog.js') + '');
// receive message from master process
process.on('message', async(message) => {
library = message["library"];
console.log(findroles(library));
// findroles(library) is a function that is defined in epilog.js,
//and this outputs an array of "roles" given a parameter,library.
// For some reason this function outputs [], rather than giving me
// all of the roles. If I run this exact line from my main thread,
// it doesn't give any errors and outputs the right array:
// e.g. ['red', 'white'].
});
I expect to get not the empty array, but [red, white], as I do if I were to run the same line in the main thread. Does anyone have an idea as to the inconsistency of the functions? I'm very new to node.js and this isn't a class focused too much on software engineering in JavaScript, so I'd appreciate if someone can dumb down what is going on, as this is all very new to me.
If your script does not find the function called findroles then there is a problem with the importing method. Using the eval function for importing is not the normal way of importing modules. Try something like this:
// buildGraph.js
const epilog = require("./epilog.js");
......
console.log(epilog.findroles(library));
then epilog.js
exports.findroles = function (library) {
// function content
}
You can find more info here:
https://www.w3schools.com/nodejs/nodejs_modules.asp
Base on the document and example here, everything seem correct but I think the problem come from this line:
var process = fork('./buildGraph.js');
you might override the original process.
try to change it to
const n = fork('./buildGraph.js');

Unit tests in JavaScript with mocked objects

So I'm working with an enterprise tool where we have javascript scripts embedded throughout. These scripts have access to certain built-in objects.
Unfortunately, the tool doesn't give any good way to unit test these scripts. So my thinking was to maintain the scripts in a repo, mock the built-in objects, and then set up unit tests that run on my system.
I'm pretty ignorant to how JavaScript works in terms of building, class loading, etc. but I've been just trying things and seeing what works. I started by trying out Mocha by making it a node project (even though it's just a directory full of scripts, not a real node project). The default test works, but when I try and test functions from my code, I get compiler errors.
Here's what a sample script from my project looks like. I'm hoping to test the functions, not the entire script:
var thing = builtInObject.foo();
doStuff(thing);
doMoreStuff(thing);
function doStuff(thing) {
// Code
}
function doMoreStuff(thing) {
// More Code
}
Here's what a test file looks like:
var assert = require('assert');
var sampleScript = require('../scripts/sampleScript.js');
describe('SampleScript', function() {
describe('#doStuff()', function() {
it('should do stuff', function() {
assert.equal(-1, sampleScript.doStuff("input"));
});
});
});
Problem happens when I import ("require") the script. I get compilation errors, because it doesn't builtInObject. Is there any way I can "inject" those built in objects with mocks? So I define variables and functions that those objects contain, and the compiler knows what they are?
I'm open to alternative frameworks or ideas. Sorry for my ignorance, I'm not really a javascript guy. And I know this is a bit hacky, but it seems like the best option since I'm not getting out of the enterprise tool.
So if I get it right you want to do the unit tests for the frontened file in the Node.js environment.
There are some complications.
First, in terms of Node.js each file has it's own scope so the variables defined inside of the file won't be accessible even if you required the file. So you need to export the vars to use them.
module.exports.doStuff = doStuff; //in the end of sample script
Second, you you start using things like require/module.exports on the frontend they'll be undefined so you'll get an error.
The easiest way to run your code would be. Inside the sample script:
var isNode = typeof module !== 'undefined' && module.exports;
if (isNode) {
//So we are exporting only when we are running in Node env.
//After this doStuff and doMoreStuff will be avail. in the test
module.exports.doStuff = doStuff;
module.exports.doMoreStuff = doMoreStuff;
}
What for the builtInObject. The easies way to mock it would be inside the test before the require do the following:
global.builtInObject = {
foo: function () { return 'thing'; }
};
The test just passed for me. See the sources.
Global variables are not good anyway. But in this case seems you cannot avoid using them.
Or you can avoid using Node.js by configuring something like Karma. It physically launches browser and runs the tests in it. :)

Include libraries in Protractor test case

I would like to include a module/library in a protractor test case, however, as soon as I add the line
var lib = require('./loginactions.js');
All the references to protractor and related objects are lost. In other words, if I don't have the require line, the 'protractor' and 'browser' variables are found and test runs fine (using the functions within the file), but after adding that line the variables are not found any more.
Here is a minimal test case:
var lib = require('./loginactions.js'); //problematic line
describe('Login / Logout to Application',function(){
var ptor;
beforeEach(function(){
ptor = protractor.getInstance(); //protractor reference lost
browser.get('http://localhost:80'); //browser reference lost
});
it('should login and then logout successfully', function(){
//Do things here
lib.login(user, pass, ptor);
});
});
I export the functions in this way:
module.exports.Login = Login;
module.exports.Logout = Logout;
//Params: ptor - protractor instance
function Login(user, pass, ptor)
{
//stuff
}
function Logout(ptor)
{
//stuff
}
I also wonder, is this even the correct way of including the own libraries into the project. So my question is, how to properly include libraries into a protractor test case?
To answer my own question, using protractor as a library method worked, this way the references to protractor were restored. So adding these two requires solved my issue:
var protractor = require('/path/to/protractor');
require('/path/to/protractor/jasminewd');
So my test looked similar to the updated code in
'no method expect' when using Protractor as a library question.
However, I am not entirely sure about the global browser object. It is a wrapper around the WebDriver object according to http://www.ng-newsletter.com/posts/practical-protractor.html, but so is protractor instance. So I decided to replace all 'browser' variables with 'ptor' and so far no complaints. This may backfire, but as I said, I'm not entirely sure whether the global browser object that is created along with the global protractor object, when running protractor normally and not as library.

Make Closure Compiler strip log function usages

I have a logging API I want to expose to some internal JS code. I want to be able to use this API to log, but only when I am making a debug build. Right now, I have it partially working. It only logs on debug builds, but the calls to this API are still in the code when there is a regular build. I would like the closure-compiler to remove this essentially dead code when I compiler with goog.DEBUG = false.
Log definition:
goog.provide('com.foo.android.Log');
com.foo.Log.e = function(message){
goog.DEBUG && AndroidLog.e(message);
}
goog.export(com.foo.Log, "e", com.foo.Log.e);
AndroidLog is a Java object provided to the webview this will run in, and properly externed like this:
var AndroidLog = {};
/**
* Log out to the error console
*
* #param {string} message The message to log
*/
AndroidLog.e = function(message) {};
Then, in my code, I can use:
com.foo.Log.e("Hello!"); // I want these stripped in production builds
My question is this: How can I provide this API, use this API all over my code, but then have any calls to this API removed when not compiled with goog.DEBUG = true? Right now, my code base is getting bloated with a bunch of calls to the Log API that are never called. I want the removed.
Thanks!
The Closure Compiler provides four options in CompilerOptions.java to strip code: 1) stripTypes, 2) stripNameSuffixes, 3) stripNamePrefixes and 4) stripTypePrefixes. The Closure build tool plovr, exposes stripNameSuffixes and stripTypePrefixes through its JSON configuration file options name-suffixes-to-strip and type-prefixes-to-strip.
There are excellent examples of how these options work in Closure: The Definitive Guide on pages 442 to 444. The following lines are provided as common use cases:
options.stripTypePrefixes = ImmutableSet.of(“goog.debug”, “goog.asserts”);
options.stripNameSuffixes = ImmutableSet.of(“logger”, “logger_”);
To understand the nuances of these options and avoid potential pitfalls, I highly recommend reading the complete examples in Closure: The Definitive Guide.
Instead of running your own script as jfriend00 suggested I would look at the define api of the compiler (which is where goog.DEBUG comes from as well), you have DEBUG, COMPILED by default, but there you can roll your own.
OK, it turns out this is easy to do if I stop exporting com.foo.Log() and its methods. If I really want to be able to log in some specific cases, but still strip out the log calls in my internal code, I can just declare two classes for this:
// This will get inlined and stripped, since its not exported.
goog.provide('com.foo.android.Log');
com.foo.Log.e = function(message){
goog.DEBUG && AndroidLog.e(message);
}
// Don't export.
// This be available to use after closure compiler runs, since it's exported.
goog.provide('com.foo.android.production.Log');
goog.exportSymbol("ProductionLog", com.foo.android.production.Log);
com.foo.android.production.Log.log = function(message){
goog.DEBUG && AndroidLog.e(message);
}
// Export.
goog.exportProperty(com.foo.android.production.Log, "log", com.foo.android.production.Log.log);
I have modified a compiler and packaged it as an npm package.
You can get it here: https://github.com/thanpolas/superstartup-closure-compiler#readme
It will strip all logging messages during compilation

Categories