Renaming a file with Node.js

Node.js LogoLearn how to rename a file with Node.js, in ten lines of code

I was fleshing out a few ideas on a project today and found myself trying to figure out how to rename a file with Node.js. I have no doubt that there are better ways to go about this, but I thought I’d document my findings.

The first thing I realized is that the low-level nature of Node.js offers a great deal of power, but also with that power comes a the need to handle all of the details. For me, this meant getting references to four things:

  1. The name of the old file
  2. The name of the new file
  3. The full path to the old file
  4. The full path to the new file (which does not exist yet)

The first two items are easy: I just had to provide a name for the old file, and decide what to call the new file. The last two items involved a bit more effort. I needed to do do three things:

  1. Get the path of the folder that contains the old file
  2. Add a trailing slash to that path
  3. Set a permanent reference to the old file

To accomplish all of these tasks, I decided to use the filepath Node.js module.

Example # 1A

 Example # 1B

Example # 1A shows the contents of package.json. There is only one dependency: the filepath Node.js module.

In Example # 1B, I first set references to the file system module, as well as the filepath module. Next, I provided strings for the names of the old and new files. The filepath module is then used to get the path to the current folder; I set that to the fpFolder variable (adding a trailing slash to that string, which will be needed when we append file names to that string).

The variable fpFile is used as a permanent reference to the old file (this will come in handy for Example # 3.) Finally, I build the full file paths for the old and new files. After that, a couple of console.log statements to make sure all of this work is correct.

Example # 1C

Example # 1C shows the output of the two console.log statements. Each path will vary for you a bit, so I simply put “[YOUR LOCAL PATH TO]” for the folder structure that leads up to that file in the github repo that you cloned (see “How to Demo” below).

This example does not actually rename a file. So, now I will use the file system module to make that change.

How to Demo:

  • Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  • Navigate to: JavaScript/node-js/node-modules/fs/fs-rename
  • Execute the following command in a terminal prompt: npm install
  • Execute the following command in a terminal prompt: node filepath-1.js

Example # 2

In Example # 2, I use the file system module’s rename method to rename the file: “re-name-me.txt.” This method takes two arguments: a path to the old file, a path to the new file and a callback. The callback takes one argument: an error object. Inside of the callback, I check for the error object, and then output the path of the new file. Follow the instructions below to see this code in action. After you execute the code, the file: “re-name-me.txt” will be renamed to: “ive-been-renamed.txt.”

In order to rename Example # 2 again, you’ll need to manually rename the file: “ive-been-renamed.txt” back to: “re-name-me.txt”. After a few times back and forth, this got pretty tedious and I started to think that there must be a way to toggle the file back and forth. Meaning: If the file has been renamed, change it back to the original name, and so forth.

How to Demo:

  • Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  • Navigate to: JavaScript/node-js/node-modules/fs/fs-rename
  • Execute the following command in a terminal prompt: npm install
  • Execute the following command in a terminal prompt: node filepath-2.js

Example # 3A

In Example # 3A, I use the ternary operator when setting the final path for the old and new files. In each case, I check to see if the old file exists, and then depending on the answer, I set each path accordingly.

Example # 3B

Example # 3B is the full code for the final version of this file. I combined all var statements and cleaned up the code a bit. When you follow the instructions below, you’ll see that you can keep executing node filepath-2.js over and over, and the text file will toggle between the old name and the new name.

How to Demo:

  • Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  • Navigate to: JavaScript/node-js/node-modules/fs/fs-rename
  • Execute the following command in a terminal prompt: npm install
  • Execute the following command in a terminal prompt: node filepath-2.js

Summary

As I mentioned, there are probably a number of ways to do this that are more efficient. Everything I detailed here was the result of a few minutes with Google. Hopefully this article either got you where you needed to go, or pointed you in the right direction.

Helpful Links for Renaming a File with Node.js

http://nodejs.org/api/fs.html

https://www.npmjs.com/package/filepath

Getting started with the filepath Node.js module

Node.js LogoWhen you need to reference and work with the local file system in your Node.js program, the filepath module is quite a handy tool.

Even if your Node.js program is a web-server of some sort, working with the local file system is somewhat inevitable. While Node.js does provide low-level file system access (see the Node.js fs module), abstraction is always helpful, particularly when dealing with absolute paths.

The filepath Node.js module is a very helpful utility for simple access to file paths. You’ll need only a package.json file with this module as a dependency, an “npm install” command, and then you are up and running. This article provides a quick introduction to a few of the most common methods.

Example # 1A

Example # 1B:

In Example # 1, we first create the FP variable, which references the filepath module. Then we create the path variable, which holds the return value of the FP object’s newPath method. And finally, we output the path in the console. Example # 1B shows the terminal output when we use console.log to view the path variable. This path will vary for each user so I simply put “[YOUR LOCAL PATH TO]” for the folder structure that leads up to that file in the github repo that you cloned (see “How to Demo” below).

How to Demo:

  1. Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  2. Navigate to: JavaScript/node-js/filepath
  3. Execute the following command in a terminal prompt: node filepath-1.js

Example # 2

Example # 2 demonstrates the list method. The only real difference between this code and Example # 1, is the new variable “files”, which receives the value of the list method, when called on our path variable. The files variable ends up as an array. Each element in the array is an object whose “path” property is a string that points to a file in the current directory.

How to Demo:

  1. Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  2. Navigate to: JavaScript/node-js/filepath
  3. Execute the following command in a terminal prompt: node filepath-2.js

Example # 3A

Example # 3B

Example # 3C

Example # 3D

In Example # 3A, we see the recurse method in action. Just as the name implies, the recurse method will recursively list all of the files in the current directory. As a result, if one of those files is a folder, then it will list all of the files in that folder, and so on. This method differs from the previous two examples in that it takes a callback. The callback is a bit like a forEach call; it iterates over all of the files or folders in the path, and calls the callback for each one. Inside of the callback, the path variable is the current path being iterated over.

Example # 3C is the output from the code in Example # 3A.

In Example # 3C, we use the toString() method of the path object so that instead of a bunch of objects that we would need to handle, we just get the values we are after; the string representation of the path to that file or folder.

Example # 3D is the output from the code in Example # 3C.

How to Demo:

  1. Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  2. Navigate to: JavaScript/node-js/filepath
  3. Execute the following command in a terminal prompt: node filepath-3.js

Summary

The filepath Node.js module has much more to offer than was demonstrated here. Hopefully, this article has demonstrated how easy it is to get started with filepath.

Helpful Links for the filepath Node.js module

https://www.npmjs.com/package/filepath

http://nodejs.org/api/fs.html

Getting started with the uglify-js Node.js module

Node.js LogoLearn how to easily implement minification and file concatenation right in your Node.js program.

There is no doubt that tools such as grunt and gulp provide powerful front-end tooling, particularly for large-scale applications. But in some cases, you may want to “roll your own”. If you want to minify and / or concatenate files from your Node.js application, the uglify-js module offers a simple syntax yet plenty of muscle-power if you want to get serious.

A quick package.json file and “npm install” command are all you need to get started. Once these two tasks are taken care of, you can minify one or more files, and concatenate the output to a new file. In this article, I will show you how to do just that in less than 20 lines of code.

Example # 1A

Example # 1B

Example # 1C

 Example # 1D

In Example # 1A we have the contents of the file: package.json. This tells npm what our program depends on the “uglify-js” module. Examples # 1B, 1C and 1D are the contents of the files we will “uglify”. The actual code has no significance. We just want to have a reference so that once we have uglified the files, we can see the difference in the output.

Example # 2A

 Example # 2B

In Example # 2, we minify the file: file-1.js. in this case, the minified code is simply shown in the console. Example # 2B shows the minified code. It’s hard to imagine a case where we would want to minify code, but only show the result in a terminal window. Realistically, we need to write the output of the minified file to a new file.

How to Demo:

  1. Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  2. Navigate to: JavaScript/node-js/uglify-js
  3. Execute the following command in a terminal prompt: npm install
  4. Execute the following command in a terminal prompt: node uglify-1.js

Example # 3

 

In Example # 3, we have the content of uglify-2.js. We’ve moved things into a more real-world context; we save the result of the minification to a physical file. Notice that after you execute node uglify-2.js in your terminal, there is a new file named: output.min.js, which is a minified version of file-1.js.

The first change we made was to add a reference to the “fs” module, which provides access to the file system in Node.js. The console.log statement was left in, just so you can still see the output in the console. Below that, we call the writeFile method of the fs object. We pass it three arguments: 1) the name of the file that will contain the result of the minification process (i.e. the minified code), 2) the content for that file (i.e. the minified code), and 3) a callback. The callback takes one argument: an error object. In the callback, we check to see if there was an error, and if not, we send a success message to the console. In this Example, the callback is optional as it has nothing to do with the minification process and only provides messaging as to the status of the minification attempt.

