How to use the npm module gs1-barcode-parser? - javascript

I want to extract the price value from the GS1 data martix QR code value using Nodejs.
Using the module
npm i gs1-barcode-parser
Tried the below throwing "parseBarcode" is not a function
const { parseBarcode } = require('gs1-barcode-parser');
let barcode = '\u001d01093393871222863922001405\u001d1522030631030006691095751410';
console.log(parseBarcode(barcode));

I would use the modded module gs1-barcode-parser-mod2
const parser = require("gs1-barcode-parser-mod2")
let barcode = ']C101040123456789011715012910ABC1233932978471131030005253922471142127649716';
console.log(parser.parseBarcode(barcode));
Unfortunately your barcode seems to be invalid. You will need to decode from UTF-8 as that would result in ∞01093393871222863922001405∞1522030631030006691095751410 even then your barcode seems to have a missing prefix, called an Application Identifier or for short, AI (]xxxxx..).
A valid barcode example is given in the code snippet above.
More info about application identifiers

So your trying to import a module to a CJS environment, but the module is written to resolve as a front end JavaScript Module.
Fortunatly the package contains a single source file, with a single IIFE function.
THIS WILL MAKE IT AN EASY FIX!
Please note though, it is only one file & one function, but the file, and the function are really big for being a single file & a single function, so big, that it wouldn't be impracticable to add them as a snippet in a Stack Overflow answer, consequently; I have created a repository, and added the source code, that works as a solution for this problem, to the repository. I have outlined the changes that one needs to make to the module, to get it to work on the backend (in the Node REPL).
The files I added to my REPO should work for your current needs though. Continue Reading
To Convert The Module you Need to do the Following...
What you need to do is convert the package single source file into a Node module, which is very easy. The file is far to long to add to a Stack Overflow answer. So what I have done, is I have added the file into a public GitHub repository located HERE.
Go to the link to the file I rewrote
The file is a module conversion of this file.
Look at both files so you can see how I made the change.
In a nutshell, the author of the module wrote it using whats called an
IIFE: Immediately Invoked Function Execution
Its a type of function that is invoked immediately. The purpose of the function is to invoke at the very start of a script being loaded. IFFE's load before anything else, which is why he was using it to load his frontend module.
 
The Entire Module is One function, and the whole thing is wrapped like the example below:
(function (){
// Function Logic Here.
})();
Basically, what I did, is I unwrapped it, and appended a module.export.BarcodeParser assignment to the function.
To reiterate: Go Get the new File (or technically its written as a CJS module) from the Repo I Created
At This Point, Just Follow the Steps Below.
Create a new Node.js project, and make sure you execute npm init to generate a properly formatted package.json file.
Test the converted module: To test the file w/ the changes JayD3V implemented: Create a file in the same directory as the barcode parser, and add the following script to it.
const BarCodeParser = require('./BarcodeParser.js');
let barcode = ']C101040123456789011715012910ABC123�39329784711�310300052539224711�42127649716';
console.log(BarCodeParser.parseBarcode(barcode));
Then execute the file using the node command.
The README.md document in the repository has much of the information I added here in it.
Here is what it looked like when I ran it:

you're using it on server-side (backend)
https://www.npmjs.com/package/gs1-barcode-parser?msclkid=bb2e3c05cf5111ecabd6ce6b8aeb965a
as its documentation says it is a library
it also says that in order to use gs1-barcode-parser you have to add it in your application (on client side / frontend) as below:
<script src="./src/BarcodeParser.js"></script>
then you can use single function provided by it (parseBarcode) as follow :
try {
var barcode = document.getElementById("barcode").value,
answer = parseBarcode(barcode);
// do something ...
} catch (e) {
alert(e);
}

Related

How do I HTTP GET a .js file and extract 'exports' variables?

I am writing a site in Laravel to complement a game written in Node. It pulls information directly from the game's .js files stored on GitHub and the plan is to use Vue to generate some nice HTML to display the data.
The .js files are of the form:
'use strict'
let x = {...};
exports.x = x;
I can import the files using a PHP request (simply using 'file') and pass them to JS with either jQuery.getScript or axios.get (so far). However, I am having real trouble coming up with a way to extract the 'x' values here under exports. If I were writing a JS app in node, I would simply do the following:
var xFile = require('xFile');
var x = xFile.x;
However, I can't figure out how to do that here as both GET methods return a string, not a JS file. JSON.parse() doesn't work, and I would like to come up with a solution that doesn't just replace the non-JSON text as I would need a reusable solution for other files. I don't suppose anybody has any ideas?
Thanks so much!
You could try something like below.
you could create the script tag dynamically and attach the script in the body and add your javascript code using innerHTML.
You call this script in your ajax response code.
let script = document.createElement('script');
script.innerHTML = 'alert("Hi")';
document.querySelector('body').appendChild(script);
I managed to figure it out! It's a little janky, but you can run a node file in PHP with the exec command. I just wrote a node file to import the file and return the useful data. This probably isn't an optimal solution, but it works for me since I'm much more confident with JS than with PHP.

