Categories
Coding

Best Way to Install NodeJS on Mac OS

Once every year I make it a priority to nuke my Macbook Pro computer.

There are two reasons why I do this is to keep the apps I actually use, naturally removing the ones I no longer use, but don’t know that I no longer use them!

As I like to try new things it does mean I install lots of scripts and apps on my computer and because I might not actively remove these things from my computer when I no longer need them my computer gets bloated.

By nuking your computer frequently it helps to completely remove unused and unnecessary scripts and apps from your machine.

Keep essential files backed up in the cloud

Knowing that I nuke my computer annually it helps to be more mindful of placing essential files on the cloud. There may come a day where my computer decides it doesn’t want a human to initiate the nuke, it wants to do it itself! When that happens all essential files still stored on my computer maybe lost forever.

This then has helped to structure my thinking into what to do with files as I am working on them. For example, if I’m writing a blog post I ensure I’ve already sent it to my private BitBucket repository, or if I’m working on a spreadsheet I store this in Google Drive or OneDrive.

It’s important then to make sure you are aware of the type of document you are handling and how this can be backed up if you’d like to keep it.

Moving on to our topic today, even though I nuked my computer 1 month ago, I’ve realised today I need to install NodeJS.

The problem I have with NodeJS is having it automatically update itself. I don’t want to have to re-install the direct downloadable file from NodeJS every time there’s a patch update.

Wouldn’t it be great to install it once, and when needed, run a command for it to automatically update?

Thankfully there is such an easy process: Homebrew for Mac

So here were the steps I undertook to be able to reinstall NodeJS back on to my computer:

Check if NodeJS is already installed:

Before you install node you may want to check if you already have it installed. To check if node is already on my machine run node -v in your terminal. This simple command checks the version number of the currently installed node module on your computer.

$ node -v
bash: node: command not found

If you have node installed, you should see a version number pop up underneath your command. Great, there’s nothing more for you to do here! If though, you see the above, move on to the next step.

Do some Homebrew housekeeping first

Before installing node, let’s do a little housekeeping to make sure our computer is updated and everything is in working order.

a) Check your system has the latest updates by running the command brew update:

$ brew update
Already up-to-date

If you see Already up-to-date then you’ve got the latest updates on your machine. If not, you would have noticed a bunch of modules updated on your system.

b) Check your system is humming along well with no conflicts by running brew doctor:

$ brew doctor
Your system is ready to brew.

If you see Your system is ready to brew then your computer is ready to proceed. If not, please read through any of the instructions provided on how you can correct your modules.

Install NodeJS using Homebrew

Our final step then is to simply run the command brew install node:

$ brew install node

You should see lots of action, and to check you’ve properly installed it, re-run our first command in terminal node -v:

$ node -v
v14.2.0

Now you’re ready to use NodeJS.

Categories
Cloud Apps

How to Clone Google App Script Code to Your Local Computer

I’m starting a new project, and the requirements for this project is to write some Google App Script, copy the source code over to BitBucket. Thankfully there’s an easy way to store Google App Script locally to your computer and then push those changes back to Google as well as git commit changes and have the code stored safely on a remote repository.

Here’s how you too can set up your computer and environment up.

Install google/clasp

To install google/clasp jump onto your terminal, and if you haven’t (as I haven’t yet), initialise npm in your folder:

$ npm init
This utility will walk you through creating a package.json file.
...

After progressing through all the prompts I then run the command to install google/clasp by npm install clasp:

$ npm install clasp
Installing @google/clasp...
Installed @google/clasp@2.3.0

Your terminal prompt should inform you of the success of your google/clasp module installation.

Login to clasp

To have google/clasp know where to pull and push scripts to it needs to connect to your Gmail account. Therefore, the first command you need to run once you’ve successfully installed it is clasp login:

$ clasp login

A link then pops up underneath the prompt and when you click on it you will be redirected to a Google login screen where you will need to enter your credentials and provide the necessary permissions for the script to function properly. You will know everything is successful when you see back in your terminal window:

Authorization successful.

Clone script

If you have already started a Google App Script project you may be able to clone it to your current project. There are two ways you can try to pull in a project’s script:

  1. Try clasp clone and then select from the options presented by using your up and down arrow keys to navigate through the list.