Although Example # 3 is more of a real-world context than Example # 2, it is still a bit unrealistic as we only minify one file. In a typical production workflow, one would likely want to minify and concatenate more than one file.

How to Demo:

  1. Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  2. Navigate to: JavaScript/node-js/uglify-js
  3. Execute the following command in a terminal prompt: npm install
  4. Execute the following command in a terminal prompt: node uglify-2.js

Example # 4

Example # 4 shows the contents of uglify-3.js. The only change we have made is in the call to UglifyJS.minify. Instead of passing it a string, we pass an array. Each element in the array is a path to a file we want to minimize and the concatenate to the output file. In this case all of the files are in the same folder as our program, so there is no folder structure (i.e. just the file names). You can take the same exact steps to demo this example, and when you do, you will see that the file output.min.js contains the minified code of file-1.js, file-2.js and file-3.js.

Summary

The uglify-js offers a ton of options, parameters and features. For this article, I wanted to demonstrate how easy it is to set up and use this Node,js module. If you want to understand the true power of uglify-js, there is a ton of documentation available online. Hopefully this article got you to first base!

Helpful Links for the uglify-js Node.js module

https://www.npmjs.com/package/uglify-js

https://www.npmjs.com/package/uglify-js#api-reference

http://lisperator.net/uglifyjs/

