I have a website where the jQuery.LiveAddress plugin is implemented, but it was deprecated and then totally removed by SmartyStreets in 2014.
https://www.smartystreets.com/archive/jquery-plugin/website/configure
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="//d79i1fxsrar4t.cloudfront.net/jquery.liveaddress/5.2/jquery.liveaddress.min.js"></script>
<script>var liveaddress = $.LiveAddress({
key: "YOUR_WEBSITE_KEY_HERE",
debug: true,
target: "US|INTERNATIONAL",
addresses: [{
address1: '#street-address',
locality: '#city',
administrative_area: '#state',
postal_code: '#zip',
country: '#country'
}]
});
</script>
There is now a JavaScript SDK: https://www.smartystreets.com/docs/sdk/javascript
const SmartyStreetsSDK = require("smartystreets-javascript-sdk");
const SmartyStreetsCore = SmartyStreetsSDK.core;
const Lookup = SmartyStreetsSDK.usStreet.Lookup;
// for Server-to-server requests, use this code:
// let authId = process.env.SMARTY_AUTH_ID;
// let authToken = process.env.SMARTY_AUTH_TOKEN;
// const credentials = new SmartyStreetsCore.StaticCredentials(authId, authToken);
// for client-side requests (browser/mobile), use this code:
let key = process.env.SMARTY_WEBSITE_KEY;
const credentials = new SmartyStreetsCore.SharedCredentials(key);
It says "for client-side requests (browser/mobile), use this code", but am I correct in assuming that it is not possible to get this code working as browser JavaScript? Wouldn't I need to be running node as a service on my server to be using this code?
The client-side code example can be used in the browser, not just in node. You will need to store your website key in a different way since the browser doesn't have access to process.env. You can store the website key in plaintext here since it will be tied to your hostname.
You will need to be using some kind of library or JS bundler to process the require statement you see on line 1. You can also import the SDK if that's what works better for your setup, for example
import SmartyStreetsSDK from "smartystreets-javascript-sdk"
Something to keep in mind with using the SDK vs the jQuery plugin is that the SDK does not provide and UI elements on the page. It's less of a drop in solution than the jQuery plugin is. You will need to design and create your own UI elements for the user to interact with.
disclaimer: I work for Smarty (formerly SmartyStreets)
I came across this same issue and unfortunately smarty streets decided to make it more difficult for users to implement their product.
Upon my search I came across this fiddle, it doesn't have all of the features the jquery plugin did but it is a good place to start that doesn't require building your own suggestion UI.
<script async src="//jsfiddle.net/smartystreets/uptgh7c8/embed/"></script>
jsfiddle source
The key file that I was missing was the browserify.js file in the SmartyStreets JavaScript SDK.
Run npm install smartystreets-javascript-sdk --save-dev in your project's root directory
Change directory to node_modules/smartystreets-javascript-sdk
Run npm install in this directory
Run rm -rf dist && node browserify.js (script will fail if the dist folder exists)
Copy dist/smartystreets-sdk-1...min.js to a dependencies folder for your main project.
I tried to write a grunt task to take the SmartyStreets SDK and automatically update it, browserify it, and deploy it along with the rest of our website, but it turned out to be too much of a hassle with the time constraints given. If anyone else writes a grunt task for this please share!
Related
I'm currently pulling hairs trying to figure out how to go about this.
So, I'm working in a vanilla JS environment with no webpack setup served with capacitor and want to use this capacitor-plugin: https://github.com/CodetrixStudio/CapacitorGoogleAuth
However, to use this plugin I have to import the package into my client code.
Here's what I've tried:
Unpkg type="module": however browser support in mobile isn't that great. And this app will be served to a ton of users
Using browserify + esmify to bundle the plugins code into something I could import with a <script> tag into my index.html. Didn't work
My last thought is to setup webpack to bundle everything for me, similar to the browserify approach and import that. However before I go through with all of that I wanted to reach out here to see if you guys had any other ideas.
Is there a way to access this plugin from window maybe?
so I figured out the way to go about this by following this article: https://medium.com/#SmileFX/a-complete-guide-building-a-capacitorjs-application-using-pure-javascript-and-webpack-37d00f11720d
Basically you have a www/js directory (vanilla js), and a src directory (ES6/import code goes). You then configure webpack to output in your www/js/ directory.
Note: Any variable you want accessible to your vanilla js code must be explicitly stored in the window object.
Example
./src/toBeWebpacked.js
import Module from "your-module"
window.doSomething = () => Module.doSomething()
./www/js/vanilla.js
const useModuleCode = () => {
// use code from webpacked ES6 JavaScript here
return window.doSomething();
}
I am writing a Client / Server application with the front end UI based in React. As a back-end Unix developer web technologies are not my forte so this is all new to me.
I need to be able to configure the UI to point to the server's URL and also to set other preferences. The typical react approach seems to be to use .env environment variables. However, as per this link:
multiple-environments-with-react
'the “environment variables” will be baked in at build time'. This does not work for me as the application is an OEM offering to be sold to customers who would configure it themselves for their own environment. I do not know their server URLS at build time so I need a way that I can deliver the pre-built (minified / linted, etc) JS to them in a single archive and let them edit some sort of properties file to configure it for their needs.
What would the general JavaScript / React best practice be for this sort of use case?
Thanks,
Troy
The easiest solution for me turned out to be to include a tag in my index.html. This gets minified during the NPM build but it does not get bundled with the other javascript so it can easily be replaced with another file at deploy time. My config.js looks like this:
config = {
"title": "Application Title",
"envName": "LocalDev",
"URL": "localhost:8090"
}
Then inside my react components they're accessible by using:
const config = window.config;
alert("Application branding title is: " + config.title);
I will now have various config.js files for each environment (config.js.dev, config.js.uat, config.js.prod, etc) and at deployment I will link or renmae the appropriate one to config.js.
I am trying to use string similarity inside Google App Script, however it is not entirely clear to me how to get it working inside App Script, I get multiple errors, such as "require" is not defined, as another note, the module itself appears to have a dependency.
My final goal is to use this script to match string score between one array with strings full of typos to one with correct strings all within App Script. This is my failed code.
function matchEmails() { var doc =
SpreadsheetApp.openById(("ID"));
var ts = doc.getSheetByName("dir"); var source =
doc.getSheetByName("data"); var names =
source.getDataRange().getValues(); var data =
ts.getDataRange().getValues(); var arr = []; var arr2 = []; var
arr3 = []; var arr4 = [];
for (i=0; i<names.length; i++) {
for (j=0; j<data.length; j++) {
stringSimilarity.compareTwoStrings(names[i][0], data[j][0]); Logger.log(stringSimilarity);
/*
var n = data[j][0].split();
for (N=0; N<n.length; N++) {
arr2.push(n[N].charAt(0));
}
var string2 = arr2.join("");
var arr2 = [];
if (names[i][0] === data[j][0]) {
arr.push([data[j][1]]);
} */ //I want to replace this blanked out code with String >similarity.
if (string === string2) {
arr.push([data[j][1]]);
arr3.push([i+1]);
arr4.push([data[j][0]]);
}
} } for (i = 0; i<arr.length; i++) {
source.getRange(arr3[i],6).setValue(arr[i]);
source.getRange(arr3[i],7).setValue(arr4[i]); } }
Your GAS project is not a Node.js app, so the above will not work. While both Google Apps Script and Node use JavaScript, they provide different runtime environments for executing JS code. In GAS, the environment is a closed ecosystem on Google Servers that end users don't know anything about.
In Node, the runtime consists of V8 (JS engine) and C++ add-ons that expose low-level APIs (access to the file system, etc.). The library you referenced is an NPM package created for Node.js. Installing the package via NPM will make it available for Node projects, but don't think it will magically appear on Google servers as well.
You must either use GAS-specific versions of these dependencies, or, if they don't exist, refactor the source code to make it compatible with GAS (Node and GAS use different ECMAScript versions, so some latest features like arrow functions will break your GAS code).
For example, here's lodash for GAS
https://github.com/contributorpw/lodashgs
Using libraries in GAS
https://developers.google.com/apps-script/guides/libraries
P.S. In GAS, all ".gs" files share the same namespace, so calling 'require' function is redundant. If you want to mimic this behavior, you'll still need to write your own require function.
I wrote up some guidance on packaging up an npm module for usage in Apps Script in this article.
tl;dr is to create an index.js with the following in a new directory:
import {compareTwoStrings, findBestMatch} from 'string-similarity';
export {compareTwoStrings, findBestMatch};
and then run the following in that directory:
npm init -y
npm install --save-dev string-similarity
npx esbuild index.js --bundle --global-name=stringSimilarity --outfile=StringSimilarity.js
You can then copy the contents of StringSimiliarity.js into a new .gs file in the Apps Script editor. The exported functions will be usable from your own Code.gs as stringSimilarity. compareTwoStrings() and stringSimilarity.findBestMatch().
(In case you'd rather not bundle it yourself, the output of the esbuild process for string-similarity can be found in this gist. But the general steps should apply to most npm modules that don't require a Node or browser-specific runtime environment.)
Google Apps Script files by default have access to Google APIs, such as the Spreadsheet Service in the G Suite Services:
https://developers.google.com/apps-script/reference/spreadsheet/
A GAS project (so scripts in that project) doesn't by default have access to Node.js or any other frameworks. However, a GAS project can include another GAS project by reference as a library. In the GAS Script Editor, use menu Resources > Libraries... to add an external GAS project as a library by setting the source project's project key (and some other source project properties).
So if you have a Javascript that depends on external resources (like Node.js) by require then if you can find an external GAS project that provides the same services with the same API you can provide it as a library to the script. You omit the require statements from the original script as they're replaced by the GAS library dependency configuration I mentioned.
If your original script and its dependencies are all open source you could create GAS projects for each level of dependencies in the originals. You can already find some popular JS frameworks scripts available as GAS libraries.
GAS also allows packaging external resources as Web apps and other package formats. They can be used with corresponding techniques, and some of them found already available from other developers.
Building upon the answer of Jeff Posnick, note we can use https://esbuild.github.io in the same simple way to bring a complete library into Google Apps Script. For example with Ramda :
npm init -y
npm install --save-dev ramda
cp ./node_modules/ramda/dist/ramda.js .
npx esbuild ramda.js --minify --bundle --global-name=R --outfile=R.js
Then copy the contents of R.js into a new .gs file in the Apps Script editor.
Now you can use ramda in your code, for example:
const seventeen = R.add(7)(10);
An easy workaround is to use JavaScript's Eval function to call an external library hosted online
i. e. eval(UrlFetchApp.fetch('http://path.to/external/javascript.js').getContentText());
This won't work if the library itself depends on other modules which aren't available in the GAS runtime, but for certain libraries it can be a simple solution.
I got an meteor app. On clientside I got a heavy calculation which freezes the whole tab in the browser while executing.
So I want to use Web Workers to avoid freezing and to handle the process better (terminating, loading informations percentages etc).
For getting the web workers to work I had to include a selfwritten webworker.js in my package.js.
So my main question is: How do I set up web workers in a meteor app (clientside)?
First I tried following things:
Add a file via api.addFile() with bare option.
Package.describe({
name: 'some:name',
version: '0.0.1',
// Brief, one-line summary of the package.
summary: 'Generates PDFs',
// URL to the Git repository containing the source code for this package.
git: '',
// By default, Meteor will default to using README.md for documentation.
// To avoid submitting documentation, set this field to null.
documentation: 'README.md'
});
Package.onUse(function(api) {
api.versionsFrom('1.1.0.2');
api.use(['mrt:redis#0.1.3'],
'server',
{weak: false, unordered: false}
);
api.addFiles([
"vendor/FileSaver.js",
"vendor/jspdf.debug.js",
"dcPDF.js"
],["client"]);
api.addFiles([
"server.js"
],["server"]);
api.addFiles(["pdfProgressWorker.js"],["client"], {bare: true});
api.export('DCPDF');
});
Meteor compresses all files in packages. To set up the workers right, I have to deploy the webworker.js as own js-file on clientside. The bare option seems not to work for this case. My js-files cannot call my webworker.js if I include the file in that way.
Second try:
I added my webworker.js to the /public folder.
Problem here: my webworker.js uses some external libaries which I already included in my own package. If I add the webworker.js to the public folder, I have to add all my external js-libaries too, which are all loaded on every site in my meteor app, which slows my whole application down. Not intended, not maintainable, not meteor-style (I think).
I want to have a strongloop example only using javascript without angular.
There's no complete working example without angular for now.
I want to simply include the browser.bundle.js in my index.html, then sync data from/to server side. In fact, I'm trying to replace pouchdb in my program since the couchdb seems not success in open source community.
I can't follow up this document correctly:
Running Loopback in the browser
create browser-app.js with the content from Running Loopback in the browser
copy past the content to browser-app.js
npm install loopback loopback-boot
browserify browser-app.js -o app.bundle.js Then I got error: Error: Cannot find module 'loopback-boot#instructions' from '/Users/simba/Projects/traveller-app/client/node_modules/loopback-boot'
There are few steps for this but its pretty simple.
Bootstrap your application via slc loopback.
Delete server/boot/root.js.
Uncomment two lines in server/server.js, it should look like:
...
// -- Mount static files here--
// All static middleware should be registered at the end, as all requests
// passing the static middleware are hitting the file system
// Example:
var path = require('path'); //this line is now uncommented
app.use(loopback.static(path.resolve(__dirname, '../client'))); //this line is now uncommented
...
Create index.html in the client dir (ie. client/index.html) with your contents.
That should get you a basic set up with just a basic front-end working. Let me know if you have any more issues.