$ clasp clone
? Clone which script? (Use arrow keys)
> ABC ...

If, however, you have many scripts, and the script you’re looking for isn’t presented you will need to exit from the prompt window using Ctrl-C.

  1. Enter the specific Script ID as a parameter to your clone command, like so:
$ clasp clone ABC123...

Where ABC123... is the Script ID you can obtain by opening up your Google App Script console for the project you’re hoping to clone and clicking on File > Project Properties. From the modal window that pops up, copy the Script ID hash.

Get Script ID for Google Clasp
Get your Script ID to easily clone a project to your computer using clasp

Ignore Files

If needed you might want to exclude certain files from clasp pushing them into your script folder in Google. If so, create a .claspignore file and populate it with files you don’t want to push up.

My .claspignore looks as follows:

.DS_Store
node_modules/**
node_modules/**/.*/**
node_modules/**/.*
.idea
.git

Update code

To update your code on the Google Server you just need to push your code back up.

$ clasp push

You can check your code is working by opening your project’s Google App Script code.

Conclusion

In this short article you’ve learned the following:

  1. How to copy a project in Google Apps to your local computer using the clasp npm package.
  2. How to exclude certain files and folders from your project.
  3. How to make local changes and push your changes up to Google Apps.

If you have your code wrapped as a library which other code references you’ll need to create a version and then reference the new version in your code dependencies.

If you’d like to discover how you can create a library for your common Google Apps code, or to prevent someone from editing your code on your Google Sheets or other Google Apps, then check out my [next post on creating a Google Apps library]({{< relref “2020-05-25-create-library-dependency-google-app-script.md” >}}).

Categories
Coding

How To Easily Install Bootstrap (2.0) in ExpressJS (3.0)

I’m certainly no expert when it comes to using ExpressJS or Bootstrap so there may be far better ways of doing this than what I detail below, however, if you do know of better ways please let me know as I bumbled my way through!

Here goes.

Prerequisites:

I’m installing this on an Ubuntu 11.10 EC2 micro box and have the following installed:

$ apt-get install node npm make zip unzip git

Process:

  1. Install via NPM the following: ExpressJS, Less & [UglifyJS]():
$ npm install -g express less uglify-js
  1. Create an ExpressJS working directory, we’ll call it testme, with Less:
$ express --css less testme
  1. Move inside your new directory:
$ cd testme
  1. Create a new directory called vendors:
~/testme$ mkdir vendors
  1. Move inside the vendors directory:
~/testme$ cd vendors
  1. Download from github Bootstrap:
~/testme/vendors$ git clone https://github.com/twitter/bootstrap.git bootstrap
  1. Move into the newly created Bootstrap directory:
~/testme/vendors$ cd bootstrap
  1. Build Bootstrap:
~/testme/vendors/bootstrap$ make -i 

You may see a cannot remove docs/assets/bootstrap.zip file – just ignore. It would also be great if you could make to a target directory, but I couldn’t find how this could be done.

  1. Once the build has been completed, move to the docs/assets directory:
~/testme/vendors$ cd bootstrap/docs/assets
  1. You should see a css, img, js folders and a bootstrap.zip file:
~/testme/vendors/bootstrap/docs/assets$ ls
  1. Go back to the testme folder:
~/testme/vendors/bootstrap/docs/assets$ cd ~/testme
  1. Move the bootstrap zip file you just created into your public folder:
~/testme$ mv vendors/bootstrap/docs/assets/bootstrap.zip public
  1. Move to the public folder:
~/testme$ cd public
  1. Unzip the bootstrap.zip file:
~/testme/public$ unzip bootstrap.zip
  1. You should see a bootstrap folder in the public folder
~/testme/public$ ls
  1. Remove the bootstrap.zip file:
$ rm bootstrap.zip
  1. Now it’s a matter of linking to the bootstrap stylesheets in your jade layout template files. Edit the views/layout.jade file to include references to the bootstrap files, remember Bootstrap needs the latest jQuery, so you may want to include reference to this too, here’s what my layout.jade looks like:
!!!
html
head
title= title
link(rel='stylesheet', href='/bootstrap/css/bootstrap.min.css')
link(rel='stylesheet', href='/bootstrap/css/bootstrap-responsive.min.css')
link(rel='stylesheet', href='/stylesheets/style.css')
script(src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js')
script(src='/bootstrap/js/bootstrap.min.js')
body
block content
view raw layout.jade hosted with ❤ by GitHub

2. To test that it works, edit the views/index.jade file to include a reference that Bootstrap will be able to use, something like:

extends layout
block content
div.top
form.form-horizontal(method="post", id="loginForm")
label Username
input.span3(id="username", type="text", name="User", placeholder="Enter your username")
label Password
input.span3(id="password", type="password", name="Password")
input.btn(type="submit", value="Log In")
div.container
div.content
table.table.table-striped
thead
tr
th Table
th Heading
tbody
tr
td Blah
td Test
tr
td Hello
td World
div.footer
p © 2012 All rights reserved.
view raw index.jade hosted with ❤ by GitHub

There you have it!

Being able to use a compiled Bootstrap file with your ExpressJS install.

Categories
Software

What is the Best Set Up For SuiteScript Coding in Webstorm?

As mentioned in my previous post on what my preferred text editor is for SuiteScripting NetSuite does provide a deeper integration with JetBrains’ WebStorm product through a plugin.

To enable this plugin in WebStorm you will need to access this help page in NetSuite’s documentation and follow the step by step guide.

(The process is fairly straightforward, but unfortunately the plugin doesn’t play well with PyCharm.)

Once you then have the plugin installed in WebStorm you then need to ensure you undertake (or already have done) the following steps:

  1. Set up the SuiteCloud Development Framework
  2. Create the SDF role (if needed) – I’m our account administrator, so I just use this role.
  3. Fetch a token.
  4. Create new “Account Customization” project in WebStorm.
  5. Set the Master Password for this project by clicking on the NetSuite > Master Password and setting it accordingly.
  6. Then click on NetSuite > Manage Accounts and follow through the prompts to get yourself connected.
  7. Insert your token ID and secret into the user account.
  8. Now time to download your project folder from within your File Cabinet. Just right-click on the folder in the Project Explorer labelled FileCabinet and then hover over the NetSuite icon on the dropdown menu and then select “Import Files from Account…”
SuiteScript Tools in WebStorm
WebStorm IDE SuiteScript Plugin options

Then you will have the option of selecting what project folder you would like to play around with.

From here on out it’s just a simple case of right-clicking on files and hovering over the NetSuite icon and selecting what you’d like to do.

  1. Deploy
  2. Validate
  3. Upload individual files

You might even want to make it a short-cut code on your keyboard!

Categories
Software

Best Editor For Coding SuiteScript Seamlessly

If you’re looking for a good text editor to perform your SuiteScript coding there are good editors, such as Microsoft’s Visual Studio Code, but the one I personally use on a regular basis is PyCharm.

Both platforms enable you to:

  • Write and analyse your JavaScript code;
  • Have integrated terminal and console windows;
  • Git integration;
  • Ability to code in other languages, such as Python (great for web-scraping and data analysis of your saved search csv files!); and
  • Connection to your SuiteScript File Cabinet (although the plugin for VSCode is a little more cumbersome to set up), and once setup you can then upload directly to your project’s folder in NetSuite.
  • Both are free PyCharm Community Edition, although I have an Ultimate licence that provides access to all of JetBrains products).

PyCharm and the more commonly known other JetBrains IDE WebStorm have been around for quite some time, and I have been more familiar with their product because of this.