Getting Started with HTML5 Drag and Drop Part IV: Multiple Draggables and Multiple Droppables

HTML5 LogoOnce you know how to successfully drag one HTML element and drop it on another one, there is a new UX challenge: multiple elements that can be dragged and then dropped on any one of multiple droppables.

In Parts I, II and III of this series, we covered the critical concepts needed to implement HTML drag and drop. We talked about the dragstart event, the dataTransfer object, originalEvent object, drop event, dragenter event, dragleave event, and setDragImage method. These concepts got us to the point where we could drag one HTML element, and then drop it on another. All of this, with some UX considerations such as setting a custom drag image, updating the droppable element when something is dragged over it or when something is dropped on it.

When I was taking a deep dive into HTML5 drag-and-drop, I wanted to be able to wire-up a scenario where there were multiple “draggable” elements, and multiple “droppable” elements. From a UX standpoint, my goals were:

  1. Any draggable could be dropped on any droppable
  2. Each droppable would change appearance when an element was dragged over it
  3. Each droppable would change appearance when an element was dropped onto it
  4. Each droppable would accept only one dropped element at a time
  5. The container that originally held the droppables would change appearance when empty
  6. The container that originally holds the droppables could accept any one or all of the droppables if they are dragged back to it

When I first attempted this, I got to a point where this all seemed like a lot of moving parts. Fortunately, a substantial portion of the challenge has been solved in parts I, II and III of this series, and I hope that if you have already read those articles, you have a solid understanding of how to do the following:

  1. Make an element draggable
  2. Set a custom drag element
  3. Make an element droppable
  4. Update the droppable when an element is dragged over it
  5. Update the droppable when an element was dropped onto it