Execute a file in global scope instead of returning exported object

In NodeJS I would like to simply execute a file and allow it to make modifications to the global namespace. I know that this is not the best practice, and if I was designing the project myself, I would make sure that each module exports a single variable.
I am converting a poorly structured SPA project joined by script tags into node, and I would like to do so incrementally.
Right now I have:
require('./three.js')
This is a version of threejs which simply fills a global variable named 'THREE' with the contents of the module. Since the execution of require implicitly creates a closure, a global variable is not created for me.
So what I'd like to do is just run an entire js file and allow it to create global variables.
Is there an elegant way to do this?
You are working on Single Page Application which use the node server to run. So why don't you try module.exports = so that you can see that under the name space you give.
So example
var THREE_74 = require('./three');
Now this THREE_74.HemispherLight()
you can access probably this what you doing.
And if you want to bring your application out of node than use same layout as present ( since you are converting the SPA application) and then create your index.html load the require.js file ( http://requirejs.org/docs/download.html ) into the script tag make all your file than call after this js file ( into those file do the require as you are doing now ).
then run single line server python -m SimpleHTTPServer and run on the browser simple :)
I was able to find this snippet. It isn't native in Node, but it works well as a provisional solution!
var fs = require('fs');
var vm = require('vm');
var includeInThisContext = function(path) {
var code = fs.readFileSync(path);
vm.runInThisContext(code, path);
}.bind(this);
includeInThisContext("<PATH_TO_FILE>");

How come I can't find a module in nodejs?

So I'm working off of https://github.com/mhart/react-server-example/blob/master/server.js to figure out server side rendering in React. It takes advantage of browserify.
The example is a flat folder structure cause it's just that, an example. So below here are some of my changes that are confusing me.
/server/controllers/bundles.jsx has this
browserify()
.add('./app/scripts/checkout.jsx')
.transform(literalify.configure({
'react': 'window.React',
'react-dom': 'window.ReactDOM',
}))
.bundle()
.pipe(res)
At this point I gather that even though I'm nested in a folder, browserify is working off of root. Meanwhile inside checkout.jsx I have this:
require('./app/scripts/components/checkout/layout');
When I boot up my server, it can't find the file. I also tried doing ./components/checkout/layout since that's where it's sitting in relation to checkout.jsx.
No matter what I try, my server says it can't find the layout module.
Update I added console.log for __dirname and saw /app/scripts so it makes me think require('components/checkout/layout') should hit /app/scripts/components/checkout/layout but it's still not found. I should also note that the file does do module.exports = Layout and is being required just fine in another file while being used on the server.
You need to add the file extension (.jsx).
Basically, require in node has a bunch of rules it goes through, all outlined in the docs here.
In your case, the most relevant is this part:
require(X) from module at path Y
1. If X is a core module,
a. return the core module
b. STOP
2. If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
3. LOAD_NODE_MODULES(X, dirname(Y))
4. THROW "not found"
LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text. STOP
2. If X.js is a file, load X.js as JavaScript text. STOP
3. If X.json is a file, parse X.json to a JavaScript Object. STOP
4. If X.node is a file, load X.node as binary addon. STOP
You're hitting #2, and then going to the LOAD_AS_FILE, and there's no case for jsx files by default there, so you need the extension to make it match #1.

How can I access constants in the lib/constants.js file in Meteor?