As a result I use more frequently the PyCharm IDE as my go to editor and occasionally when I’m coding in the Advanced Template syntax (FreeMarker) I will use the [IntelliJ](https://www.jetbrains.com/idea/ editor).

I have requested for this to be a plugin so that I don’t need to pay for all different versions of JetBrains, so if you similarly inclined you may want to up-vote this request too

I’ll detail more in subsequent posts about how I use the PyCharm IDE from JetBrains in my day to day workflow.

Categories
Software

How To Fix “Invalid Property Assignment (Error 450)”

If you are testing the return value of a function in the immediate window in VBA and get the following error:

Wrong number of arguments or invalid property assignment (Error 450)

What you are doing is something like this:

Function GetCollection() As Collection
    Dim coll As New Collection
    coll.Add "Hello"
    coll.Add "World"
    Set GetCollection = coll
End Function

Then in the immediate window typing:

? GetCollection()

The code appears to work fine, but the error is a mystery. The reason for the error is that the immediate window call expects a collection, but isn’t receiving one.

Therefore, to properly test your functions returning a collection data type create a test subroutine that calls the function and receives the collection returned. Such as:

Sub Test()
    Dim a As Collection
    Set a = GetCollection()
    Debug.Print a.Item(1)
End Sub

Then in the immediate window enter the name of the subroutine just created:

Test

You should then see the following output:

Test
Hello

Conclusion

When testing functions that return a Collection data type instead of using the immediate window defer instead to calling them from a test subroutine. Then output the desired response to visually check your code works, or instead of printing to the immediate window, use Debug.Assert like this:

' Debug.Print a.Item(1)
Debug.Assert a.Item(1) = "Hello"

If there’s a problem with your function when the subroutine is ran in the immediate window it will break at the failed assertion test.

Either way, learning this has helped brush up my rusty Excel VBA skills as I jump back into Excel VBA 2016.

Categories
Coding

Common Mistakes With Jekyll Front Matter

As I don’t blog very often whenever I create a new blog post in GitHub Pages (using Jekyll’s template framework) there a couple of times I forget the basics and spend a few minutes trying to figure out why the page didn’t load properly.

So this post today is more of a note to self.

Firstly, for blog posts name the file according to the following convention:

YYYY-MM-DD-BlahBlah.md

Secondly, in the front matter area don’t use another colon in the value of the variable. For example don’t do this:

title: Errors: Why do they happen?

Just use another type of punctuation, like:

title: Errors - Why do they happen?

Lastly, every variable in the front matter must contain a name followed by the colon. You cannot create a one-liner variable like this:

redirect_from "yoo/hoo/im-here"

Must be in this type of format in the case of redirect_from:

redirect_from: - yoo/hoo/im-here

Anyway, these are the pesky little bugs that trip me up all the time and tend to cost me a few minutes to an hour of scratching my head trying to figure out what on earth is happening. Hopefully by documenting them I can squash them quicker!

Categories
Cloud Apps

How To Fix Oblique Advanced PDF/HTML Template Errors In Netsuite

When working with Advanced Templates, and the FreeMarker syntax in NetSuite there can be some oblique errors which make it difficult to diagnose.

To help diagnose any such errors, I highly recommend writing your templates in a code editor.

I personally prefer the editors from JetBrains as they package everything you need in one nice editor. To effectively write FreeMarker templates with syntax highlighting and auto-completion you will need the IntelliJ Editor.

Template cannot be saved error

When you get an error from NetSuite such as something of the form:

The template cannot be saved due to the following errors: Parse exception during template merging. Cause: Encountered “&” at line 128, column 89 in template. Was expecting one of: … … “false” … “true” … … … “.” … “+” … “-” … “!” … “[” … “(” … “)” … “{” … …

What I’ve found is when I return to my editor to hunt for the problem I don’t see anything on line 128??

So what is going on with this error?

To properly diagnose the error, copy the code as it is in the Advanced Template window. Then paste this code back into your text editor and then look at line 128.

You should notice with the newly pasted code that NetSuite may have parsed through some lines and edited it for you. Some lines may have been concatenated together and other lines may have page breaks.

With the newly inserted code you should be able to better diagnose the problem.

In the case of the error above I would navigate to line 128, and I’d see where NetSuite is struggling with my template code.

In the example above it appeared NetSuite doesn’t like using the &nbsp; HTML entity directly in the code. So just changed this to a space character.

The error appeared to go away when I tried saving the template again. In fact if you apply any innocuous edit it should save just fine.

The important thing to remember though, especially if you’re scratching your head and looking at the error, and your code on side-by-side screens: copy the code from NetSuite and then you’ll see the error.

Categories
Cloud Apps Coding

How To Print More Than 1 Page In Advanced PDF/HTML Templates

I like NetSuite’s Advanced PDF/HTML templating system with the FreeMarker syntax. However, there are a couple of issues I’ve run into and one just recently:

How can you force printing on two or more pages?

One example I’ve been working on is the ability to print “how to pay” information on the back of our invoices that are issued to our customers.

As our invoices can span a few lines we have been squeezing that information down in the footer of the page. This makes for small font and errors from the customer when entering payment details. I mean, you’ve got a lot more space on the back than you do in the footer! It would be so much more convenient if this information were to be printed on the back of the invoice, but to do this it would mean getting the template to do a page break.

After asking for this feature request to NetSuite some time ago, I came across an interesting, and simple, CSS technique that actually works!

The solution?

  1. Just measure the dimensions of the paper you would like to print. Or obtain standard paper dimensions from the web.
  2. Enter this information into a CSS class in the <style> area within your PDF/HTML template.
  3. Reference this class whenever you want to do a page break.

Here’s a simplified template demonstrating this concept:

<?xml version="1.0"?>
<!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">
<pdf>
    <head>
        <macrolist>
            <macro id="nlfooter">
                <table>
                    <tr>
                        <td>This is the footer. I've chosen to span this over each page.</td>
                    </tr>
                </table>
            </macro>
        </macrolist>
        <style>
            /* Insert the physical dimensions of the size of the paper you print.*/
            /* Width = page width; Min-height = page height; */
            /* (You may/may not need to have `margin-right:1.5cm`. I found the contents spilled off the page without it.)*/
            .page { margin-right: 1.5cm; width: 21cm; min-height: 29.7cm; }
        </style>
    </head>
    <body footer="nlfooter" footer-height="15%">
    <div class="page">
        <h1>Welcome to the first page!</h1>
        <p>Place all your first page information here. For example, you may want to put your company logo, the invoice date, number, contact address of the customer, and then you'll want to loop through all the items in the invoice in a nice neat table.</p>
        <p><strong>Notice how the right-margin is a little funny?</strong></p>
        <p>You may need to increase the `margin-right` value on the `page` class attribute to make this margin look nicer on the page. Play with it.</p>           
    </div>
    <div class="page">
        <h1>Welcome to page 2!</h1>
        <p>You should now see this on the second page.</p>
        <p>This is where you can place additional information on whatever else is important, i.e. how to pay, etc.</p>
    </div>
    </body>
</pdf>

As you can see from the comments, all you need do is enter the dimensions of the size of the paper into the .page attribute and then reference that class whenever you want to apply a page break.

How did that demo turn out?

Have a look at the demo copy of the PDF and see for yourself.

Nice!

Categories
Coding

Function That Receives An Array Of Strings & Outputs Most Used String

I love the occasional programming challenge and yesterday I came across the following:

Create a function that receives an array of strings and outputs the most used string?

I pondered on this for awhile and in my mind thought of the following process:

  1. Loop through each element of the original array;
  2. Count the occurrences of each element by looping through the array again;
  3. Sort the new array;
  4. Output the new array’s first element.

However, looking at this I realised I was looping way too many times!

So I refactored my code such that it does the following:

function getModal( arr ) {
  var maxCount = 0;
  var result = "";
  arr.reduce( function( p, el ) {
    p[el] ? p[el] += 1 : p[el] = 1;
    if ( p[el] > maxCount ) {
      maxCount = p[el];
      result = el;
    } 
    return p;
  }, {} );
  return result;
}

var e = ["h","g","x", "d", "b", "h", "x", "i", "s", "g", "x", "p"];

console.log( getModal( e ) ); // => "x"

Notice how there’s only one looping array function used – reduce.

What this function does is take the array arr as a parameter, create two variables to measure the maxCount and another to take the result. As we then loop through the arr we assign each element (being a string) as a key to the new object created by reduce and make it’s property value equal to the count.

This makes counting the number of occurrences relatively easy.

All we then do is check whether the property value is greater than the maxCount value and if it is to make that value equal to the maxCount and the result equal to that element.

Once we’ve finished looping through the arr we then just simply output the result.

If we need to output the count of occurrences we could just change our code to output:

return {
    answer : result,
    count : maxCount
};

Anyway, I’m sure there is a better answer to my response, but I liked the challenge and I also liked the refactoring process – looking at my code and finding a better way.