With that knowledge, our task list shrinks a bit:

  1. Any draggable can be dropped-on any droppable
  2. Each droppable will accept only one dropped element at a time
  3. The container that originally held the droppables will change appearance when empty
  4. The container that originally held the droppables will accept any one or all of the droppables if they are dragged back to it

From here on, I will walk through the steps I took to accomplish these goals. There are probably other ways to go about solving these problems. I am sharing the approach I took.

Task # 1: Any draggable can be dropped-on any droppable

This was the easiest step. In parts I, II and III of this series, all of the JavaScript event binding was accomplished using classes instead of IDs. Because of this, adding more draggables and droppables in the HTML solved this problem. The existing JavaScript worked fine.

Task # 2: Each droppable will accept only one dropped element at a time

There are two things I needed to do in order to solve this problem: 1) create two separate “drop” event handlers, one for the multiple droppable HTML elements and another for the container that originally held the droppables; 2) in “drop” event handlers of the multiple droppables, check to see if the droppable element already has a child element.

Before I discuss the fix for task # 2, take a look at this JSFiddle link: http://jsfiddle.net/v9hawcof/5/

That link demonstrates the behavior that I do NOT want: more than one draggable can be dropped onto a droppable.

Base HTML

In the code example above, we have the base HTML for the rest of the examples in this article. For brevity’s sake, I’ve stripped out all but the most essential areas of the markup so that you can focus on the technologies demonstrated in this article. When you view the page source for the final working example, you will see that there is more HTML, but it is for presentational purposes only.

Example # 1

Here is the JSfiddle link for Example # 1: http://jsfiddle.net/v9hawcof/6/

In Example # 1, I’ve added a new function called: “dropHandlerSingle”. This event handler is dedicated to the four light brown boxes at top (i.e. the “multiple droppables”). In the function I check to see if the droppable element has any children. If so, then I exit immediately. You may also noticed that I trigger this custom event: “custom:dropEvent”. That will be explained shortly.

Task # 3: The container that originally held the droppables will change appearance when empty

Example # 2

Here is the JSfiddle link for Example # 2: http://jsfiddle.net/v9hawcof/7/

In Example # 2, you see the event handler for “custom:dropEvent”. The reason I used the setTimeout method, is because of timing challenges. When the drop event occurs, the DOM is not in the state needed in order to query it and figure out what is going on (i.e. which droppable elements have children). This event handler for “custom:dropEvent” will check each droppable element, and if it has no children, it removes the CSS class that gives it a “hasChildren” appearance (i.e. the background color changes from dark brown to light brown).

Task # 4: The container that originally held the droppables will change appearance when empty

Example # 3A

Example # 3B

Example # 3C

 Here is the JSfiddle link for Example # 3: http://jsfiddle.net/v9hawcof/8/

In Example # 3A, I bind an event handler for the container that originally held the droppables. In Example # 3B you’ll see that event handler: the “dropHandlerMultiple” function. The “dropHandlerMultiple” event handler does pretty much the same thing as the “dropHandlerSingle” event handler. The only difference is that the “dropHandlerMultiple” function does not check to see if it has children already. This is the critical step in accomplishing task # 4. In Example # 3B, you’ll see the code that tells the dragenter event handler to exit immediately if an element is dragged over the container that originally held the droppables. This is not a critical feature. I supposed I could have allowed the dragenter UX to apply to that container as well.

Here is the working example for this article: http://examples.kevinchisholm.com/html5/drag-and-drop/part-iv.html

Here is the JavaScript for this article’s working example: http://examples.kevinchisholm.com/html5/drag-and-drop/js/part-iv.js

Summary

Everything in this article is really a matter of personal choice. What I’ve done is detail how I decided to solve a particular UX challenge. How you approach this same set of tasks is completely up to you. I found that while attempting all of this, I learned a few things about HTML5 drag and drop. I hope you will too.