I followed the documentation to put the constants in the lib/constants.js file.
Question:
How to access these constants in my client side html and js files?
Variables in Meteor are file-scoped.
Normally a var myVar would go in the global Node context, however in Meteor it stays enclosed in the file (which makes it really useful to write more transparent code). What happens is that Meteor will wrap all files in an IIFE, scoping the variables in that function and thus effectively in the file.
To define a global variable, simply remove the var/let/const keyword and Meteor will take care to export it. You have to create functions through the same mechanism (myFunc = function myFunc() {} or myFunc = () => {}). This export will either be client-side if the code is in the client directory, or server-side if it is in the server directory, or both if it is in some other not-so-special directories.
Don't forget to follow these rules:
HTML template files are always loaded before everything else
Files beginning with main. are loaded last
Files inside any lib/ directory are loaded next
Files with deeper paths are loaded next
Files are then loaded in alphabetical order of the entire path
Now you may run into an issue server-side if you try to access this global variable immediately, but Meteor hasn't yet instantiated it because it hasn't run over the file defining the variable. So you have to fight with files and folder names, or maybe try to trick Meteor.startup() (good luck with that). This means less readable, fragile location-dependant code. One of your colleague moves a file and your application breaks.
Or maybe you just don't want to have to go back to the documentation each time you add a file to run a five-step process to know where to place this file and how to name it.
There is two solutions to this problem as of Meteor 1.3:
1. ES6 modules
Meteor 1.3 (currently in beta) allows you to use modules in your application by using the modules package (meteor add modules or api.use('modules')).
Modules go a long way, here is a simple example taken directly from the link above:
File: a.js (loaded first with traditional load order rules):
import {bThing} from './b.js';
// bThing is now usable here
File: b.js (loaded second with traditional load order rules):
export const bThing = 'my constant';
Meteor 1.3 will take care of loading the b.js file before a.js since it's been explicitly told so.
2. Packages
The last option to declare global variables is to create a package.
meteor create --package global_constants
Each variable declared without the var keyword is exported to the whole package. It means that you can create your variables in their own files, finely grain the load order with api.addFiles, control if they should go to the client, the server, or both. It also allows you to api.use these variables in other packages.
This means clear, reusable code. Do you want to add a constant? Either do it in one of the already created file or create one and api.addFiles it.
You can read more about package management in the doc.
Here's a quote from "Structuring your application":
This [using packages] is the ultimate in code separation, modularity, and reusability. If you put the code for each feature in a separate package, the code for one feature won't be able to access the code for the other feature except through exports, making every dependency explicit. This also allows for the easiest independent testing of features. You can also publish the packages and use them in multiple apps with meteor add.
It's amazing to combine the two approaches with Meteor 1.3. Modules are way easier and lighter to write than packages since using them is one export line and as many imports as needed rather than the whole package creation procedure, but not as dumb-error-proof (forgot to write the import line at top of file) as packages.
A good bet would be to use modules first, then switch to a package as soon as they're tiring to write or if an error happened because of it (miswritten the import, ...).
Just make sure to avoid relying on traditional load order if you're doing anything bigger than a POC.
You will need to make them global variables in order for other files to see them.
JavaScript
/lib/constants.js
THE_ANSWER = 42; // note the lack of var
/client/some-other-file.js
console.log(THE_ANSWER);
CoffeeScript
/lib/constants.coffee
#THE_ANSWER = 42
/client/some-other-file.coffee
console.log THE_ANSWER

How to combine node.js modules/source into one .js file, to execute inside node

I have a need where I need to execute node code/modules in a node app (in a sandbox) with vm.createScript / script.runInNewContext. The host node app runs on heroku, so there is no local filesystem to speak of. I am able to download and run code that has no outside dependencies just fine, however the requirement is to be able to include other node modules as well. (as a build/packaging step would be ideal)
There are many existing solutions (browserify is one I've spent the most time with) which get close... but they inevitably generate a single blob of code (yeah!), meant to execute in a browser (boo!). Browserify for example generates dependencies on window., etc.
Does anyone know of a tool that will either read a package.json dependencies{} (or look at all require()'s in the source) and generate a single monolithic blob suitable for node's runInNewContext?
I don't think the solution you're looking for is the right solution. Basically you want to grab a bunch of require('lib')'s, mush them together into a single Javascript context, serialize that context into source code, then pass that serialized form into the runInNewContext function to deserialize and rebuild into a Javascript context, then deserialize your custom, sandboxed code, and finally run the whole thing.
Wouldn't it make much more sense to just create a context Object that includes the needed require('lib')'s and pass that object directly into your VM? Based on code from the documentation:
var vm = require('vm'),
initSandbox = {
async: require('async'),
http: require('http')
},
context = vm.createContext(initSandbox);
vm.runInContext("async.forEach([0, 1, 2], function(element) { console.log(element); });", context);
Now you have the required libraries accessible via the context without going through a costly serialization/deserialization process.

Categories