Node.js Basics – Command-Line Arguments

Node.js LogoLearn how to access command-line arguments passed to your node.js file

When you use Node.js as a command-line tool, you most likely type the following into your terminal application: node some-file.js. Once your application grows to even a modest level of complexity or sophistication, you will probably want to accept arguments on the command line. In this article, I will explain the basics of how to gain access to the arguments that are passed to your node application on the command line.

The key to accessing command-line arguments lies in the argv property of the process global. The process object is a global object, which means that you can access it from anywhere in your program. The argv property is an array that contains all arguments provided when you executed your program on the command line.

Example # 1A

Example # 1B

Example # 1C

In Example # 1A, we have the contents of the file: showArgs-1.js. This line simply inspects the argv property of the process objet. The output will go straight to the terminal window the moment you execute your program.

In Example # 1B, we have the actual command you use to execute the program; first node (the executable for Node.js), and then the name of the file we want to execute: showArgs-1.js.

Example # 1C shows the output of this program. In the console, you will see an array. The first element of that array is node, and the second element is the path to the program. This path will vary for each user so I simply put “[PATH TO]” for the folder structure that leads up that file in the github repo that you cloned (see “How to Demo” below).

How to Demo:

  1. Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  2. Navigate to: JavaScript/node-js/command-line-arguments/basics
  3. Execute the following command in a terminal prompt: node showArgs-1.js

Example # 2A

Example # 2B

 Example # 2C

In Example # 2B, you’ll see that we passed some additional arguments to our program: “arg2”, “arg3” and “arg4”. I used the numbers 2, 3, and 4 because they make more sense, due to the 0-based nature of this arguments array. Remember: arguments 0 and 1 are node and the file that contains your program, so the additional arguments here are indexed as 2, 3 and 4.

Since we know that the first two arguments will be the same every time, let’s try to get rid of those first two arguments.

How to Demo:

  1. Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  2. Navigate to: JavaScript/node-js/command-line-arguments/basics
  3. Execute the following command in a terminal prompt: node showArgs-1.js arg2 arg3 arg4

Example # 3A

 Example # 3B

 Example # 3C

In Example # 3A, we use the Array.prototype.slice method to remove the first two elements of the arguments array. Specifically, process.argv is an array, so we use its slice method to remove the first two elements of the array, and assign that return value to the variable args. We then inspect the args array using a console.dir statement.

In Example # 3B, we execute our program, passing three arguments: “arg0”, “arg1” and “arg2’. Example # 3C shows the output: an array containing only the arguments that we passed to the program.

How to Demo:

  1. Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  2. Navigate to: JavaScript/node-js/command-line-arguments/basics
  3. Execute the following command in a terminal prompt: node showArgs-2.js arg0 arg1 arg2

Example # 4A

 Example # 4B

Example # 4C

In Example # 4A, we make the output a bit easier on the eyes. Instead of a simple console.dir statement, we use the forEach method of the args array for iteration. Inside of each iteration, we use a console.log statement to output a more human-friendly message that shows the argument that is contained in that element.

How to Demo: 

  1. Clone this github repo: https://github.com/kevinchisholm/video-code-examples
  2. Navigate to: JavaScript/node-js/command-line-arguments/basics
  3. Execute the following command in a terminal prompt: node showArgs-3.js arg0 arg1 arg2

Summary

While the examples here were quite basic, they are perfectly valid and could be used in your code. There are Node.js modules that provide powerful abstractions when it comes to Node.js command-line arguments. The one I have probably heard the most about is minimist. If you are writing an application that has even a moderate level of complexity, you will likely want to use something like minimist. That said, understanding how things work on a low-level is always a good idea. Hopefully, this article has provided a helpful introduction to this concept.

Helpful Links for Node.js Command-Line Basics

http://nodejs.org/api/process.html

http://nodejs.org/api/process.html#process_process_argv

https://www.npmjs.com/package/minimist